diff --git a/monaco.d.ts b/monaco.d.ts index 1021c98f..44caf572 100644 --- a/monaco.d.ts +++ b/monaco.d.ts @@ -413,6 +413,12 @@ declare namespace monaco.languages.typescript { errorCodes: number[], formatOptions: any ): Promise>; + /** + * Get inlay hints in the range of the file. + * @param fileName + * @returns `Promise` + */ + provideInlayHints(fileName: string, start: number, end: number): Promise>; } export const typescriptVersion: string; export const typescriptDefaults: LanguageServiceDefaults; diff --git a/src/languageFeatures.ts b/src/languageFeatures.ts index db332fa6..648a48d6 100644 --- a/src/languageFeatures.ts +++ b/src/languageFeatures.ts @@ -1221,3 +1221,49 @@ export class RenameAdapter extends Adapter implements languages.RenameProvider { return { edits }; } } + +// --- inlay hints ---- + +export class InlayHintsAdapter extends Adapter implements languages.InlayHintsProvider { + public async provideInlayHints( + model: editor.ITextModel, + range: Range, + token: CancellationToken + ): Promise { + const resource = model.uri; + const fileName = resource.toString(); + const start = model.getOffsetAt({ + lineNumber: range.startLineNumber, + column: range.startColumn + }); + const end = model.getOffsetAt({ + lineNumber: range.endLineNumber, + column: range.endColumn + }); + const worker = await this._worker(resource); + if (model.isDisposed()) { + return []; + } + + const hints = await worker.provideInlayHints(fileName, start, end); + + return hints.map(hint => { + return { + ...hint, + position: model.getPositionAt(hint.position), + kind: this._convertHintKind(hint.kind) + } + }) + } + + private _convertHintKind (kind?: ts.InlayHintKind) { + switch (kind) { + case "Parameter": + return languages.InlayHintKind.Parameter; + case "Type": + return languages.InlayHintKind.Type; + default: + return languages.InlayHintKind.Other; + } + } +} \ No newline at end of file diff --git a/src/monaco.contribution.ts b/src/monaco.contribution.ts index a2f8984d..e646c636 100644 --- a/src/monaco.contribution.ts +++ b/src/monaco.contribution.ts @@ -452,6 +452,17 @@ export interface TypeScriptWorker { errorCodes: number[], formatOptions: any ): Promise>; + + /** + * Get inlay hints in the range of the file. + * @param fileName + * @returns `Promise` + */ + provideInlayHints( + fileName: string, + start: number, + end: number, + ): Promise>; } // --- TypeScript configuration and defaults --------- diff --git a/src/tsMode.ts b/src/tsMode.ts index bc8498dd..01de0376 100644 --- a/src/tsMode.ts +++ b/src/tsMode.ts @@ -81,7 +81,7 @@ function setupMode( ); languages.registerCodeActionProvider(modeId, new languageFeatures.CodeActionAdaptor(worker)); languages.registerRenameProvider(modeId, new languageFeatures.RenameAdapter(worker)); + languages.registerInlayHintsProvider(modeId, new languageFeatures.InlayHintsAdapter(worker)); new languageFeatures.DiagnosticsAdapter(libFiles, defaults, modeId, worker); - return worker; } diff --git a/src/tsWorker.ts b/src/tsWorker.ts index 0e3efdf6..52452a63 100644 --- a/src/tsWorker.ts +++ b/src/tsWorker.ts @@ -253,7 +253,7 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, ITypeScriptWork entry, undefined, undefined, - undefined, + undefined, undefined ); } @@ -415,6 +415,29 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, ITypeScriptWork async updateExtraLibs(extraLibs: IExtraLibs): Promise { this._extraLibs = extraLibs; } + + async provideInlayHints(fileName: string, start: number, end: number): Promise { + if (fileNameIsLib(fileName)) { + return []; + } + const preferences: ts.InlayHintsOptions = { + includeInlayParameterNameHints: "all" + }; + const span: ts.TextSpan = { + start, + length: end - start + } + + try { + return this._languageService.provideInlayHints( + fileName, + span, + preferences + ); + } catch { + return []; + } + } } export interface ICreateData {