diff --git a/src/components/widgets/filesystem/setupMonaco.features.ts b/src/components/widgets/filesystem/setupMonaco.features.ts index d9101cd3ac..86bbee4087 100644 --- a/src/components/widgets/filesystem/setupMonaco.features.ts +++ b/src/components/widgets/filesystem/setupMonaco.features.ts @@ -3,6 +3,7 @@ import 'monaco-editor/esm/vs/editor/editor.all.js' // full list of features on 'monaco-editor/esm/metadata.js' import 'monaco-editor/esm/vs/editor/standalone/browser/iPadShowKeyboard/iPadShowKeyboard.js' import 'monaco-editor/esm/vs/editor/standalone/browser/quickAccess/standaloneGotoLineQuickAccess.js' +import 'monaco-editor/esm/vs/editor/standalone/browser/quickAccess/standaloneGotoSymbolQuickAccess.js' import 'monaco-editor/esm/vs/editor/standalone/browser/quickAccess/standaloneCommandsQuickAccess.js' import 'monaco-editor/esm/vs/language/css/monaco.contribution' diff --git a/src/components/widgets/filesystem/setupMonaco.ts b/src/components/widgets/filesystem/setupMonaco.ts index 5ae78b3355..cfc3dc4aa4 100644 --- a/src/components/widgets/filesystem/setupMonaco.ts +++ b/src/components/widgets/filesystem/setupMonaco.ts @@ -131,6 +131,81 @@ async function setupMonaco () { window.open(url) }) + monaco.languages.registerDocumentSymbolProvider('klipper-config', { + provideDocumentSymbols: (model) => { + const linesContent = model.getLinesContent() + + const sectionBlocks = linesContent + .reduce, range: monaco.IRange }>>((state, lineContent, index) => { + const section = /^\[[^\]]+\]/.exec(lineContent) + + if (section) { + state.result.push(state.current = { + name: section[0], + children: { result: [] }, + range: { + startLineNumber: index + 1, + startColumn: model.getLineFirstNonWhitespaceColumn(index + 1), + endLineNumber: index + 1, + endColumn: model.getLineLastNonWhitespaceColumn(index + 1) + } + }) + } else { + const isNotComment = /^\s*[^#;]/.test(lineContent) + + if (isNotComment && state.current) { + const property = /^(\S+)\s*[:=]/.exec(lineContent) + + if (property) { + state.current.children.result.push(state.current.children.current = { + name: property[1], + range: { + startLineNumber: index + 1, + startColumn: model.getLineFirstNonWhitespaceColumn(index + 1), + endLineNumber: index + 1, + endColumn: model.getLineLastNonWhitespaceColumn(index + 1) + } + }) + } else if (state.current.children.current) { + state.current.children.current.range = { + ...state.current.children.current.range, + endLineNumber: index + 1, + endColumn: model.getLineLastNonWhitespaceColumn(index + 1) + } + } + + state.current.range = { + ...state.current.range, + endLineNumber: index + 1, + endColumn: model.getLineLastNonWhitespaceColumn(index + 1) + } + } + } + + return state + }, { result: [] }) + .result + + return sectionBlocks + .map(section => ({ + name: section.name, + detail: section.name, + kind: monaco.languages.SymbolKind.Namespace, + range: section.range, + selectionRange: section.range, + tags: [], + children: section.children.result.map(child => ({ + name: child.name, + detail: child.name, + kind: monaco.languages.SymbolKind.Property, + range: child.range, + selectionRange: child.range, + tags: [] + })) + })) + } + }) + monaco.languages.registerCodeLensProvider('klipper-config', { provideCodeLenses: (model) => { const { service } = app.$typedGetters['server/getConfigMapByFilename'](model.uri.path.split('/').pop()!) ?? {}