mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-13 16:14:07 -08:00
WIP
This commit is contained in:
parent
42966628d3
commit
406aeb005a
|
@ -4,11 +4,10 @@ import type { CodeExecutionMode, CodeNodeEditorLanguage } from 'n8n-workflow';
|
|||
import { format } from 'prettier';
|
||||
import jsParser from 'prettier/plugins/babel';
|
||||
import * as estree from 'prettier/plugins/estree';
|
||||
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
||||
import { computed, onBeforeUnmount, onMounted, ref, toRaw, watch } from 'vue';
|
||||
|
||||
import { CODE_NODE_TYPE } from '@/constants';
|
||||
import { codeNodeEditorEventBus } from '@/event-bus';
|
||||
import { usePostHog } from '@/stores/posthog.store';
|
||||
import { useRootStore } from '@/stores/root.store';
|
||||
|
||||
import { useCodeEditor } from '@/composables/useCodeEditor';
|
||||
|
@ -18,6 +17,8 @@ import { useTelemetry } from '@/composables/useTelemetry';
|
|||
import AskAI from './AskAI/AskAI.vue';
|
||||
import { CODE_PLACEHOLDERS } from './constants';
|
||||
import { useLinter } from './linter';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { dropInCodeEditor } from '@/plugins/codemirror/dragAndDrop';
|
||||
|
||||
type Props = {
|
||||
mode: CodeExecutionMode;
|
||||
|
@ -59,8 +60,11 @@ const linter = useLinter(
|
|||
);
|
||||
const extensions = computed(() => [linter.value]);
|
||||
const placeholder = computed(() => CODE_PLACEHOLDERS[props.language]?.[props.mode] ?? '');
|
||||
const dragAndDropEnabled = computed(() => {
|
||||
return !props.isReadOnly && props.mode === 'runOnceForEachItem';
|
||||
});
|
||||
|
||||
const { highlightLine, readEditorValue } = useCodeEditor({
|
||||
const { highlightLine, readEditorValue, editor } = useCodeEditor({
|
||||
editorRef: codeNodeEditorRef,
|
||||
language: () => props.language,
|
||||
editorValue: () => props.modelValue,
|
||||
|
|
|
@ -19,6 +19,7 @@ import { editorKeymap } from '@/plugins/codemirror/keymap';
|
|||
import { n8nAutocompletion } from '@/plugins/codemirror/n8nLang';
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
import { codeEditorTheme } from '../CodeNodeEditor/theme';
|
||||
import { mappingDropCursor } from '@/plugins/codemirror/dragAndDrop';
|
||||
|
||||
type Props = {
|
||||
modelValue: string;
|
||||
|
|
|
@ -2,7 +2,7 @@ import { codeEditorTheme } from '@/components/CodeNodeEditor/theme';
|
|||
import { editorKeymap } from '@/plugins/codemirror/keymap';
|
||||
import { typescript } from '@/plugins/codemirror/lsp/typescript';
|
||||
import { closeCursorInfoBox } from '@/plugins/codemirror/tooltips/InfoBoxTooltip';
|
||||
import { closeCompletion, completionStatus } from '@codemirror/autocomplete';
|
||||
import { closeBrackets, closeCompletion, completionStatus } from '@codemirror/autocomplete';
|
||||
import { history } from '@codemirror/commands';
|
||||
import { javascript } from '@codemirror/lang-javascript';
|
||||
import { json } from '@codemirror/lang-json';
|
||||
|
@ -40,6 +40,7 @@ import {
|
|||
type MaybeRefOrGetter,
|
||||
type Ref,
|
||||
} from 'vue';
|
||||
import { mappingDropCursor } from '../plugins/codemirror/dragAndDrop';
|
||||
|
||||
export type CodeEditorLanguage = 'json' | 'html' | 'javaScript' | 'python';
|
||||
|
||||
|
@ -232,7 +233,9 @@ export const useCodeEditor = ({
|
|||
dropCursor(),
|
||||
indentOnInput(),
|
||||
bracketMatching(),
|
||||
closeBrackets(),
|
||||
highlightActiveLineGutter(),
|
||||
mappingDropCursor(),
|
||||
indentationMarkers({
|
||||
highlightActiveBlock: true,
|
||||
markerType: 'fullScope',
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { autocompletion, completeFromList, type CompletionSource } from '@codemirror/autocomplete';
|
||||
import { autocompletion, type CompletionSource } from '@codemirror/autocomplete';
|
||||
import { javascriptLanguage } from '@codemirror/lang-javascript';
|
||||
import { linter, type LintSource } from '@codemirror/lint';
|
||||
import { combineConfig, Facet, type Extension } from '@codemirror/state';
|
||||
|
@ -17,13 +17,23 @@ export const tsFacet = Facet.define<
|
|||
|
||||
const tsCompletions: CompletionSource = async (context) => {
|
||||
const { worker } = context.state.facet(tsFacet);
|
||||
console.log('complete', context);
|
||||
const { pos, explicit } = context;
|
||||
|
||||
let word = context.matchBefore(/\w*/);
|
||||
if (!word?.text) {
|
||||
word = context.matchBefore(/\./);
|
||||
}
|
||||
|
||||
if (!word?.text && !explicit) return null;
|
||||
|
||||
const result = await worker.getCompletionsAtPos(context.pos);
|
||||
|
||||
if (!result) return result;
|
||||
|
||||
return await completeFromList(result.options)(context);
|
||||
return {
|
||||
from: word ? (word.text === '.' ? word.to : word.from) : pos,
|
||||
options: result.options,
|
||||
};
|
||||
};
|
||||
|
||||
const tsLint: LintSource = async (view) => {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,6 +11,9 @@ import {
|
|||
cmPosToTs,
|
||||
} from './utils';
|
||||
import type { Completion } from '@codemirror/autocomplete';
|
||||
import types from './types.d.ts?raw';
|
||||
|
||||
const TS_COMPLETE_BLOCKLIST: ts.ScriptElementKind[] = [ts.ScriptElementKind.warning];
|
||||
|
||||
const worker = (): LanguageServiceWorker => {
|
||||
let env: tsvfs.VirtualTypeScriptEnvironment;
|
||||
|
@ -21,12 +24,11 @@ const worker = (): LanguageServiceWorker => {
|
|||
allowJs: true,
|
||||
checkJs: true,
|
||||
target: ts.ScriptTarget.ESNext,
|
||||
lib: ['ESNext'],
|
||||
noLib: true,
|
||||
module: ts.ModuleKind.ESNext,
|
||||
strict: true,
|
||||
typeRoots: [],
|
||||
types: [],
|
||||
importHelpers: false,
|
||||
skipDefaultLibCheck: true,
|
||||
noEmit: true,
|
||||
};
|
||||
|
||||
|
@ -40,15 +42,8 @@ const worker = (): LanguageServiceWorker => {
|
|||
await indexedDbCache('typescript-cache', 'fs-map'),
|
||||
);
|
||||
|
||||
fsMap.set('types.d.ts', types);
|
||||
fsMap.set(FILE_NAME, wrapInFunction(content));
|
||||
fsMap.set(
|
||||
'types.d.ts',
|
||||
`export {};
|
||||
|
||||
declare global {
|
||||
const $input: { json: Record<string,any>, all: () => [] }
|
||||
}`,
|
||||
);
|
||||
|
||||
const system = tsvfs.createSystem(fsMap);
|
||||
env = tsvfs.createVirtualTypeScriptEnvironment(
|
||||
|
@ -76,13 +71,19 @@ declare global {
|
|||
|
||||
if (!completionInfo) return null;
|
||||
|
||||
const options = completionInfo.entries.map((entry): Completion => {
|
||||
const boost = -Number(entry.sortText) || 0;
|
||||
return {
|
||||
label: entry.name,
|
||||
boost,
|
||||
};
|
||||
});
|
||||
const options = completionInfo.entries
|
||||
.filter(
|
||||
(entry) =>
|
||||
!TS_COMPLETE_BLOCKLIST.includes(entry.kind) &&
|
||||
(entry.sortText < '15' || completionInfo.optionalReplacementSpan?.length),
|
||||
)
|
||||
.map((entry): Completion => {
|
||||
const boost = -Number(entry.sortText) || 0;
|
||||
return {
|
||||
label: entry.name,
|
||||
boost,
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
from: pos,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import type { Diagnostic } from '@codemirror/lint';
|
||||
import ts from 'typescript';
|
||||
|
||||
export const FILE_NAME = 'index.ts';
|
||||
export const FILE_NAME = 'index.js';
|
||||
const FN_PREFIX = '(() => {\n';
|
||||
|
||||
export function wrapInFunction(script: string): string {
|
||||
|
@ -9,7 +9,7 @@ export function wrapInFunction(script: string): string {
|
|||
}
|
||||
|
||||
export function cmPosToTs(pos: number) {
|
||||
return pos + FN_PREFIX.length - 1;
|
||||
return pos + FN_PREFIX.length;
|
||||
}
|
||||
|
||||
export function tsPosToCm(pos: number) {
|
||||
|
|
|
@ -26,5 +26,6 @@
|
|||
// TODO: remove all options below this line
|
||||
"useUnknownInCatchVariables": false
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue"]
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue"],
|
||||
"exclude": ["src/plugins/codemirror/lsp/worker/**/*.d.ts"]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue