Skip to content

Commit

Permalink
fix: codemirror editor tab behavior (#1522)
Browse files Browse the repository at this point in the history
* fix: codemirror editor  tab behavior

* handle case of selection

* handle multipe selection
  • Loading branch information
jczhong84 authored Nov 22, 2024
1 parent 7dd47c0 commit 0350efb
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { KeyBinding, keymap, Prec } from '@uiw/react-codemirror';
import { useCallback, useMemo } from 'react';

import { CodeMirrorKeyMap } from 'lib/codemirror';
import { indentLess, insertTab } from '@codemirror/commands';

export const useKeyMapExtension = ({
keyMap = {},
Expand Down Expand Up @@ -41,7 +40,6 @@ export const useKeyMapExtension = ({
})),
])
),
keymap.of([{ key: 'Tab', run: insertTab, shift: indentLess }]),
],
[keyBindings, keyMap, transformKey]
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,41 @@
import { indentLess, indentMore, insertTab } from '@codemirror/commands';
import { indentUnit } from '@codemirror/language';
import { EditorView } from '@uiw/react-codemirror';
import { EditorSelection, EditorState, Extension } from '@codemirror/state';
import { EditorView, keymap } from '@uiw/react-codemirror';
import { useMemo } from 'react';
import { EditorState, Extension } from '@codemirror/state';

const handleTabKey =
(indentWithTabs: boolean, tabSize: number) =>
({ state, dispatch }) => {
// If there is a selection, indent the selection
if (!state.selection.main.empty) {
return indentMore({ state, dispatch });
}

// If user chooses to use a real tab, insert a real tab
if (indentWithTabs) {
return insertTab({ state, dispatch });
}

// Insert 2 or 4 spaces instead of a real tab to reach the next tab stop
const changes = state.changeByRange((range) => {
const line = state.doc.lineAt(range.from);
const column = range.from - line.from;
const spacesToInsert = tabSize - (column % tabSize);

return {
changes: {
from: range.from,
to: range.to,
insert: ' '.repeat(spacesToInsert),
},
range: EditorSelection.cursor(range.from + spacesToInsert),
};
});

dispatch(state.update(changes, { userEvent: 'input' }));
return true;
};

export const useOptionsExtension = ({
lineWrapping = true,
Expand All @@ -15,11 +49,21 @@ export const useOptionsExtension = ({

if (options.indentWithTabs) {
extensions.push(indentUnit.of('\t'));
extensions.push(EditorState.tabSize.of(options.tabSize));
} else {
extensions.push(EditorState.tabSize.of(options.tabSize));
extensions.push(indentUnit.of(' '.repeat(options.indentUnit)));
}

extensions.push(
keymap.of([
{
key: 'Tab',
run: handleTabKey(options.indentWithTabs, options.tabSize),
shift: indentLess,
},
])
);

if (lineWrapping) {
extensions.push(EditorView.lineWrapping);
}
Expand Down

0 comments on commit 0350efb

Please sign in to comment.