fix(editor): Match nodes for autocomplete (#13716)

This commit is contained in:
Dana
2025-03-10 14:01:00 +01:00
committed by GitHub
parent e9a8a7f875
commit 8043a6ce82
2 changed files with 48 additions and 7 deletions

View File

@@ -1,5 +1,6 @@
import { escapeMappingString } from '@/utils/mappingUtils';
import {
type CompletionContext,
insertCompletionText,
pickedCompletion,
type Completion,
@@ -16,16 +17,21 @@ import { blockCommentSnippet, snippets } from './snippets';
const START_CHARACTERS = ['"', "'", '(', '.', '@'];
const START_CHARACTERS_REGEX = /[\.\(\'\"\@]/;
export const typescriptCompletionSource: CompletionSource = async (context) => {
const { worker } = context.state.facet(typescriptWorkerFacet);
export const matchText = (context: CompletionContext) => {
let word = context.matchBefore(START_CHARACTERS_REGEX);
if (!word?.text) {
word = context.matchBefore(/[\"\'].*/);
}
if (!word?.text) {
word = context.matchBefore(/[\$\w]+/);
}
if (!word?.text) {
word = context.matchBefore(/[\"\'].*/);
}
return word;
};
export const typescriptCompletionSource: CompletionSource = async (context) => {
const { worker } = context.state.facet(typescriptWorkerFacet);
const word = matchText(context);
const blockComment = context.matchBefore(/\/\*?\*?/);
if (blockComment) {
@@ -46,7 +52,7 @@ export const typescriptCompletionSource: CompletionSource = async (context) => {
if (isGlobal) {
options = options
.flatMap((opt) => {
if (opt.label === '$') {
if (opt.label === '$()') {
return [
opt,
...autocompletableNodeNames().map((name) => ({

View File

@@ -0,0 +1,35 @@
import { matchText } from '../completions';
import { CompletionContext } from '@codemirror/autocomplete';
import { EditorState } from '@codemirror/state';
import { n8nLang } from '@/plugins/codemirror/n8nLang';
describe('matchText', () => {
afterEach(() => {
vi.resetAllMocks();
});
it.each([
{ node: '$(|)', expected: '(' },
{ node: '$("|', expected: '"' },
{ node: "$('|", expected: "'" },
{ node: '$(""|', expected: '"' },
{ node: "$('|", expected: "'" },
{ node: '$("|")', expected: '"' },
{ node: "$('|')", expected: "'" },
{ node: '$("|)', expected: '"' },
{ node: '$("No|")', expected: 'No' },
{ node: "$('No|')", expected: 'No' },
{ node: '$("N|")', expected: 'N' },
{ node: "$('N|')", expected: 'N' },
])('should match on previous node: $node', ({ node, expected }) => {
const cursorPosition = node.indexOf('|');
const state = EditorState.create({
doc: node.replace('|', ''),
selection: { anchor: cursorPosition },
extensions: [n8nLang()],
});
const context = new CompletionContext(state, cursorPosition, false);
expect(matchText(context)?.text).toEqual(expected);
});
});