← All projects

Tab Shift

I move Chrome tabs with the mouse. Grab one, drag it three along, drop it. That's how I've always done it and I hadn't thought about it once.

Chrome has a keyboard shortcut for this. Ctrl+Shift+PgUp and Ctrl+Shift+PgDn. A Mac laptop has no PgUp key. What you actually press is Ctrl+Shift+Fn+arrow. Four fingers on one hand, for a thing I do all day.

So I wrote the one-hand version. Option+Shift+Left and Option+Shift+Right move the current tab one spot. Two files. About sixty lines doing the work.

It asks for zero permissions. Chrome shows no warning at install because there's nothing to warn about: it can't read the page, the address bar or my history. It says shift this tab one spot, and that's the end of its reach.

Adding one to a number

Moving a tab one spot sounds like adding one to a number. That version is wrong almost straight away.

Pinned tabs sit in their own section at the front. Add one to a normal tab's position at that boundary and it slides in there and pins itself.

Groups are the harder one. A tab group is a run of tabs Chrome draws a box around, and position plus one puts your tab inside the box. What Chrome does then isn't written down anywhere I could find.

So it doesn't go in. A loose tab hops the whole group and lands the far side. A tab already in a group moves inside it, and at the edge it drops out of the group and stays exactly where it is. Press again to carry on.

That's what Chrome's own move shortcut does. Copying it meant I got to leave the undocumented case alone.

Push the first tab left and it comes out at the far end. Same going the other way. The wrap doubles as send this to the front.

Chrome can run the tab strip down the side now. Left and right stop meaning much when the tabs are stacked. Option+Shift+Up and Option+Shift+Down do the same two moves.

Both pairs are live all the time. Chrome keeps one tab order whichever way the strip points, and it doesn't tell extensions which layout is on. The whole layout question stays out of the code.

Four shortcuts is Chrome's ceiling on suggested defaults. I've used all four.

The chord is changeable and I didn't build the screen for changing it. Chrome forbids an extension from rebinding its own shortcuts in code. Its own page at chrome://extensions/shortcuts does it, and clicking my extension's icon opens that page.

I could've built a recorder that listens for whatever keys you press. It would need permission to run on every site you visit, and that's the one thing I wanted this to stay clear of.

The one link I can't automate

The tests load the real extension into a real browser and call the real service worker. Nothing in the test file re-implements the moving logic. Thirty-three checks: every move, the pinned strip, all five group cases, the icon click and Chrome's own confirmation that it took all four shortcuts at install.

Thirty-three green ticks. The keypress is the one they skip.

So what do the thirty-three cover? Everything underneath the key. Turning Option+Shift+Left into a message my code hears is wiring I declare in a config file, and I can't press a key from a script. I can ask Chrome whether it accepted the shortcuts and it says yes to all four. Whether the one I press arrives is a thing I found out by pressing it.

Moving the chord moved the test too. The old check asked whether Chrome had bound something, and it would have passed just as green if Chrome had bound the wrong keys. It now checks the exact chord one glyph at a time.

The browser in the tests isn't the browser I use either. Chrome dropped command-line loading of unpacked extensions at version 137, so the harness runs Chromium (the open-source browser Chrome is built out of).

It shipped on Cmd+Shift+arrow and I broke my own keyboard the same afternoon. Cmd+Shift+Left selects to the start of the line. I reach for that constantly, and inside Chrome my extension was swallowing it.

So the default moved to Option+Shift. Every arrow chord on a Mac is already some kind of selection. Option+Shift takes word by word and paragraph by paragraph, and only inside Chrome. I picked the collision I'd notice least and handed the busy one back.

The rebinding page is what made that cheap. I built it for whoever installs this and wants different keys. I was the first person to need it.

I didn't try anything else first. There are tab managers that do this and more, and a keyboard remapper I could've pointed at it (Karabiner). I went straight to writing the thing. Zero permissions is what I wanted going in. What the alternatives would've asked me for, I can't tell you.

This is the second Chrome extension I've built. Deny Cookies is the other one, and the only piece that carries across is the way these get tested. Moving it over is still on the list.

Where it stands: it's loaded in my Chrome out of a folder, wearing the puzzle piece Chrome hands anything with no icon art (there's no Web Store listing, which wants art and a developer account).

A few hours of pressing it isn't muscle memory. A month would tell me.

I haven't dragged a tab since this morning.