glide: Add split view keymaps
C-w v creates a split with a new tab (not the adjacent one).
C-h/l moves between panes within a split (wrapping).
C-j/k navigates to the next/prev tab, skipping split siblings.
C-w q separates the current tab from its split.

Assisted-by: Claude Opus 4.6 via pi
change wryytrklqwxwyxzvrolytzkrnxyxuxtr
commit 1e7c7340aea874afd38d0f2fdfef2778165b9868
author Alpha Chen <alpha@kejadlen.dev>
date
parent vvtvpuxk
diff --git a/.config/glide/glide.ts b/.config/glide/glide.ts
index 558f006a..9f66783a 100644
--- a/.config/glide/glide.ts
+++ b/.config/glide/glide.ts
@@ -18,6 +18,7 @@
 
 glide.include("hints.glide.ts");
 glide.include("tridactyl.glide.ts");
+glide.include("unstable.glide.ts");
 glide.fs.exists("local.glide.ts").then(exists => {
   if (exists) glide.include("local.glide.ts");
 });
diff --git a/.config/glide/unstable.glide.ts b/.config/glide/unstable.glide.ts
new file mode 100644
index 00000000..0df65e95
--- /dev/null
+++ b/.config/glide/unstable.glide.ts
@@ -0,0 +1,102 @@
+// https://glide-browser.app/changelog#0.1.55a-split-views
+glide.keymaps.set(
+  "normal",
+  "<C-w>v",
+  async ({ tab_id }) => {
+    await glide.excmds.execute("tab_new");
+    const new_tab = await glide.tabs.active();
+    glide.unstable.split_views.create([tab_id, new_tab.id]);
+  },
+  {
+    description: "Create a split view with a new tab",
+  },
+);
+
+glide.keymaps.set(
+  "normal",
+  "<C-h>",
+  async ({ tab_id }) => {
+    const split = glide.unstable.split_views.get(tab_id);
+    if (!split) return;
+    const index = split.tabs.findIndex((t) => t.id === tab_id);
+    const target = split.tabs.at((index - 1) % split.tabs.length);
+    if (!target?.id) return;
+    await browser.tabs.update(target.id, { active: true });
+  },
+  {
+    description: "Focus the split to the left",
+  },
+);
+
+glide.keymaps.set(
+  "normal",
+  "<C-l>",
+  async ({ tab_id }) => {
+    const split = glide.unstable.split_views.get(tab_id);
+    if (!split) return;
+    const index = split.tabs.findIndex((t) => t.id === tab_id);
+    const target = split.tabs.at((index + 1) % split.tabs.length);
+    if (!target?.id) return;
+    await browser.tabs.update(target.id, { active: true });
+  },
+  {
+    description: "Focus the split to the right",
+  },
+);
+
+glide.keymaps.set(
+  "normal",
+  "<C-j>",
+  async ({ tab_id }) => {
+    const split = glide.unstable.split_views.get(tab_id);
+    if (!split) {
+      await glide.excmds.execute("tab_next");
+      return;
+    }
+    const splitIds = new Set(split.tabs.map((t) => t.id));
+    const all_tabs = await glide.tabs.query({});
+    const currentIndex = all_tabs.findIndex((t) => t.id === tab_id);
+    for (let i = 1; i < all_tabs.length; i++) {
+      const target = all_tabs[(currentIndex + i) % all_tabs.length];
+      if (target?.id && !splitIds.has(target.id)) {
+        await browser.tabs.update(target.id, { active: true });
+        return;
+      }
+    }
+  },
+  { description: "Next tab (skipping split siblings)" },
+);
+
+glide.keymaps.set(
+  "normal",
+  "<C-k>",
+  async ({ tab_id }) => {
+    const split = glide.unstable.split_views.get(tab_id);
+    if (!split) {
+      await glide.excmds.execute("tab_prev");
+      return;
+    }
+    const splitIds = new Set(split.tabs.map((t) => t.id));
+    const all_tabs = await glide.tabs.query({});
+    const currentIndex = all_tabs.findIndex((t) => t.id === tab_id);
+    for (let i = 1; i < all_tabs.length; i++) {
+      const target = all_tabs.at((currentIndex - i) % all_tabs.length);
+      if (target?.id && !splitIds.has(target.id)) {
+        await browser.tabs.update(target.id, { active: true });
+        return;
+      }
+    }
+  },
+  { description: "Previous tab (skipping split siblings)" },
+);
+
+glide.keymaps.set(
+  "normal",
+  "<C-w>q",
+  async ({ tab_id }) => {
+    glide.unstable.split_views.separate(tab_id);
+  },
+  {
+    description: "Close the split view for the current tab",
+  },
+);