feat(editor): Bring completions to HTML editor (#5382)

 Bring completions to HTML editor
This commit is contained in:
Iván Ovejero 2023-02-09 09:41:07 +01:00 committed by GitHub
parent 74fc1414d7
commit a07de049a2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 18 deletions

View file

@ -8,10 +8,16 @@ import prettier from 'prettier/standalone';
import htmlParser from 'prettier/parser-html'; import htmlParser from 'prettier/parser-html';
import cssParser from 'prettier/parser-postcss'; import cssParser from 'prettier/parser-postcss';
import jsParser from 'prettier/parser-babel'; import jsParser from 'prettier/parser-babel';
import { html } from 'codemirror-lang-html-n8n'; import { htmlLanguage, autoCloseTags, html } from 'codemirror-lang-html-n8n';
import { autocompletion } from '@codemirror/autocomplete'; import { autocompletion } from '@codemirror/autocomplete';
import { indentWithTab, insertNewlineAndIndent, history } from '@codemirror/commands'; import { indentWithTab, insertNewlineAndIndent, history } from '@codemirror/commands';
import { bracketMatching, ensureSyntaxTree, foldGutter, indentOnInput } from '@codemirror/language'; import {
bracketMatching,
ensureSyntaxTree,
foldGutter,
indentOnInput,
LanguageSupport,
} from '@codemirror/language';
import { EditorState, Extension } from '@codemirror/state'; import { EditorState, Extension } from '@codemirror/state';
import { import {
dropCursor, dropCursor,
@ -23,6 +29,7 @@ import {
ViewUpdate, ViewUpdate,
} from '@codemirror/view'; } from '@codemirror/view';
import { n8nCompletionSources } from '@/plugins/codemirror/completions/addCompletions';
import { expressionInputHandler } from '@/plugins/codemirror/inputHandlers/expression.inputHandler'; import { expressionInputHandler } from '@/plugins/codemirror/inputHandlers/expression.inputHandler';
import { highlighter } from '@/plugins/codemirror/resolvableHighlighter'; import { highlighter } from '@/plugins/codemirror/resolvableHighlighter';
import { htmlEditorEventBus } from '@/event-bus/html-editor-event-bus'; import { htmlEditorEventBus } from '@/event-bus/html-editor-event-bus';
@ -50,6 +57,10 @@ export default mixins(expressionManager).extend({
type: Boolean, type: Boolean,
default: false, default: false,
}, },
disableExpressionCompletions: {
type: Boolean,
default: false,
},
}, },
data() { data() {
return { return {
@ -62,10 +73,18 @@ export default mixins(expressionManager).extend({
}, },
extensions(): Extension[] { extensions(): Extension[] {
function htmlWithCompletions() {
return new LanguageSupport(
htmlLanguage,
n8nCompletionSources().map((source) => htmlLanguage.data.of(source)),
);
}
return [ return [
bracketMatching(), bracketMatching(),
autocompletion(), autocompletion(),
html({ autoCloseTags: true }), this.disableExpressionCompletions ? html() : htmlWithCompletions(),
autoCloseTags,
expressionInputHandler(), expressionInputHandler(),
keymap.of([indentWithTab, { key: 'Enter', run: insertNewlineAndIndent }]), keymap.of([indentWithTab, { key: 'Enter', run: insertNewlineAndIndent }]),
indentOnInput(), indentOnInput(),

View file

@ -86,6 +86,7 @@
:isReadOnly="isReadOnly" :isReadOnly="isReadOnly"
:rows="getArgument('rows')" :rows="getArgument('rows')"
:disableExpressionColoring="!isHtmlNode(node)" :disableExpressionColoring="!isHtmlNode(node)"
:disableExpressionCompletions="!isHtmlNode(node)"
@valueChanged="valueChangedDebounced" @valueChanged="valueChangedDebounced"
/> />

View file

@ -0,0 +1,18 @@
import { ifIn } from '@codemirror/autocomplete';
import { blankCompletions } from './blank.completions';
import { bracketAccessCompletions } from './bracketAccess.completions';
import { datatypeCompletions } from './datatype.completions';
import { dollarCompletions } from './dollar.completions';
import { nonDollarCompletions } from './nonDollar.completions';
export function n8nCompletionSources() {
return [
blankCompletions,
bracketAccessCompletions,
datatypeCompletions,
dollarCompletions,
nonDollarCompletions,
].map((source) => ({
autocomplete: ifIn(['Resolvable'], source),
}));
}

View file

@ -2,13 +2,8 @@ import { parserWithMetaData as n8nParser } from 'codemirror-lang-n8n-expression'
import { LanguageSupport, LRLanguage } from '@codemirror/language'; import { LanguageSupport, LRLanguage } from '@codemirror/language';
import { parseMixed } from '@lezer/common'; import { parseMixed } from '@lezer/common';
import { javascriptLanguage } from '@codemirror/lang-javascript'; import { javascriptLanguage } from '@codemirror/lang-javascript';
import { ifIn } from '@codemirror/autocomplete';
import { blankCompletions } from './completions/blank.completions'; import { n8nCompletionSources } from './completions/addCompletions';
import { bracketAccessCompletions } from './completions/bracketAccess.completions';
import { datatypeCompletions } from './completions/datatype.completions';
import { dollarCompletions } from './completions/dollar.completions';
import { nonDollarCompletions } from './completions/nonDollar.completions';
const n8nParserWithNestedJsParser = n8nParser.configure({ const n8nParserWithNestedJsParser = n8nParser.configure({
wrap: parseMixed((node) => { wrap: parseMixed((node) => {
@ -23,16 +18,8 @@ const n8nParserWithNestedJsParser = n8nParser.configure({
const n8nLanguage = LRLanguage.define({ parser: n8nParserWithNestedJsParser }); const n8nLanguage = LRLanguage.define({ parser: n8nParserWithNestedJsParser });
export function n8nLang() { export function n8nLang() {
const options = [
blankCompletions,
bracketAccessCompletions,
datatypeCompletions,
dollarCompletions,
nonDollarCompletions,
].map((group) => n8nLanguage.data.of({ autocomplete: ifIn(['Resolvable'], group) }));
return new LanguageSupport(n8nLanguage, [ return new LanguageSupport(n8nLanguage, [
n8nLanguage.data.of({ closeBrackets: { brackets: ['{', '('] } }), n8nLanguage.data.of({ closeBrackets: { brackets: ['{', '('] } }),
...options, ...n8nCompletionSources().map((source) => n8nLanguage.data.of(source)),
]); ]);
} }