diff options
| author | vsrs <vit@conrlab.com> | 2020-06-03 14:15:54 +0300 |
|---|---|---|
| committer | vsrs <vit@conrlab.com> | 2020-06-05 14:59:26 +0300 |
| commit | 7d0dd17b09240385333805637ea17992a8089cf2 (patch) | |
| tree | 605249f14a8d7c8071362e31be28ca9c17b55173 /editors/code/src/client.ts | |
| parent | 913a623281ed4cd190ca04845c64e5054d176a2a (diff) | |
| download | rust-7d0dd17b09240385333805637ea17992a8089cf2.tar.gz rust-7d0dd17b09240385333805637ea17992a8089cf2.zip | |
Add hover actions as LSP extension
Diffstat (limited to 'editors/code/src/client.ts')
| -rw-r--r-- | editors/code/src/client.ts | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index 40ad1e3cd84..9df6702839b 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts @@ -7,6 +7,29 @@ import { CallHierarchyFeature } from 'vscode-languageclient/lib/callHierarchy.pr import { SemanticTokensFeature, DocumentSemanticsTokensSignature } from 'vscode-languageclient/lib/semanticTokens.proposed'; import { assert } from './util'; +function toTrusted(obj: vscode.MarkedString): vscode.MarkedString { + const md = <vscode.MarkdownString>obj; + if (md && md.value.includes("```rust")) { + md.isTrusted = true; + return md; + } + return obj; +} + +function renderCommand(cmd: CommandLink) { + return `[${cmd.title}](command:${cmd.command}?${encodeURIComponent(JSON.stringify(cmd.arguments))} '${cmd.tooltip!}')`; +} + +function renderHoverActions(actions: CommandLinkGroup[]): vscode.MarkdownString { + const text = actions.map(group => + (group.title ? (group.title + " ") : "") + group.commands.map(renderCommand).join(' | ') + ).join('___'); + + const result = new vscode.MarkdownString(text); + result.isTrusted = true; + return result; +} + export function createClient(serverPath: string, cwd: string): lc.LanguageClient { // '.' Is the fallback if no folder is open // TODO?: Workspace folders support Uri's (eg: file://test.txt). @@ -35,6 +58,27 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient if (res === undefined) throw new Error('busy'); return res; }, + async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, _next: lc.ProvideHoverSignature) { + return client.sendRequest(lc.HoverRequest.type, client.code2ProtocolConverter.asTextDocumentPositionParams(document, position), token).then( + (result) => { + const hover = client.protocol2CodeConverter.asHover(result); + if (hover) { + // Workaround to support command links (trusted vscode.MarkdownString) in hovers + // https://github.com/microsoft/vscode/issues/33577 + hover.contents = hover.contents.map(toTrusted); + + const actions = (<any>result).actions; + if (actions) { + hover.contents.push(renderHoverActions(actions)); + } + } + return hover; + }, + (error) => { + client.logFailedRequest(lc.HoverRequest.type, error); + return Promise.resolve(null); + }); + }, // Using custom handling of CodeActions where each code action is resloved lazily // That's why we are not waiting for any command or edits async provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken, _next: lc.ProvideCodeActionsSignature) { @@ -129,6 +173,7 @@ class ExperimentalFeatures implements lc.StaticFeature { caps.snippetTextEdit = true; caps.codeActionGroup = true; caps.resolveCodeAction = true; + caps.hoverActions = true; capabilities.experimental = caps; } initialize(_capabilities: lc.ServerCapabilities<any>, _documentSelector: lc.DocumentSelector | undefined): void { |
