glide: add a Tridactyl-style :tab_move command
Assisted-by: Claude Opus 5.5 via Claude Code
change optvwxnlrqxnrlnmqopqssxylqqxzmuz
commit 658c574de9ace342a3443dc3da73932d056693a7
author Alpha Chen <alpha@kejadlen.dev>
date
parent uzuzqwyo
diff --git a/.config/glide/glide.ts b/.config/glide/glide.ts
index 6b2b2f1c..47ae2c96 100644
--- a/.config/glide/glide.ts
+++ b/.config/glide/glide.ts
@@ -314,6 +314,32 @@ glide.keymaps.set(["normal", "insert"], "<D-A-t>", async () => {
 },
   { description: "Open a new tab at the end of the tab strip" });
 
+// Tridactyl-style :tabmove — "+N"/"-N" relative, "N" 1-based absolute, "^"/"$" start/end.
+// Targets are clamped to the tab's pinned/unpinned group, since tabs.move
+// silently no-ops on a move across that boundary.
+glide.excmds.create(
+  { name: "tab_move", description: "Move the current tab: +N, -N, N, ^, or $ (default)" },
+  async ({ tab_id, args_arr }) => {
+    const arg = args_arr[0] ?? "$";
+    const tab = await browser.tabs.get(tab_id);
+    const tabs = await browser.tabs.query({ windowId: tab.windowId });
+    const pinnedCount = tabs.reduce((n, t) => (t.pinned ? n + 1 : n), 0);
+    const [first, last] = tab.pinned ? [0, pinnedCount - 1] : [pinnedCount, tabs.length - 1];
+
+    let index: number;
+    if (arg === "^") index = first;
+    else if (arg === "$") index = last;
+    else if (/^[+-]\d+$/.test(arg)) index = tab.index + Number(arg);
+    else if (/^\d+$/.test(arg)) index = Number(arg) - 1;
+    else {
+      glide.g["dev.kejadlen"]!.notify(`tab_move: expected +N, -N, N, ^, or $, got "${arg}"`);
+      return;
+    }
+
+    await browser.tabs.move(tab_id, { index: Math.min(Math.max(index, first), last) });
+  },
+);
+
 // Forward to Firefox's built-in screenshot shortcut; the config sandbox can't
 // invoke the Browser:Screenshot command directly.
 glide.keymaps.set(["normal", "insert"], "<D-S-2>", async () => {