chore(code): support multiple selections in tab

This commit is contained in:
Elian Doran 2025-05-11 17:59:44 +03:00
parent 4bac03570c
commit 8d18823608
No known key found for this signature in database

View File

@ -1,38 +1,45 @@
import { indentLess, indentMore } from "@codemirror/commands"; import { indentLess, indentMore } from "@codemirror/commands";
import { EditorSelection, type ChangeSpec } from "@codemirror/state";
import type { KeyBinding } from "@codemirror/view"; import type { KeyBinding } from "@codemirror/view";
const smartIndentWithTab: KeyBinding[] = [ const smartIndentWithTab: KeyBinding[] = [
{ {
key: "Tab", key: "Tab",
run({ state, dispatch}) { run({ state, dispatch }) {
const { selection } = state; const { selection } = state;
for (const range of selection.ranges) { // Handle selection indenting normally
if (!range.empty) { if (selection.ranges.some(range => !range.empty)) {
// Allow default behaviour. return indentMore({ state, dispatch });
return false; }
}
const changes = [];
const newSelections = [];
for (let range of selection.ranges) {
const line = state.doc.lineAt(range.head); const line = state.doc.lineAt(range.head);
const beforeCursor = state.doc.sliceString(line.from, range.head); const beforeCursor = state.doc.sliceString(line.from, range.head);
if (/^\s*$/.test(beforeCursor)) { if (/^\s*$/.test(beforeCursor)) {
// Only whitespace before cursor: indent line // Only whitespace before cursor indent line
return indentMore({state, dispatch}); return indentMore({ state, dispatch });
} else { } else {
// Insert a tab character // Insert a tab character at cursor
const cursor = range.head; changes.push({ from: range.head, to: range.head, insert: "\t" });
dispatch(state.update({ newSelections.push(EditorSelection.cursor(range.head + 1));
changes: { }
from: cursor, }
insert: "\t"
}, if (changes.length) {
selection: { anchor: cursor + 1 }, dispatch(
state.update({
changes,
selection: EditorSelection.create(newSelections),
scrollIntoView: true, scrollIntoView: true,
userEvent: "input" userEvent: "input"
})); })
return true; );
} return true;
} }
return false; return false;