From 1cda6c638223c3d26f1b07deb24c6ba7b699014b Mon Sep 17 00:00:00 2001 From: johnsoncodehk Date: Thu, 9 Jun 2022 18:25:57 +0800 Subject: [PATCH] feat: implemented provideDocumentSymbols --- src/monaco/code2monaco.ts | 79 +++++++++++++++++++++++++++++++++++++ src/monaco/ls.ts | 83 ++++++++++++++++++++++++++------------- 2 files changed, 134 insertions(+), 28 deletions(-) diff --git a/src/monaco/code2monaco.ts b/src/monaco/code2monaco.ts index 3e3cae9c..9ff86fa8 100644 --- a/src/monaco/code2monaco.ts +++ b/src/monaco/code2monaco.ts @@ -285,3 +285,82 @@ export function asWorkspaceEdit(workspaceEdit: vscode.WorkspaceEdit): monaco.lan } return result; } + +export function asDocumentSymbol(symbol: vscode.SymbolInformation): monaco.languages.DocumentSymbol { + return { + name: symbol.name, + detail: '', + kind: asSymbolKind(symbol.kind), + tags: symbol.tags?.map(asSymbolTag) ?? [], + containerName: symbol.containerName, + range: asRange(symbol.location.range), + selectionRange: asRange(symbol.location.range), + children: [], + }; +} + +export function asSymbolTag(tag: vscode.SymbolTag): monaco.languages.SymbolTag { + switch (tag) { + case vscode.SymbolTag.Deprecated: + return monaco.languages.SymbolTag.Deprecated; + } +} + +export function asSymbolKind(kind: vscode.SymbolKind): monaco.languages.SymbolKind { + switch (kind) { + case vscode.SymbolKind.File: + return monaco.languages.SymbolKind.File; + case vscode.SymbolKind.Module: + return monaco.languages.SymbolKind.Module; + case vscode.SymbolKind.Namespace: + return monaco.languages.SymbolKind.Namespace; + case vscode.SymbolKind.Package: + return monaco.languages.SymbolKind.Package; + case vscode.SymbolKind.Class: + return monaco.languages.SymbolKind.Class; + case vscode.SymbolKind.Method: + return monaco.languages.SymbolKind.Method; + case vscode.SymbolKind.Property: + return monaco.languages.SymbolKind.Property; + case vscode.SymbolKind.Field: + return monaco.languages.SymbolKind.Field; + case vscode.SymbolKind.Constructor: + return monaco.languages.SymbolKind.Constructor; + case vscode.SymbolKind.Enum: + return monaco.languages.SymbolKind.Enum; + case vscode.SymbolKind.Interface: + return monaco.languages.SymbolKind.Interface; + case vscode.SymbolKind.Function: + return monaco.languages.SymbolKind.Function; + case vscode.SymbolKind.Variable: + return monaco.languages.SymbolKind.Variable; + case vscode.SymbolKind.Constant: + return monaco.languages.SymbolKind.Constant; + case vscode.SymbolKind.String: + return monaco.languages.SymbolKind.String; + case vscode.SymbolKind.Number: + return monaco.languages.SymbolKind.Number; + case vscode.SymbolKind.Boolean: + return monaco.languages.SymbolKind.Boolean; + case vscode.SymbolKind.Array: + return monaco.languages.SymbolKind.Array; + case vscode.SymbolKind.Object: + return monaco.languages.SymbolKind.Object; + case vscode.SymbolKind.Key: + return monaco.languages.SymbolKind.Key; + case vscode.SymbolKind.Null: + return monaco.languages.SymbolKind.Null; + case vscode.SymbolKind.EnumMember: + return monaco.languages.SymbolKind.EnumMember; + case vscode.SymbolKind.Struct: + return monaco.languages.SymbolKind.Struct; + case vscode.SymbolKind.Event: + return monaco.languages.SymbolKind.Event; + case vscode.SymbolKind.Operator: + return monaco.languages.SymbolKind.Operator; + case vscode.SymbolKind.TypeParameter: + return monaco.languages.SymbolKind.TypeParameter; + default: + return monaco.languages.SymbolKind.File; + } +} diff --git a/src/monaco/ls.ts b/src/monaco/ls.ts index 30959d29..8b68e6f6 100644 --- a/src/monaco/ls.ts +++ b/src/monaco/ls.ts @@ -1,8 +1,8 @@ /* eslint-disable sonarjs/no-duplicate-string */ import * as monaco from 'monaco-editor'; -import type * as vscode from 'vscode-languageserver-protocol'; +import * as vscode from 'vscode-languageserver-protocol'; import * as ts from 'typescript/lib/tsserverlibrary'; -import { createLanguageService, type LanguageService, type LanguageServiceHost } from '@volar/vue-language-service'; +import { createLanguageService, getDocumentService, type LanguageService, type LanguageServiceHost } from '@volar/vue-language-service'; import type { Ref } from 'vue'; import { onBeforeUnmount, ref } from 'vue'; import * as code2monaco from './code2monaco'; @@ -190,9 +190,11 @@ export async function setupLs(modelsMap: Ref(); + const documents = new WeakMap(); disposables.value.push( // TODO: registerTokensProviderFactory @@ -222,6 +224,43 @@ export async function setupLs(modelsMap: Ref { + const codeResult = await ls.getSignatureHelp( + model.uri.toString(), + monaco2code.asPosition(position), + ); + if (codeResult) { + return { + value: code2monaco.asSignatureHelp(codeResult), + dispose: () => { }, + }; + } + }, + }), + monaco.languages.registerHoverProvider(lang, { + provideHover: async (model, position) => { + const codeResult = await ls.doHover( + model.uri.toString(), + monaco2code.asPosition(position), + ); + if (codeResult) { + return code2monaco.asHover(codeResult); + } + }, + }), + monaco.languages.registerDocumentSymbolProvider(lang, { + provideDocumentSymbols: async (model) => { + const document = documents.get(model); + if (document) { + const codeResult = await ds.findDocumentSymbols(document); + if (codeResult) { + return codeResult.map(code2monaco.asDocumentSymbol); + } + } + }, + }), monaco.languages.registerCompletionItemProvider(lang, { // https://github.com/johnsoncodehk/volar/blob/2f786182250d27e99cc3714fbfc7d209616e2289/packages/vue-language-server/src/registers/registerlanguageFeatures.ts#L57 triggerCharacters: '!@#$%^&*()_+-=`~{}|[]\:";\'<>?,./ '.split(''), @@ -249,17 +288,6 @@ export async function setupLs(modelsMap: Ref { - const codeResult = await ls.doHover( - model.uri.toString(), - monaco2code.asPosition(position), - ); - if (codeResult) { - return code2monaco.asHover(codeResult); - } - }, - }), monaco.languages.registerDefinitionProvider(lang, { provideDefinition: async (model, position) => { const codeResult = await ls.findDefinition( @@ -272,24 +300,23 @@ export async function setupLs(modelsMap: Ref { - const codeResult = await ls.getSignatureHelp( - model.uri.toString(), - monaco2code.asPosition(position), - ); - if (codeResult) { - return { - value: code2monaco.asSignatureHelp(codeResult), - dispose: () => { }, - }; - } - }, - }), ); return ls; + + function getTextDocument(model: monaco.editor.ITextModel) { + let document = documents.get(model); + if (!document || document.version !== model.getVersionId()) { + document = vscode.TextDocument.create( + model.uri.toString(), + model.getLanguageId(), + model.getVersionId(), + model.getValue(), + ); + documents.set(model, document); + } + return document; + } } export function setupValidate(editor: monaco.editor.IStandaloneCodeEditor, ls: LanguageService) {