From 924fbe61928741a90f0f4b0bf344b0f7cf1df2e0 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Mon, 29 Jul 2024 14:36:42 -0700 Subject: [PATCH 1/5] add verbosity level to hover provider --- .../typescript-language-features/package.json | 29 +++++++++------ .../src/languageFeatures/hover.ts | 37 +++++++++++++++---- .../tsconfig.json | 1 + 3 files changed, 48 insertions(+), 19 deletions(-) diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index e93299d81694e..7182acd2bcc1e 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -14,7 +14,8 @@ "mappedEditsProvider", "codeActionAI", "codeActionRanges", - "documentPaste" + "documentPaste", + "editorHoverVerbosityLevel" ], "capabilities": { "virtualWorkspaces": { @@ -824,16 +825,16 @@ ], "enumDescriptions": [ "%typescript.locale.auto%", - "Deutsch", - "español", + "Deutsch", + "español", "English", - "français", - "italiano", - "日本語", - "한국어", - "русский", - "中文(简体)", - "中文(繁體)" + "français", + "italiano", + "日本語", + "한국어", + "русский", + "中文(简体)", + "中文(繁體)" ], "markdownDescription": "%typescript.locale%", "scope": "window" @@ -1482,14 +1483,18 @@ "type": "boolean", "default": false, "description": "%configuration.updateImportsOnPaste%", - "tags": ["experimental"] + "tags": [ + "experimental" + ] }, "typescript.experimental.updateImportsOnPaste": { "scope": "window", "type": "boolean", "default": false, "description": "%configuration.updateImportsOnPaste%", - "tags": ["experimental"] + "tags": [ + "experimental" + ] } } }, diff --git a/extensions/typescript-language-features/src/languageFeatures/hover.ts b/extensions/typescript-language-features/src/languageFeatures/hover.ts index 3012658036f87..0634563b90ccc 100644 --- a/extensions/typescript-language-features/src/languageFeatures/hover.ts +++ b/extensions/typescript-language-features/src/languageFeatures/hover.ts @@ -11,11 +11,13 @@ import { DocumentSelector } from '../configuration/documentSelector'; import { documentationToMarkdown } from './util/textRendering'; import * as typeConverters from '../typeConverters'; import FileConfigurationManager from './fileConfigurationManager'; - +import { API } from '../tsServer/api'; class TypeScriptHoverProvider implements vscode.HoverProvider { + private readonly hoverToLevel: Map = new Map(); + public constructor( private readonly client: ITypeScriptServiceClient, private readonly fileConfigurationManager: FileConfigurationManager, @@ -24,17 +26,24 @@ class TypeScriptHoverProvider implements vscode.HoverProvider { public async provideHover( document: vscode.TextDocument, position: vscode.Position, - token: vscode.CancellationToken - ): Promise { + token: vscode.CancellationToken, + context?: vscode.HoverContext, + ): Promise { const filepath = this.client.toOpenTsFilePath(document); if (!filepath) { return undefined; } + let verbosityLevel: number | undefined; + if (this.client.apiVersion.gte(API.v560)) { // >> TODO: use v570 + const previousLevel = (context?.previousHover && this.hoverToLevel.get(context.previousHover)) ?? 0; + verbosityLevel = Math.max(0, previousLevel + (context?.verbosityDelta ?? 0)); + } + const args = { ...typeConverters.Position.toFileLocationRequestArgs(filepath, position), verbosityLevel }; + const response = await this.client.interruptGetErr(async () => { await this.fileConfigurationManager.ensureConfigurationForDocument(document, token); - const args = typeConverters.Position.toFileLocationRequestArgs(filepath, position); return this.client.execute('quickinfo', args, token); }); @@ -42,9 +51,23 @@ class TypeScriptHoverProvider implements vscode.HoverProvider { return undefined; } - return new vscode.Hover( - this.getContents(document.uri, response.body, response._serverType), - typeConverters.Range.fromTextSpan(response.body)); + const contents = this.getContents(document.uri, response.body, response._serverType); + const range = typeConverters.Range.fromTextSpan(response.body); + const hover = verbosityLevel !== undefined ? + new vscode.VerboseHover( + contents, + range, + /*canIncreaseVerbosity*/ true, + /*canDecreaseVerbosity*/ verbosityLevel !== 0 + ) : new vscode.Hover( + contents, + range + ); + + if (verbosityLevel !== undefined) { + this.hoverToLevel.set(hover, verbosityLevel); + } + return hover; } private getContents( diff --git a/extensions/typescript-language-features/tsconfig.json b/extensions/typescript-language-features/tsconfig.json index 65557839ba60d..8fcf1b79833c1 100644 --- a/extensions/typescript-language-features/tsconfig.json +++ b/extensions/typescript-language-features/tsconfig.json @@ -18,5 +18,6 @@ "../../src/vscode-dts/vscode.proposed.multiDocumentHighlightProvider.d.ts", "../../src/vscode-dts/vscode.proposed.workspaceTrust.d.ts", "../../src/vscode-dts/vscode.proposed.documentPaste.d.ts", + "../../src/vscode-dts/vscode.proposed.editorHoverVerbosityLevel.d.ts", ] } From d6fd99f33a787c25fa0bbf83c10d96f5fb27be07 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Wed, 11 Sep 2024 08:38:51 -0700 Subject: [PATCH 2/5] cleanup --- .../src/languageFeatures/hover.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/extensions/typescript-language-features/src/languageFeatures/hover.ts b/extensions/typescript-language-features/src/languageFeatures/hover.ts index 0634563b90ccc..b7219daa4b977 100644 --- a/extensions/typescript-language-features/src/languageFeatures/hover.ts +++ b/extensions/typescript-language-features/src/languageFeatures/hover.ts @@ -15,8 +15,7 @@ import { API } from '../tsServer/api'; class TypeScriptHoverProvider implements vscode.HoverProvider { - - private readonly hoverToLevel: Map = new Map(); + private lastHoverAndLevel: [vscode.Hover, number] | undefined; public constructor( private readonly client: ITypeScriptServiceClient, @@ -36,8 +35,7 @@ class TypeScriptHoverProvider implements vscode.HoverProvider { let verbosityLevel: number | undefined; if (this.client.apiVersion.gte(API.v560)) { // >> TODO: use v570 - const previousLevel = (context?.previousHover && this.hoverToLevel.get(context.previousHover)) ?? 0; - verbosityLevel = Math.max(0, previousLevel + (context?.verbosityDelta ?? 0)); + verbosityLevel = Math.max(0, this.getPreviousLevel(context?.previousHover) + (context?.verbosityDelta ?? 0)); } const args = { ...typeConverters.Position.toFileLocationRequestArgs(filepath, position), verbosityLevel }; @@ -65,7 +63,7 @@ class TypeScriptHoverProvider implements vscode.HoverProvider { ); if (verbosityLevel !== undefined) { - this.hoverToLevel.set(hover, verbosityLevel); + this.lastHoverAndLevel = [hover, verbosityLevel]; } return hover; } @@ -95,6 +93,13 @@ class TypeScriptHoverProvider implements vscode.HoverProvider { parts.push(md); return parts; } + + private getPreviousLevel(previousHover: vscode.Hover | undefined): number { + if (previousHover && this.lastHoverAndLevel && this.lastHoverAndLevel[0] === previousHover) { + return this.lastHoverAndLevel[1]; + } + return 0; + } } export function register( From 17447b6ebe9fc8a716b4ac4cd982d8fa817e6fae Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Wed, 11 Sep 2024 09:14:32 -0700 Subject: [PATCH 3/5] update minimum ts version --- .../typescript-language-features/src/languageFeatures/hover.ts | 2 +- extensions/typescript-language-features/src/tsServer/api.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/src/languageFeatures/hover.ts b/extensions/typescript-language-features/src/languageFeatures/hover.ts index b7219daa4b977..f99f29a41d39b 100644 --- a/extensions/typescript-language-features/src/languageFeatures/hover.ts +++ b/extensions/typescript-language-features/src/languageFeatures/hover.ts @@ -34,7 +34,7 @@ class TypeScriptHoverProvider implements vscode.HoverProvider { } let verbosityLevel: number | undefined; - if (this.client.apiVersion.gte(API.v560)) { // >> TODO: use v570 + if (this.client.apiVersion.gte(API.v570)) { verbosityLevel = Math.max(0, this.getPreviousLevel(context?.previousHover) + (context?.verbosityDelta ?? 0)); } const args = { ...typeConverters.Position.toFileLocationRequestArgs(filepath, position), verbosityLevel }; diff --git a/extensions/typescript-language-features/src/tsServer/api.ts b/extensions/typescript-language-features/src/tsServer/api.ts index b70810989ecfe..7b6d160952ee2 100644 --- a/extensions/typescript-language-features/src/tsServer/api.ts +++ b/extensions/typescript-language-features/src/tsServer/api.ts @@ -30,6 +30,7 @@ export class API { public static readonly v540 = API.fromSimpleString('5.4.0'); public static readonly v550 = API.fromSimpleString('5.5.0'); public static readonly v560 = API.fromSimpleString('5.6.0'); + public static readonly v570 = API.fromSimpleString('5.7.0'); public static fromVersionString(versionString: string): API { let version = semver.valid(versionString); From a12778cef3ffe79427766e3d03430be8bd130bb9 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Mon, 23 Sep 2024 15:23:33 -0700 Subject: [PATCH 4/5] get `canIncreaseVerbosityLevel` from server response --- .../typescript-language-features/src/languageFeatures/hover.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/src/languageFeatures/hover.ts b/extensions/typescript-language-features/src/languageFeatures/hover.ts index f99f29a41d39b..fb43f8ac7c14a 100644 --- a/extensions/typescript-language-features/src/languageFeatures/hover.ts +++ b/extensions/typescript-language-features/src/languageFeatures/hover.ts @@ -55,7 +55,8 @@ class TypeScriptHoverProvider implements vscode.HoverProvider { new vscode.VerboseHover( contents, range, - /*canIncreaseVerbosity*/ true, + // @ts-expect-error + /*canIncreaseVerbosity*/ response.body.canIncreaseVerbosityLevel, /*canDecreaseVerbosity*/ verbosityLevel !== 0 ) : new vscode.Hover( contents, From ca8d20e11e925af4170ae7a84ce9041565fd49e0 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Mon, 23 Sep 2024 15:55:58 -0700 Subject: [PATCH 5/5] add expandable hover experimental setting --- extensions/typescript-language-features/package.json | 9 +++++++++ extensions/typescript-language-features/package.nls.json | 1 + .../src/languageFeatures/hover.ts | 3 ++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index 7182acd2bcc1e..cfda8f8c805f1 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -1495,6 +1495,15 @@ "tags": [ "experimental" ] + }, + "typescript.experimental.expandableHover": { + "type": "boolean", + "default": false, + "description": "%configuration.expandableHover%", + "scope": "window", + "tags": [ + "experimental" + ] } } }, diff --git a/extensions/typescript-language-features/package.nls.json b/extensions/typescript-language-features/package.nls.json index d2a0ca892fa79..d9c4ddb2a65b8 100644 --- a/extensions/typescript-language-features/package.nls.json +++ b/extensions/typescript-language-features/package.nls.json @@ -237,6 +237,7 @@ "configuration.tsserver.web.typeAcquisition.enabled": "Enable/disable package acquisition on the web. This enables IntelliSense for imported packages. Requires `#typescript.tsserver.web.projectWideIntellisense.enabled#`. Currently not supported for Safari.", "configuration.tsserver.nodePath": "Run TS Server on a custom Node installation. This can be a path to a Node executable, or 'node' if you want VS Code to detect a Node installation.", "configuration.updateImportsOnPaste": "Automatically update imports when pasting code. Requires TypeScript 5.6+.", + "configuration.expandableHover": "(Experimental) Enable/disable expanding on hover.", "walkthroughs.nodejsWelcome.title": "Get started with JavaScript and Node.js", "walkthroughs.nodejsWelcome.description": "Make the most of Visual Studio Code's first-class JavaScript experience.", "walkthroughs.nodejsWelcome.downloadNode.forMacOrWindows.title": "Install Node.js", diff --git a/extensions/typescript-language-features/src/languageFeatures/hover.ts b/extensions/typescript-language-features/src/languageFeatures/hover.ts index fb43f8ac7c14a..edb08d029faa2 100644 --- a/extensions/typescript-language-features/src/languageFeatures/hover.ts +++ b/extensions/typescript-language-features/src/languageFeatures/hover.ts @@ -33,8 +33,9 @@ class TypeScriptHoverProvider implements vscode.HoverProvider { return undefined; } + const enableExpandableHover = vscode.workspace.getConfiguration('typescript').get('experimental.expandableHover'); let verbosityLevel: number | undefined; - if (this.client.apiVersion.gte(API.v570)) { + if (enableExpandableHover && this.client.apiVersion.gte(API.v570)) { verbosityLevel = Math.max(0, this.getPreviousLevel(context?.previousHover) + (context?.verbosityDelta ?? 0)); } const args = { ...typeConverters.Position.toFileLocationRequestArgs(filepath, position), verbosityLevel };