chore(code): add smart tab behaviour

This commit is contained in:
Elian Doran 2025-05-11 17:39:10 +03:00
parent 9bbe111dd9
commit 4bac03570c
No known key found for this signature in database
5 changed files with 46 additions and 2 deletions

View File

@ -0,0 +1,43 @@
import { indentLess, indentMore } from "@codemirror/commands";
import type { KeyBinding } from "@codemirror/view";
const smartIndentWithTab: KeyBinding[] = [
{
key: "Tab",
run({ state, dispatch}) {
const { selection } = state;
for (const range of selection.ranges) {
if (!range.empty) {
// Allow default behaviour.
return false;
}
const line = state.doc.lineAt(range.head);
const beforeCursor = state.doc.sliceString(line.from, range.head);
if (/^\s*$/.test(beforeCursor)) {
// Only whitespace before cursor: indent line
return indentMore({state, dispatch});
} else {
// Insert a tab character
const cursor = range.head;
dispatch(state.update({
changes: {
from: cursor,
insert: "\t"
},
selection: { anchor: cursor + 1 },
scrollIntoView: true,
userEvent: "input"
}));
return true;
}
}
return false;
},
shift: indentLess
},
]
export default smartIndentWithTab;

View File

@ -5,6 +5,7 @@ import { Compartment, type Extension } from "@codemirror/state";
import { highlightSelectionMatches } from "@codemirror/search"; import { highlightSelectionMatches } from "@codemirror/search";
import { vim } from "@replit/codemirror-vim"; import { vim } from "@replit/codemirror-vim";
import byMimeType from "./syntax_highlighting.js"; import byMimeType from "./syntax_highlighting.js";
import smartIndentWithTab from "./extensions/custom_tab.js";
type ContentChangedListener = () => void; type ContentChangedListener = () => void;
@ -45,7 +46,7 @@ export default class CodeMirror extends EditorView {
keymap.of([ keymap.of([
...defaultKeymap, ...defaultKeymap,
...historyKeymap, ...historyKeymap,
indentWithTab ...smartIndentWithTab
]) ])
] ]

View File

@ -4,7 +4,7 @@ import type { Extension } from "@codemirror/state";
async function buildJavaScript(mimeType: string) { async function buildJavaScript(mimeType: string) {
const { javascript, esLint } = await import('@codemirror/lang-javascript'); const { javascript, esLint } = await import('@codemirror/lang-javascript');
const lint = (await import("./eslint.js")).lint; const lint = (await import("./extensions/eslint.js")).lint;
const extensions: Extension[] = [ javascript() ]; const extensions: Extension[] = [ javascript() ];
const result = await lint(mimeType); const result = await lint(mimeType);