From 91f0f76ab605397882dc5de1f1bd0c07f2403f24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E4=B9=8B=E9=98=B3?= <51194195+luoliwoshang@users.noreply.github.com> Date: Wed, 13 Mar 2024 18:30:34 +0800 Subject: [PATCH] fix: clean editor language rely (#206) --- spx-gui/src/components/code-editor/editor.ts | 148 +++++++++++++++++ spx-gui/src/components/code-editor/index.ts | 58 +++---- .../src/components/code-editor/language.ts | 150 ----------------- .../src/components/code-editor/register.ts | 155 +++++++++--------- 4 files changed, 251 insertions(+), 260 deletions(-) create mode 100644 spx-gui/src/components/code-editor/editor.ts diff --git a/spx-gui/src/components/code-editor/editor.ts b/spx-gui/src/components/code-editor/editor.ts new file mode 100644 index 000000000..7212777db --- /dev/null +++ b/spx-gui/src/components/code-editor/editor.ts @@ -0,0 +1,148 @@ +import function_completions from './snippet' +import { keywords, brackets, typeKeywords, operators } from './language' +import { monaco } from '.' +export const editorOptions: monaco.editor.IStandaloneEditorConstructionOptions = { + language: 'spx', // define the language mode + minimap: { enabled: true }, + selectOnLineNumbers: true, // select the line number's of the code + roundedSelection: true, // rounded selection + readOnly: false, // read/write + cursorStyle: 'line', // line, block, 'line-thin', 'block-outline', 'underline', 'underline-thin' + automaticLayout: true, // auto layout + glyphMargin: true, // the margin is used for glyph margin and line numbers + useTabStops: false, // use tab key + renderControlCharacters: false, // render control characters + fontSize: 16, // font size + quickSuggestionsDelay: 100, // quick suggestions + wordWrapColumn: 40, + tabSize: 4, // tab size + folding: true, // code folding + foldingHighlight: true, // 折叠等高线 + foldingStrategy: 'indentation', // 折叠方式 auto | indentation + showFoldingControls: 'mouseover', // 是否一直显示折叠 always | mouseover + disableLayerHinting: true // 等宽优 +} +export const MonarchTokensProviderConfig: + | monaco.languages.IMonarchLanguage + | monaco.Thenable = { + defaultToken: 'invalid', + keywords, + typeKeywords, + operators, + functions: function_completions.map((e) => e.label), + brackets, + symbols: /[=>](?!@symbols)/, '@brackets'], + [ + /@symbols/, + { + cases: { + '@operators': 'operator', + '@default': '' + } + } + ], + + // numbers + [/(@digits)[eE]([-+]?(@digits))?/, 'number.float'], + [/(@digits)\.(@digits)([eE][-+]?(@digits))?/, 'number.float'], + [/0[xX](@hexdigits)/, 'number.hex'], + [/0[oO]?(@octaldigits)/, 'number.octal'], + [/0[bB](@binarydigits)/, 'number.binary'], + [/(@digits)/, 'number'], + + // delimiter: after number because of .\d floats + [/[;,.]/, 'delimiter'], + [/[=>/?\s]+)/g, + comments: { + lineComment: '//', + blockComment: ['/*', '*/'] + }, + brackets: [ + ['{', '}'], + ['[', ']'], + ['(', ')'], + ['"', '"'], + ["'", "'"] + ], + onEnterRules: [ + // if current cursor is betwwen work and space,then will not indent + { + beforeText: /\w/, + afterText: /^$/, + action: { indentAction: monaco.languages.IndentAction.None } + }, + { + // match /* + beforeText: /^\s*(\/\*)/, + // match */ + afterText: /^\s*\*\/$/, + action: { indentAction: monaco.languages.IndentAction.IndentOutdent } + } + ] +} diff --git a/spx-gui/src/components/code-editor/index.ts b/spx-gui/src/components/code-editor/index.ts index 316ecd452..c9dd9b5a5 100644 --- a/spx-gui/src/components/code-editor/index.ts +++ b/spx-gui/src/components/code-editor/index.ts @@ -4,50 +4,44 @@ * @LastEditors: Zhang Zhi Yang * @LastEditTime: 2024-02-04 13:15:49 * @FilePath: /spx-gui/src/components/code-editor/index.ts - * @Description: + * @Description: */ import * as monaco from 'monaco-editor' -import CodeEditor from "./CodeEditor.vue" +import CodeEditor from './CodeEditor.vue' -import { register } from './register'; -import { editorOptions } from "./language" -export default CodeEditor; +import { register } from './register' +import { editorOptions } from './editor' +export default CodeEditor -export interface Snippet extends monaco.languages.CompletionItem { -} +export interface Snippet extends monaco.languages.CompletionItem {} export interface FormatError { - Column: number; - Line: number; - Msg: string; -}; + Column: number + Line: number + Msg: string +} export interface FormatResponse { - Body: string; - Error: FormatError; -}; - + Body: string + Error: FormatError +} export interface EditorOptions { - minimap?: { - enabled: boolean - } - readOnly?: boolean - cursorStyle?: "line" // line, block, 'line-thin', 'block-outline', 'underline', 'underline-thin' + minimap?: { + enabled: boolean + } + readOnly?: boolean + cursorStyle?: 'line' // line, block, 'line-thin', 'block-outline', 'underline', 'underline-thin' } export interface CodeEditorProps { - modelValue: string - height?: string - width?: string - editorOptions?: EditorOptions + modelValue: string + height?: string + width?: string + editorOptions?: EditorOptions } export interface CodeEditorEmits { - (e: 'change', value: string): void - (e: 'update:modelValue', value: string): void -} -export * from "./snippet" -export { - monaco, - register, - editorOptions, + (e: 'change', value: string): void + (e: 'update:modelValue', value: string): void } +export * from './snippet' +export { monaco, register, editorOptions } diff --git a/spx-gui/src/components/code-editor/language.ts b/spx-gui/src/components/code-editor/language.ts index 310dcd57e..0a87f8011 100644 --- a/spx-gui/src/components/code-editor/language.ts +++ b/spx-gui/src/components/code-editor/language.ts @@ -6,9 +6,6 @@ * @FilePath: /builder/spx-gui/src/components/code-editor/Language.ts * @Description: */ -import { monaco } from "." -import function_completions from "./snippet"; - const keywords = [ "func", "main", @@ -95,158 +92,11 @@ const operators = [ ">>=", "=>", ]; - const brackets = [ { open: "{", close: "}", token: "delimiter.curly" }, { open: "[", close: "]", token: "delimiter.bracket" }, { open: "(", close: ")", token: "delimiter.parenthesis" }, ]; - -// editor options -export const editorOptions: monaco.editor.IStandaloneEditorConstructionOptions = { - language: "spx", // define the language mode - minimap: { enabled: true }, - selectOnLineNumbers: true, // select the line number's of the code - roundedSelection: true, // rounded selection - readOnly: false, // read/write - cursorStyle: "line", // line, block, 'line-thin', 'block-outline', 'underline', 'underline-thin' - automaticLayout: true, // auto layout - glyphMargin: true, // the margin is used for glyph margin and line numbers - useTabStops: false, // use tab key - renderControlCharacters: false, // render control characters - fontSize: 16, // font size - quickSuggestionsDelay: 100, // quick suggestions - wordWrapColumn: 40, - tabSize: 4, // tab size - folding: true, // code folding - foldingHighlight: true, // 折叠等高线 - foldingStrategy: "indentation", // 折叠方式 auto | indentation - showFoldingControls: "mouseover", // 是否一直显示折叠 always | mouseover - disableLayerHinting: true, // 等宽优 -}; -export const MonarchTokensProviderConfig: - | monaco.languages.IMonarchLanguage - | monaco.Thenable = { - defaultToken: "invalid", - keywords, - typeKeywords, - operators, - functions: function_completions.map((e) => e.label), - brackets, - symbols: /[=>](?!@symbols)/, '@brackets'], - [/@symbols/, { - cases: { - '@operators': 'operator', - '@default': '' - } - }], - - // numbers - [/(@digits)[eE]([-+]?(@digits))?/, 'number.float'], - [/(@digits)\.(@digits)([eE][-+]?(@digits))?/, 'number.float'], - [/0[xX](@hexdigits)/, 'number.hex'], - [/0[oO]?(@octaldigits)/, 'number.octal'], - [/0[bB](@binarydigits)/, 'number.binary'], - [/(@digits)/, 'number'], - - // delimiter: after number because of .\d floats - [/[;,.]/, "delimiter"], - [/[=>/?\s]+)/g, - comments: { - lineComment: "//", - blockComment: ["/*", "*/"], - }, - brackets: [ - ["{", "}"], - ["[", "]"], - ["(", ")"], - ['"', '"'], - ["'", "'"], - ], - onEnterRules: [ - // if current cursor is betwwen work and space,then will not indent - { - beforeText: /\w/, - afterText: /^$/, - action: { indentAction: monaco.languages.IndentAction.None }, - }, - { - // match /* - beforeText: /^\s*(\/\*)/, - // match */ - afterText: /^\s*\*\/$/, - action: { indentAction: monaco.languages.IndentAction.IndentOutdent }, - }, - ], -}; export { keywords, typeKeywords, diff --git a/spx-gui/src/components/code-editor/register.ts b/spx-gui/src/components/code-editor/register.ts index 2334b7f4e..da92c0252 100644 --- a/spx-gui/src/components/code-editor/register.ts +++ b/spx-gui/src/components/code-editor/register.ts @@ -6,95 +6,94 @@ * @FilePath: /builder/spx-gui/src/components/code-editor/register.ts * @Description: */ -import { keywords, typeKeywords, LanguageConfig, MonarchTokensProviderConfig } from './language' -import wasmModuleUrl from '@/assets/format.wasm?url'; -import function_completions from './snippet'; -import { monaco } from '.'; -function completionItem(range: monaco.IRange | monaco.languages.CompletionItemRanges): monaco.languages.CompletionItem[] { - return [ - ...keywords.map((keyword) => ({ - label: keyword, - insertText: keyword, - kind: monaco.languages.CompletionItemKind.Keyword, - detail: 'This is a keyword', - range - })), - ...function_completions.map(e => ({ - ...e, - range - })), - ...typeKeywords.map((typeKeyword) => ({ - label: typeKeyword, - insertText: typeKeyword, - kind: monaco.languages.CompletionItemKind.TypeParameter, - detail: 'This is a type', - range - })) - ] +import { LanguageConfig, MonarchTokensProviderConfig } from './editor' +import { keywords, typeKeywords } from './language' +import wasmModuleUrl from '@/assets/format.wasm?url' +import function_completions from './snippet' +import { monaco } from '.' +function completionItem( + range: monaco.IRange | monaco.languages.CompletionItemRanges +): monaco.languages.CompletionItem[] { + return [ + ...keywords.map((keyword) => ({ + label: keyword, + insertText: keyword, + kind: monaco.languages.CompletionItemKind.Keyword, + detail: 'This is a keyword', + range + })), + ...function_completions.map((e) => ({ + ...e, + range + })), + ...typeKeywords.map((typeKeyword) => ({ + label: typeKeyword, + insertText: typeKeyword, + kind: monaco.languages.CompletionItemKind.TypeParameter, + detail: 'This is a type', + range + })) + ] } const completionItemProvider: monaco.languages.CompletionItemProvider = { - provideCompletionItems: (model, position) => { - const word = model.getWordUntilPosition(position); - const range = { - startLineNumber: position.lineNumber, - endLineNumber: position.lineNumber, - startColumn: word.startColumn, - endColumn: word.endColumn, - }; - const suggestions: monaco.languages.CompletionItem[] = completionItem(range) - return { suggestions } + provideCompletionItems: (model, position) => { + const word = model.getWordUntilPosition(position) + const range = { + startLineNumber: position.lineNumber, + endLineNumber: position.lineNumber, + startColumn: word.startColumn, + endColumn: word.endColumn } + const suggestions: monaco.languages.CompletionItem[] = completionItem(range) + return { suggestions } + } } - - const initFormat = async () => { - const go = new Go(); - const result = await WebAssembly.instantiateStreaming(fetch(wasmModuleUrl), go.importObject) - go.run(result.instance) + const go = new Go() + const result = await WebAssembly.instantiateStreaming(fetch(wasmModuleUrl), go.importObject) + go.run(result.instance) } export const register = () => { - monaco.languages.register({ - id: 'spx', - }) +console.log("register") + monaco.languages.register({ + id: 'spx' + }) - monaco.editor.defineTheme("myTransparentTheme", { - base: "vs", - inherit: true, - rules: [ - { token: 'comment', foreground: '#F8BBD0', fontStyle: 'italic' }, - { token: 'string', foreground: '#9CCC65' }, - { token: 'operator', foreground: '#7FDAFF' }, - { token: 'number', foreground: '#3AA6D4' }, - { token: 'keyword', foreground: '#E4564A' }, - { token: 'typeKeywords', foreground: '#BA68C8' }, - { token: 'functions', foreground: '#FF80AB' }, - { token: 'brackets', foreground: '#00ACC1' }, - ], - colors: { - "editor.background": "#FFFFFF", // 透明背景 - "scrollbar.shadow": "#FFFFFF00", // 滚动条阴影颜色 - "scrollbarSlider.background": "#fa81a833", // 滚动条背景颜色 - "scrollbarSlider.hoverBackground": "#fa81a866", // 鼠标悬停时滚动条背景颜色 - "scrollbarSlider.activeBackground": "#fa81a899", // 激活时滚动条背景颜色 - "scrollbarSlider.width": "8px !important", // 激活时滚动条背景颜色 - "minimap.background": "#fa81a810", // 小地图背景颜色 - "minimapSlider.background": "#fa81a833", // 小地图滑块背景颜色 - "minimapSlider.hoverBackground": "#FFFFFF66", // 小地图滑块鼠标悬停背景颜色 - "minimapSlider.activeBackground": "#FFFFFF99", // 小地图滑块激活背景颜色 - }, - }); + monaco.editor.defineTheme('myTransparentTheme', { + base: 'vs', + inherit: true, + rules: [ + { token: 'comment', foreground: '#F8BBD0', fontStyle: 'italic' }, + { token: 'string', foreground: '#9CCC65' }, + { token: 'operator', foreground: '#7FDAFF' }, + { token: 'number', foreground: '#3AA6D4' }, + { token: 'keyword', foreground: '#E4564A' }, + { token: 'typeKeywords', foreground: '#BA68C8' }, + { token: 'functions', foreground: '#FF80AB' }, + { token: 'brackets', foreground: '#00ACC1' } + ], + colors: { + 'editor.background': '#FFFFFF', // 透明背景 + 'scrollbar.shadow': '#FFFFFF00', // 滚动条阴影颜色 + 'scrollbarSlider.background': '#fa81a833', // 滚动条背景颜色 + 'scrollbarSlider.hoverBackground': '#fa81a866', // 鼠标悬停时滚动条背景颜色 + 'scrollbarSlider.activeBackground': '#fa81a899', // 激活时滚动条背景颜色 + 'scrollbarSlider.width': '8px !important', // 激活时滚动条背景颜色 + 'minimap.background': '#fa81a810', // 小地图背景颜色 + 'minimapSlider.background': '#fa81a833', // 小地图滑块背景颜色 + 'minimapSlider.hoverBackground': '#FFFFFF66', // 小地图滑块鼠标悬停背景颜色 + 'minimapSlider.activeBackground': '#FFFFFF99' // 小地图滑块激活背景颜色 + } + }) - monaco.languages.setLanguageConfiguration('spx', LanguageConfig) + monaco.languages.setLanguageConfiguration('spx', LanguageConfig) - // Match token and highlight - monaco.languages.setMonarchTokensProvider('spx', MonarchTokensProviderConfig); - // Code hint - monaco.languages.registerCompletionItemProvider('spx', completionItemProvider); - initFormat() + // Match token and highlight + monaco.languages.setMonarchTokensProvider('spx', MonarchTokensProviderConfig) + // Code hint + monaco.languages.registerCompletionItemProvider('spx', completionItemProvider) + initFormat() } - - -