Skip to content

Commit ff93bf2

Browse files
authored
fix: add missing autoclosebracket keymap(paired bracket deletion) (#2472)
1 parent e90866f commit ff93bf2

2 files changed

Lines changed: 69 additions & 6 deletions

File tree

‎src/cm/baseExtensions.ts‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
acceptCompletion,
33
closeBrackets,
4+
closeBracketsKeymap,
45
completionKeymap,
56
} from "@codemirror/autocomplete";
67
import { defaultKeymap, history, historyKeymap } from "@codemirror/commands";
@@ -75,7 +76,12 @@ export default function createBaseExtensions(
7576
Prec.highest(keymap.of([{ key: "Tab", run: acceptCompletion }])),
7677
);
7778
extensions.push(
78-
keymap.of([...completionKeymap, ...defaultKeymap, ...historyKeymap]),
79+
keymap.of([
80+
...(autoCloseBrackets ? closeBracketsKeymap : []),
81+
...completionKeymap,
82+
...defaultKeymap,
83+
...historyKeymap,
84+
]),
7985
);
8086
extensions.push(
8187
// This prevents tooltips from being going out of the editor area

‎src/test/editor.tests.js‎

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
} from "@codemirror/language";
88
import { highlightSelectionMatches, searchKeymap } from "@codemirror/search";
99
import { EditorSelection, EditorState } from "@codemirror/state";
10-
import { EditorView } from "@codemirror/view";
10+
import { EditorView, runScopeHandlers } from "@codemirror/view";
1111
import createBaseExtensions from "cm/baseExtensions";
1212
import indentGuides from "cm/indentGuides";
1313
import {
@@ -33,7 +33,7 @@ import { TestRunner } from "./tester";
3333
export async function runCodeMirrorTests(writeOutput) {
3434
const runner = new TestRunner("CodeMirror 6 Editor Tests");
3535

36-
function createEditor(doc = "", extensions = []) {
36+
function createEditor(doc = "", extensions = [], baseExtensionOptions = {}) {
3737
const container = document.createElement("div");
3838
container.style.width = "500px";
3939
container.style.height = "300px";
@@ -42,18 +42,31 @@ export async function runCodeMirrorTests(writeOutput) {
4242

4343
const state = EditorState.create({
4444
doc,
45-
extensions: [...createBaseExtensions(), ...extensions],
45+
extensions: [
46+
...createBaseExtensions(baseExtensionOptions),
47+
...extensions,
48+
],
4649
});
4750

4851
const view = new EditorView({ state, parent: container });
4952
return { view, container };
5053
}
5154

52-
async function withEditor(test, fn, initialDoc = "", extensions = []) {
55+
async function withEditor(
56+
test,
57+
fn,
58+
initialDoc = "",
59+
extensions = [],
60+
baseExtensionOptions = {},
61+
) {
5362
let view, container;
5463

5564
try {
56-
({ view, container } = createEditor(initialDoc, extensions));
65+
({ view, container } = createEditor(
66+
initialDoc,
67+
extensions,
68+
baseExtensionOptions,
69+
));
5770
test.assert(view != null, "EditorView instance should be created");
5871
await new Promise((resolve) => setTimeout(resolve, 100));
5972
await fn(view);
@@ -139,6 +152,50 @@ export async function runCodeMirrorTests(writeOutput) {
139152
container.remove();
140153
});
141154

155+
runner.test("Backspace deletes an auto-closed bracket pair", async (test) => {
156+
await withEditor(
157+
test,
158+
async (view) => {
159+
view.dispatch({ selection: { anchor: 1 } });
160+
const handled = runScopeHandlers(
161+
view,
162+
new KeyboardEvent("keydown", { key: "Backspace" }),
163+
"editor",
164+
);
165+
166+
test.assert(
167+
handled,
168+
"Backspace should be handled between a bracket pair",
169+
);
170+
test.assertEqual(view.state.doc.toString(), "");
171+
},
172+
"()",
173+
);
174+
});
175+
176+
runner.test(
177+
"Backspace behaves normally when auto-close is disabled",
178+
async (test) => {
179+
await withEditor(
180+
test,
181+
async (view) => {
182+
view.dispatch({ selection: { anchor: 1 } });
183+
const handled = runScopeHandlers(
184+
view,
185+
new KeyboardEvent("keydown", { key: "Backspace" }),
186+
"editor",
187+
);
188+
189+
test.assert(handled, "Backspace should retain its default behavior");
190+
test.assertEqual(view.state.doc.toString(), ")");
191+
},
192+
"()",
193+
[],
194+
{ autoCloseBrackets: false },
195+
);
196+
},
197+
);
198+
142199
runner.test("State access", async (test) => {
143200
await withEditor(test, async (view) => {
144201
const state = view.state;

0 commit comments

Comments
 (0)