Add keyboard-driven navigation within tabs

This commit is contained in:
Quinten Kock 2025-12-02 20:52:39 +01:00
parent aecff9f546
commit e898bd91f4
4 changed files with 25 additions and 18 deletions

View File

@ -22,7 +22,7 @@ export abstract class Displayable {
setTimeout(() => this.installHandlers(0), 0); setTimeout(() => this.installHandlers(0), 0);
// Add general shortcuts // Add general shortcuts
this.addShortcut("Ctrl-w", () => this.close()); this.addShortcut("Alt-w", () => this.close());
this.addShortcut("Alt--", () => this.changeWidth(-100)); this.addShortcut("Alt--", () => this.changeWidth(-100));
this.addShortcut("Alt-=", () => this.changeWidth(100)); this.addShortcut("Alt-=", () => this.changeWidth(100));
} }

View File

@ -19,7 +19,7 @@ import {
crosshairCursor, crosshairCursor,
showPanel, showPanel,
} from "@codemirror/view"; } from "@codemirror/view";
import { defaultKeymap, undo, redo } from "@codemirror/commands"; import { defaultKeymap, undo, redo, indentWithTab } from "@codemirror/commands";
import { oneDark } from "@codemirror/theme-one-dark"; import { oneDark } from "@codemirror/theme-one-dark";
import { import {
LanguageDescription, LanguageDescription,
@ -110,6 +110,7 @@ export class Editor extends Displayable {
...findReferencesKeymap, ...findReferencesKeymap,
...formatKeymap, ...formatKeymap,
...renameKeymap, ...renameKeymap,
indentWithTab,
{ key: "Mod-z", run: () => undo(file.target) }, { key: "Mod-z", run: () => undo(file.target) },
{ key: "Mod-shift-z", run: () => redo(file.target) }, { key: "Mod-shift-z", run: () => redo(file.target) },
{ {

View File

@ -17,28 +17,34 @@ const EditorWrapper = (
van.derive(() => { van.derive(() => {
if (!editor || !editor.val) return; if (!editor || !editor.val) return;
const wrappedDelete = () => { const findLeft = () => {
// TODO: find a better way to get the list containing this EditorWrapper
const list = editors[currentTab.val] || []; const list = editors[currentTab.val] || [];
// Find nearest non-empty neighbor (scan left then right)
let neighborState: Displayable | null = null;
for (let i = k - 1; i >= 0; i--) { for (let i = k - 1; i >= 0; i--) {
const c = list[i]; const c = list[i];
if (c) { if (c) {
neighborState = c; return c;
break;
} }
} }
if (!neighborState) { return null;
for (let i = k + 1; i < list.length; i++) { };
const c = list[i];
if (c) { const findRight = () => {
neighborState = c; const list = editors[currentTab.val] || [];
break; for (let i = k + 1; i < list.length; i++) {
} const c = list[i];
if (c) {
return c;
} }
} }
return null;
};
const wrappedDelete = () => {
// Find nearest non-empty neighbor (scan left then right)
let neighborState: Displayable | null = findLeft();
if (!neighborState) {
neighborState = findRight();
}
// Call the original delete function which updates the reactive list / DOM // Call the original delete function which updates the reactive list / DOM
del(); del();
@ -49,6 +55,8 @@ const EditorWrapper = (
} }
}; };
editor.val.addShortcut("Alt-[", () => findLeft()?.focus());
editor.val.addShortcut("Alt-]", () => findRight()?.focus());
editor.val.setDeleteFunction(wrappedDelete); editor.val.setDeleteFunction(wrappedDelete);
}); });

View File

@ -96,12 +96,10 @@ class OpenFileWorkspace extends Workspace {
// Look through known workspace files and update their docs/versions // Look through known workspace files and update their docs/versions
// based on the editor views or the OpenFile state when no view exists. // based on the editor views or the OpenFile state when no view exists.
// TODO: fix (cause vibe coding is useless)
syncFiles() { syncFiles() {
const result = []; const result = [];
for (const file of this.files) { for (const file of this.files) {
const prevDoc = file.doc; const prevDoc = file.doc;
// TODO: get changes from rootState (tracked in OpenFile) rather than the view's LSPPlugin.
const changes = file.changes; const changes = file.changes;
if (changes && !changes.empty) { if (changes && !changes.empty) {
result.push({ file, prevDoc, changes }); result.push({ file, prevDoc, changes });