@@ -3,73 +3,13 @@ import * as lc from "vscode-languageclient/node";
33import * as vscode from "vscode" ;
44import * as ra from "../src/lsp_ext" ;
55import * as Is from "vscode-languageclient/lib/common/utils/is" ;
6- import { assert } from "./util" ;
6+ import { assert , unwrapUndefinable } from "./util" ;
77import * as diagnostics from "./diagnostics" ;
88import { WorkspaceEdit } from "vscode" ;
99import { type Config , prepareVSCodeConfig } from "./config" ;
10- import { randomUUID } from "crypto" ;
1110import { sep as pathSeparator } from "path" ;
12- import { unwrapUndefinable } from "./undefinable" ;
1311import { RaLanguageClient } from "./lang_client" ;
1412
15- export interface Env {
16- [ name : string ] : string ;
17- }
18-
19- // Command URIs have a form of command:command-name?arguments, where
20- // arguments is a percent-encoded array of data we want to pass along to
21- // the command function. For "Show References" this is a list of all file
22- // URIs with locations of every reference, and it can get quite long.
23- //
24- // To work around it we use an intermediary linkToCommand command. When
25- // we render a command link, a reference to a command with all its arguments
26- // is stored in a map, and instead a linkToCommand link is rendered
27- // with the key to that map.
28- export const LINKED_COMMANDS = new Map < string , ra . CommandLink > ( ) ;
29-
30- // For now the map is cleaned up periodically (I've set it to every
31- // 10 minutes). In general case we'll probably need to introduce TTLs or
32- // flags to denote ephemeral links (like these in hover popups) and
33- // persistent links and clean those separately. But for now simply keeping
34- // the last few links in the map should be good enough. Likewise, we could
35- // add code to remove a target command from the map after the link is
36- // clicked, but assuming most links in hover sheets won't be clicked anyway
37- // this code won't change the overall memory use much.
38- setInterval (
39- function cleanupOlderCommandLinks ( ) {
40- // keys are returned in insertion order, we'll keep a few
41- // of recent keys available, and clean the rest
42- const keys = [ ...LINKED_COMMANDS . keys ( ) ] ;
43- const keysToRemove = keys . slice ( 0 , keys . length - 10 ) ;
44- for ( const key of keysToRemove ) {
45- LINKED_COMMANDS . delete ( key ) ;
46- }
47- } ,
48- 10 * 60 * 1000 ,
49- ) ;
50-
51- function renderCommand ( cmd : ra . CommandLink ) : string {
52- const commandId = randomUUID ( ) ;
53- LINKED_COMMANDS . set ( commandId , cmd ) ;
54- return `[${ cmd . title } ](command:rust-analyzer.linkToCommand?${ encodeURIComponent (
55- JSON . stringify ( [ commandId ] ) ,
56- ) } '${ cmd . tooltip } ')`;
57- }
58-
59- function renderHoverActions ( actions : ra . CommandLinkGroup [ ] ) : vscode . MarkdownString {
60- const text = actions
61- . map (
62- ( group ) =>
63- ( group . title ? group . title + " " : "" ) +
64- group . commands . map ( renderCommand ) . join ( " | " ) ,
65- )
66- . join ( " | " ) ;
67-
68- const result = new vscode . MarkdownString ( text ) ;
69- result . isTrusted = true ;
70- return result ;
71- }
72-
7313export async function createClient (
7414 traceOutputChannel : vscode . OutputChannel ,
7515 outputChannel : vscode . OutputChannel ,
@@ -450,3 +390,32 @@ function isCodeActionWithoutEditsAndCommands(value: any): boolean {
450390 candidate . command === void 0
451391 ) ;
452392}
393+
394+ // Command URIs have a form of command:command-name?arguments, where
395+ // arguments is a percent-encoded array of data we want to pass along to
396+ // the command function. For "Show References" this is a list of all file
397+ // URIs with locations of every reference, and it can get quite long.
398+ // So long in fact that it will fail rendering inside an `a` tag so we need
399+ // to proxy around that. We store the last hover's reference command link
400+ // here, as only one hover can be active at a time, and we don't need to
401+ // keep a history of these.
402+ export let HOVER_REFERENCE_COMMAND : ra . CommandLink | undefined = undefined ;
403+
404+ function renderCommand ( cmd : ra . CommandLink ) : string {
405+ HOVER_REFERENCE_COMMAND = cmd ;
406+ return `[${ cmd . title } ](command:rust-analyzer.hoverRefCommandProxy '${ cmd . tooltip } ')` ;
407+ }
408+
409+ function renderHoverActions ( actions : ra . CommandLinkGroup [ ] ) : vscode . MarkdownString {
410+ const text = actions
411+ . map (
412+ ( group ) =>
413+ ( group . title ? group . title + " " : "" ) +
414+ group . commands . map ( renderCommand ) . join ( " | " ) ,
415+ )
416+ . join ( " | " ) ;
417+
418+ const result = new vscode . MarkdownString ( text ) ;
419+ result . isTrusted = true ;
420+ return result ;
421+ }
0 commit comments