diff --git a/frontend/package.json b/frontend/package.json index 07c55542f..2cbc391cc 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -20,12 +20,12 @@ "prettier": "prettier --write ." }, "dependencies": { - "@codemirror/lang-html": "^6.4.9", - "@codemirror/lang-json": "^6.0.1", - "@codemirror/lang-php": "^6.0.1", - "@codemirror/language": "^6.10.2", - "@codemirror/legacy-modes": "^6.4.0", - "@codemirror/theme-one-dark": "^6.1.2", + "@codemirror/lang-html": "^6.4.10", + "@codemirror/lang-json": "^6.0.2", + "@codemirror/lang-php": "^6.0.2", + "@codemirror/language": "^6.11.3", + "@codemirror/legacy-modes": "^6.5.1", + "@codemirror/theme-one-dark": "^6.1.3", "@element-plus/icons-vue": "^1.1.4", "@highlightjs/vue-plugin": "^2.1.0", "@vue-office/docx": "^1.6.2", @@ -35,7 +35,7 @@ "@xterm/xterm": "^5.5.0", "anser": "^2.3.2", "axios": "^1.7.2", - "codemirror": "^6.0.1", + "codemirror": "^6.0.2", "crypto-js": "^4.2.0", "echarts": "^5.5.0", "element-plus": "^2.11.2", diff --git a/frontend/src/components/codemirror-pro/index.vue b/frontend/src/components/codemirror-pro/index.vue index da477012b..cf274a7cf 100644 --- a/frontend/src/components/codemirror-pro/index.vue +++ b/frontend/src/components/codemirror-pro/index.vue @@ -15,7 +15,7 @@ import { yaml } from '@codemirror/legacy-modes/mode/yaml'; import { shell } from '@codemirror/legacy-modes/mode/shell'; import { dockerFile } from '@codemirror/legacy-modes/mode/dockerfile'; import { javascript } from '@codemirror/legacy-modes/mode/javascript'; -import { placeholder } from '@codemirror/view'; +import { KeyBinding, placeholder } from '@codemirror/view'; import { json } from '@codemirror/lang-json'; import { keymap } from '@codemirror/view'; import { defaultKeymap, indentWithTab } from '@codemirror/commands'; @@ -68,6 +68,49 @@ const customStyle = computed(() => ({ width: '100%', })); +const toggleLineComment = (mode: string) => { + return (view: EditorView) => { + const commentChar = + mode === 'yaml' || mode === 'shell' || mode === 'nginx' || mode === 'dockerfile' ? '#' : '//'; + + const { state } = view; + + const transaction = state.changeByRange((range) => { + let line = state.doc.lineAt(range.from); + let text = line.text; + let changes; + + if (text.trim().startsWith(commentChar)) { + const pos = line.from + text.indexOf(commentChar); + changes = { from: pos, to: pos + commentChar.length, insert: '' }; + } else { + changes = { from: line.from, insert: commentChar }; + } + + return { + changes, + range, + }; + }); + + view.dispatch(transaction); + return true; + }; +}; + +const customKeymap: KeyBinding[] = [ + { + key: 'Alt-/', + run: toggleLineComment(props.mode), + preventDefault: true, + }, + { + key: 'Mod-/', + run: toggleLineComment(props.mode), + preventDefault: true, + }, +]; + const initCodeMirror = () => { const defaultTheme = EditorView.theme({ '&.cm-editor': { @@ -80,7 +123,7 @@ const initCodeMirror = () => { defaultTheme, oneDark, basicSetup, - keymap.of([...defaultKeymap, indentWithTab]), + keymap.of([...defaultKeymap, indentWithTab, ...customKeymap]), EditorView.updateListener.of((v: any) => { if (v.docChanged) { emit('update:modelValue', v.state.doc.toString()); @@ -89,9 +132,11 @@ const initCodeMirror = () => { placeholder(props.placeholder), EditorView.editable.of(!props.disabled), ]; + if (props.lineWrapping) { extensions.push(EditorView.lineWrapping); } + switch (props.mode) { case 'dockerfile': extensions.push(StreamLanguage.define(dockerFile)); @@ -112,10 +157,12 @@ const initCodeMirror = () => { extensions.push(StreamLanguage.define(shell)); break; } + let startState = EditorState.create({ doc: content.value, extensions: extensions, }); + editorView.value = new EditorView({ state: startState, parent: editorRef.value,