Skip to content

Commit 1cda6c6

Browse files
committed
feat: implemented provideDocumentSymbols
1 parent 5ca6318 commit 1cda6c6

File tree

2 files changed

+134
-28
lines changed

2 files changed

+134
-28
lines changed

src/monaco/code2monaco.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,3 +285,82 @@ export function asWorkspaceEdit(workspaceEdit: vscode.WorkspaceEdit): monaco.lan
285285
}
286286
return result;
287287
}
288+
289+
export function asDocumentSymbol(symbol: vscode.SymbolInformation): monaco.languages.DocumentSymbol {
290+
return {
291+
name: symbol.name,
292+
detail: '',
293+
kind: asSymbolKind(symbol.kind),
294+
tags: symbol.tags?.map(asSymbolTag) ?? [],
295+
containerName: symbol.containerName,
296+
range: asRange(symbol.location.range),
297+
selectionRange: asRange(symbol.location.range),
298+
children: [],
299+
};
300+
}
301+
302+
export function asSymbolTag(tag: vscode.SymbolTag): monaco.languages.SymbolTag {
303+
switch (tag) {
304+
case vscode.SymbolTag.Deprecated:
305+
return monaco.languages.SymbolTag.Deprecated;
306+
}
307+
}
308+
309+
export function asSymbolKind(kind: vscode.SymbolKind): monaco.languages.SymbolKind {
310+
switch (kind) {
311+
case vscode.SymbolKind.File:
312+
return monaco.languages.SymbolKind.File;
313+
case vscode.SymbolKind.Module:
314+
return monaco.languages.SymbolKind.Module;
315+
case vscode.SymbolKind.Namespace:
316+
return monaco.languages.SymbolKind.Namespace;
317+
case vscode.SymbolKind.Package:
318+
return monaco.languages.SymbolKind.Package;
319+
case vscode.SymbolKind.Class:
320+
return monaco.languages.SymbolKind.Class;
321+
case vscode.SymbolKind.Method:
322+
return monaco.languages.SymbolKind.Method;
323+
case vscode.SymbolKind.Property:
324+
return monaco.languages.SymbolKind.Property;
325+
case vscode.SymbolKind.Field:
326+
return monaco.languages.SymbolKind.Field;
327+
case vscode.SymbolKind.Constructor:
328+
return monaco.languages.SymbolKind.Constructor;
329+
case vscode.SymbolKind.Enum:
330+
return monaco.languages.SymbolKind.Enum;
331+
case vscode.SymbolKind.Interface:
332+
return monaco.languages.SymbolKind.Interface;
333+
case vscode.SymbolKind.Function:
334+
return monaco.languages.SymbolKind.Function;
335+
case vscode.SymbolKind.Variable:
336+
return monaco.languages.SymbolKind.Variable;
337+
case vscode.SymbolKind.Constant:
338+
return monaco.languages.SymbolKind.Constant;
339+
case vscode.SymbolKind.String:
340+
return monaco.languages.SymbolKind.String;
341+
case vscode.SymbolKind.Number:
342+
return monaco.languages.SymbolKind.Number;
343+
case vscode.SymbolKind.Boolean:
344+
return monaco.languages.SymbolKind.Boolean;
345+
case vscode.SymbolKind.Array:
346+
return monaco.languages.SymbolKind.Array;
347+
case vscode.SymbolKind.Object:
348+
return monaco.languages.SymbolKind.Object;
349+
case vscode.SymbolKind.Key:
350+
return monaco.languages.SymbolKind.Key;
351+
case vscode.SymbolKind.Null:
352+
return monaco.languages.SymbolKind.Null;
353+
case vscode.SymbolKind.EnumMember:
354+
return monaco.languages.SymbolKind.EnumMember;
355+
case vscode.SymbolKind.Struct:
356+
return monaco.languages.SymbolKind.Struct;
357+
case vscode.SymbolKind.Event:
358+
return monaco.languages.SymbolKind.Event;
359+
case vscode.SymbolKind.Operator:
360+
return monaco.languages.SymbolKind.Operator;
361+
case vscode.SymbolKind.TypeParameter:
362+
return monaco.languages.SymbolKind.TypeParameter;
363+
default:
364+
return monaco.languages.SymbolKind.File;
365+
}
366+
}

src/monaco/ls.ts

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/* eslint-disable sonarjs/no-duplicate-string */
22
import * as monaco from 'monaco-editor';
3-
import type * as vscode from 'vscode-languageserver-protocol';
3+
import * as vscode from 'vscode-languageserver-protocol';
44
import * as ts from 'typescript/lib/tsserverlibrary';
5-
import { createLanguageService, type LanguageService, type LanguageServiceHost } from '@volar/vue-language-service';
5+
import { createLanguageService, getDocumentService, type LanguageService, type LanguageServiceHost } from '@volar/vue-language-service';
66
import type { Ref } from 'vue';
77
import { onBeforeUnmount, ref } from 'vue';
88
import * as code2monaco from './code2monaco';
@@ -190,9 +190,11 @@ export async function setupLs(modelsMap: Ref<Map<string, monaco.editor.ITextMode
190190
tsWithAny.setSys(sys);
191191

192192
const ls = createLanguageService({ typescript: ts }, host, undefined, undefined, undefined, []);
193+
const ds = getDocumentService({ typescript: ts }, undefined, undefined, []);
193194
disposables.value.push(ls);
194195

195196
const completionItems = new WeakMap<monaco.languages.CompletionItem, vscode.CompletionItem>();
197+
const documents = new WeakMap<monaco.editor.ITextModel, vscode.TextDocument>();
196198

197199
disposables.value.push(
198200
// TODO: registerTokensProviderFactory
@@ -222,6 +224,43 @@ export async function setupLs(modelsMap: Ref<Map<string, monaco.editor.ITextMode
222224
}
223225
},
224226
}),
227+
monaco.languages.registerSignatureHelpProvider(lang, {
228+
signatureHelpTriggerCharacters: ['(', ','],
229+
provideSignatureHelp: async (model, position) => {
230+
const codeResult = await ls.getSignatureHelp(
231+
model.uri.toString(),
232+
monaco2code.asPosition(position),
233+
);
234+
if (codeResult) {
235+
return {
236+
value: code2monaco.asSignatureHelp(codeResult),
237+
dispose: () => { },
238+
};
239+
}
240+
},
241+
}),
242+
monaco.languages.registerHoverProvider(lang, {
243+
provideHover: async (model, position) => {
244+
const codeResult = await ls.doHover(
245+
model.uri.toString(),
246+
monaco2code.asPosition(position),
247+
);
248+
if (codeResult) {
249+
return code2monaco.asHover(codeResult);
250+
}
251+
},
252+
}),
253+
monaco.languages.registerDocumentSymbolProvider(lang, {
254+
provideDocumentSymbols: async (model) => {
255+
const document = documents.get(model);
256+
if (document) {
257+
const codeResult = await ds.findDocumentSymbols(document);
258+
if (codeResult) {
259+
return codeResult.map(code2monaco.asDocumentSymbol);
260+
}
261+
}
262+
},
263+
}),
225264
monaco.languages.registerCompletionItemProvider(lang, {
226265
// https://github.com/johnsoncodehk/volar/blob/2f786182250d27e99cc3714fbfc7d209616e2289/packages/vue-language-server/src/registers/registerlanguageFeatures.ts#L57
227266
triggerCharacters: '!@#$%^&*()_+-=`~{}|[]\:";\'<>?,./ '.split(''),
@@ -249,17 +288,6 @@ export async function setupLs(modelsMap: Ref<Map<string, monaco.editor.ITextMode
249288
return monacoItem;
250289
},
251290
}),
252-
monaco.languages.registerHoverProvider(lang, {
253-
provideHover: async (model, position) => {
254-
const codeResult = await ls.doHover(
255-
model.uri.toString(),
256-
monaco2code.asPosition(position),
257-
);
258-
if (codeResult) {
259-
return code2monaco.asHover(codeResult);
260-
}
261-
},
262-
}),
263291
monaco.languages.registerDefinitionProvider(lang, {
264292
provideDefinition: async (model, position) => {
265293
const codeResult = await ls.findDefinition(
@@ -272,24 +300,23 @@ export async function setupLs(modelsMap: Ref<Map<string, monaco.editor.ITextMode
272300
}
273301
},
274302
}),
275-
monaco.languages.registerSignatureHelpProvider(lang, {
276-
signatureHelpTriggerCharacters: ['(', ','],
277-
provideSignatureHelp: async (model, position) => {
278-
const codeResult = await ls.getSignatureHelp(
279-
model.uri.toString(),
280-
monaco2code.asPosition(position),
281-
);
282-
if (codeResult) {
283-
return {
284-
value: code2monaco.asSignatureHelp(codeResult),
285-
dispose: () => { },
286-
};
287-
}
288-
},
289-
}),
290303
);
291304

292305
return ls;
306+
307+
function getTextDocument(model: monaco.editor.ITextModel) {
308+
let document = documents.get(model);
309+
if (!document || document.version !== model.getVersionId()) {
310+
document = vscode.TextDocument.create(
311+
model.uri.toString(),
312+
model.getLanguageId(),
313+
model.getVersionId(),
314+
model.getValue(),
315+
);
316+
documents.set(model, document);
317+
}
318+
return document;
319+
}
293320
}
294321

295322
export function setupValidate(editor: monaco.editor.IStandaloneCodeEditor, ls: LanguageService) {

0 commit comments

Comments
 (0)