Skip to content

Commit 1864472

Browse files
committed
feat: Completed the client side implementation of rust-analyzer/hoverRange
1 parent 8ca3bb8 commit 1864472

File tree

7 files changed

+129
-30
lines changed

7 files changed

+129
-30
lines changed

crates/rust-analyzer/src/handlers.rs

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -867,28 +867,40 @@ pub(crate) fn handle_signature_help(
867867

868868
pub(crate) fn handle_hover(
869869
snap: GlobalStateSnapshot,
870-
params: lsp_ext::HoverParams,
870+
params: lsp_types::HoverParams,
871871
) -> Result<Option<lsp_ext::Hover>> {
872872
let _p = profile::span("handle_hover");
873+
let position = from_proto::file_position(&snap, params.text_document_position_params)?;
874+
let info = match snap.analysis.hover(&snap.config.hover(), position)? {
875+
None => return Ok(None),
876+
Some(info) => info,
877+
};
878+
879+
let line_index = snap.file_line_index(position.file_id)?;
880+
let range = to_proto::range(&line_index, info.range);
881+
let hover = lsp_ext::Hover {
882+
hover: lsp_types::Hover {
883+
contents: HoverContents::Markup(to_proto::markup_content(info.info.markup)),
884+
range: Some(range),
885+
},
886+
actions: prepare_hover_actions(&snap, &info.info.actions),
887+
};
888+
889+
Ok(Some(hover))
890+
}
891+
892+
pub(crate) fn handle_hover_range(
893+
snap: GlobalStateSnapshot,
894+
params: lsp_ext::HoverRangeParams,
895+
) -> Result<Option<lsp_ext::Hover>> {
896+
let _p = profile::span("handle_hover_range");
873897
let file_id = from_proto::file_id(&snap, &params.text_document.uri)?;
874898
let range = from_proto::file_range(&snap, params.text_document, params.range)?;
875899

876-
let info = if range.range.is_empty() {
877-
// It's a hover over a position
878-
match snap
879-
.analysis
880-
.hover(&snap.config.hover(), FilePosition { file_id, offset: range.range.start() })?
881-
{
882-
None => return Ok(None),
883-
Some(info) => info,
884-
}
885-
} else {
886-
// It's a hover over a range
887-
log::info!("Triggered range hover");
888-
match snap.analysis.hover_range(&snap.config.hover(), range)? {
889-
None => return Ok(None),
890-
Some(info) => info,
891-
}
900+
log::info!("Triggered range hover");
901+
let info = match snap.analysis.hover_range(&snap.config.hover(), range)? {
902+
None => return Ok(None),
903+
Some(info) => info,
892904
};
893905

894906
let line_index = snap.file_line_index(range.file_id)?;

crates/rust-analyzer/src/lsp_ext.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,14 +376,22 @@ pub struct SnippetTextEdit {
376376
pub enum HoverRequest {}
377377

378378
impl Request for HoverRequest {
379-
type Params = HoverParams;
379+
type Params = lsp_types::HoverParams;
380380
type Result = Option<Hover>;
381381
const METHOD: &'static str = "textDocument/hover";
382382
}
383383

384+
pub enum HoverRangeRequest {}
385+
386+
impl Request for HoverRangeRequest {
387+
type Params = HoverRangeParams;
388+
type Result = Option<Hover>;
389+
const METHOD: &'static str = "rust-analyzer/hoverRange";
390+
}
391+
384392
#[derive(Deserialize, Serialize, Debug)]
385393
#[serde(rename_all = "camelCase")]
386-
pub struct HoverParams {
394+
pub struct HoverRangeParams {
387395
pub text_document: TextDocumentIdentifier,
388396
pub range: Range,
389397
}

crates/rust-analyzer/src/main_loop.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,7 @@ impl GlobalState {
542542
.on::<lsp_ext::CodeActionRequest>(handlers::handle_code_action)
543543
.on::<lsp_ext::CodeActionResolveRequest>(handlers::handle_code_action_resolve)
544544
.on::<lsp_ext::HoverRequest>(handlers::handle_hover)
545+
.on::<lsp_ext::HoverRangeRequest>(handlers::handle_hover_range)
545546
.on::<lsp_ext::ExternalDocs>(handlers::handle_open_docs)
546547
.on::<lsp_ext::OpenCargoToml>(handlers::handle_open_cargo_toml)
547548
.on::<lsp_ext::MoveItem>(handlers::handle_move_item)

editors/code/src/client.ts

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,21 +56,67 @@ export function createClient(serverPath: string, workspace: Workspace, extraEnv:
5656
traceOutputChannel,
5757
middleware: {
5858
async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, _next: lc.ProvideHoverSignature) {
59-
return client.sendRequest(lc.HoverRequest.type, client.code2ProtocolConverter.asTextDocumentPositionParams(document, position), token).then(
60-
(result) => {
61-
const hover = client.protocol2CodeConverter.asHover(result);
62-
if (hover) {
59+
const editor = vscode.window.activeTextEditor;
60+
const selection = editor?.selection;
61+
return selection?.contains(position)
62+
? client
63+
.sendRequest(
64+
ra.hoverRange,
65+
{
66+
textDocument:
67+
client.code2ProtocolConverter.asTextDocumentIdentifier(
68+
document
69+
),
70+
range: client.code2ProtocolConverter.asRange(
71+
editor?.selection
72+
),
73+
},
74+
token
75+
)
76+
.then(
77+
(result) =>
78+
client.protocol2CodeConverter.asHover(result),
79+
(error) => {
80+
client.handleFailedRequest(
81+
lc.HoverRequest.type,
82+
undefined,
83+
error,
84+
null
85+
);
86+
return Promise.resolve(null);
87+
}
88+
)
89+
: client
90+
.sendRequest(
91+
lc.HoverRequest.type,
92+
client.code2ProtocolConverter.asTextDocumentPositionParams(
93+
document,
94+
position
95+
),
96+
token
97+
)
98+
.then(
99+
(result) => {
100+
const hover =
101+
client.protocol2CodeConverter.asHover(result);
102+
if (hover) {
63103
const actions = (<any>result).actions;
64104
if (actions) {
65-
hover.contents.push(renderHoverActions(actions));
105+
hover.contents.push(renderHoverActions(actions));
66106
}
107+
}
108+
return hover;
109+
},
110+
(error) => {
111+
client.handleFailedRequest(
112+
lc.HoverRequest.type,
113+
token,
114+
error,
115+
null
116+
);
117+
return Promise.resolve(null);
67118
}
68-
return hover;
69-
},
70-
(error) => {
71-
client.handleFailedRequest(lc.HoverRequest.type, token, error, null);
72-
return Promise.resolve(null);
73-
});
119+
);
74120
},
75121
// Using custom handling of CodeActions to support action groups and snippet edits.
76122
// Note that this means we have to re-implement lazy edit resolving ourselves as well.

editors/code/src/commands.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,30 @@ export function matchingBrace(ctx: Ctx): Cmd {
116116
};
117117
}
118118

119+
export function hoverRange(ctx: Ctx): Cmd {
120+
return async () => {
121+
const editor = ctx.activeRustEditor;
122+
const client = ctx.client;
123+
if (!editor || !client) return;
124+
125+
client
126+
.sendRequest(ra.hoverRange, {
127+
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(
128+
editor.document
129+
),
130+
range: client.code2ProtocolConverter.asRange(editor.selection),
131+
})
132+
.then(
133+
(result) => client.protocol2CodeConverter.asHover(result),
134+
(error) => {
135+
client.handleFailedRequest(lc.HoverRequest.type, undefined, error, null);
136+
return Promise.resolve(null);
137+
}
138+
);
139+
};
140+
}
141+
142+
119143
export function joinLines(ctx: Ctx): Cmd {
120144
return async () => {
121145
const editor = ctx.activeRustEditor;

editors/code/src/lsp_ext.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ export const serverStatus = new lc.NotificationType<ServerStatusParams>("experim
1919

2020
export const reloadWorkspace = new lc.RequestType0<null, void>("rust-analyzer/reloadWorkspace");
2121

22+
export const hoverRange = new lc.RequestType<HoverRangeParams, lc.Hover | null, void>("rust-analyzer/hoverRange");
23+
24+
export interface HoverRangeParams {
25+
textDocument: lc.TextDocumentIdentifier;
26+
range: lc.Range;
27+
}
28+
2229
export interface SyntaxTreeParams {
2330
textDocument: lc.TextDocumentIdentifier;
2431
range: lc.Range | null;

editors/code/src/main.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ async function initCommonContext(context: vscode.ExtensionContext, ctx: Ctx) {
118118
ctx.registerCommand('reloadWorkspace', commands.reloadWorkspace);
119119
ctx.registerCommand('matchingBrace', commands.matchingBrace);
120120
ctx.registerCommand('joinLines', commands.joinLines);
121+
ctx.registerCommand('hoverRange', commands.hoverRange);
121122
ctx.registerCommand('parentModule', commands.parentModule);
122123
ctx.registerCommand('syntaxTree', commands.syntaxTree);
123124
ctx.registerCommand('viewHir', commands.viewHir);

0 commit comments

Comments
 (0)