From 6377635bf03387c8d0ae5d54848113258bbabacc Mon Sep 17 00:00:00 2001 From: Elias Meire Date: Fri, 14 Feb 2025 16:09:20 +0100 Subject: [PATCH] fix(editor): Open autocompletion when starting an expression (#13249) --- .../expressionCloseBrackets.test.ts | 52 +++++++++++++++++++ .../codemirror/expressionCloseBrackets.ts | 2 + 2 files changed, 54 insertions(+) create mode 100644 packages/editor-ui/src/plugins/codemirror/expressionCloseBrackets.test.ts diff --git a/packages/editor-ui/src/plugins/codemirror/expressionCloseBrackets.test.ts b/packages/editor-ui/src/plugins/codemirror/expressionCloseBrackets.test.ts new file mode 100644 index 00000000000..e93e1db7d5c --- /dev/null +++ b/packages/editor-ui/src/plugins/codemirror/expressionCloseBrackets.test.ts @@ -0,0 +1,52 @@ +import { EditorView } from '@codemirror/view'; +import userEvent from '@testing-library/user-event'; +import { expressionCloseBrackets } from './expressionCloseBrackets'; +import { n8nAutocompletion, n8nLang } from './n8nLang'; +import { completionStatus } from '@codemirror/autocomplete'; +import { EditorSelection } from '@codemirror/state'; +import { setActivePinia } from 'pinia'; +import { createTestingPinia } from '@pinia/testing'; + +describe('expressionCloseBrackets', () => { + const createEditor = () => { + const parent = document.createElement('div'); + document.body.appendChild(parent); + const editor = new EditorView({ + parent, + extensions: [expressionCloseBrackets(), n8nLang(), n8nAutocompletion()], + }); + return editor; + }; + + beforeEach(() => { + setActivePinia(createTestingPinia()); + }); + + it('should complete {{| to {{ | }} and open autocomplete', async () => { + const editor = createEditor(); + // '{' is an escape character: '{{' === '{' + await userEvent.type(editor.contentDOM, '{{{{'); + expect(editor.state.doc.toString()).toEqual('{{ }}'); + expect(editor.state.selection).toEqual(EditorSelection.single(3)); + expect(completionStatus(editor.state)).not.toBeNull(); + }); + + it('should type over auto-closed brackets', async () => { + const editor = createEditor(); + await userEvent.type(editor.contentDOM, 'foo()'); + // no extra closing bracket foo()) + expect(editor.state.doc.toString()).toEqual('foo()'); + }); + + it.each([ + { char: '"', expected: '""' }, + { char: "'", expected: "''" }, + { char: '(', expected: '()' }, + { char: '{{}', expected: '{}' }, + { char: '{[}', expected: '[]' }, + ])('should auto-close $expected', async ({ expected, char }) => { + const editor = createEditor(); + await userEvent.type(editor.contentDOM, char); + expect(editor.state.doc.toString()).toEqual(expected); + }); +}); diff --git a/packages/editor-ui/src/plugins/codemirror/expressionCloseBrackets.ts b/packages/editor-ui/src/plugins/codemirror/expressionCloseBrackets.ts index 9342ecab307..0edbac9738c 100644 --- a/packages/editor-ui/src/plugins/codemirror/expressionCloseBrackets.ts +++ b/packages/editor-ui/src/plugins/codemirror/expressionCloseBrackets.ts @@ -1,6 +1,7 @@ import { closeBrackets, closeBracketsKeymap, + startCompletion, type CloseBracketConfig, } from '@codemirror/autocomplete'; import { EditorSelection, Text } from '@codemirror/state'; @@ -21,6 +22,7 @@ const expressionBracketSpacing = EditorView.updateListener.of((update) => { changes: [{ from: fromB + 1, insert: ' ' }], selection: EditorSelection.cursor(toB), }); + startCompletion(update.view); } }); });