mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-03 13:23:25 +00:00
feat: Completed the client side implementation of rust-analyzer/hoverRange
This commit is contained in:
parent
8ca3bb8fcd
commit
18644720eb
7 changed files with 129 additions and 30 deletions
|
|
@ -867,28 +867,40 @@ pub(crate) fn handle_signature_help(
|
||||||
|
|
||||||
pub(crate) fn handle_hover(
|
pub(crate) fn handle_hover(
|
||||||
snap: GlobalStateSnapshot,
|
snap: GlobalStateSnapshot,
|
||||||
params: lsp_ext::HoverParams,
|
params: lsp_types::HoverParams,
|
||||||
) -> Result<Option<lsp_ext::Hover>> {
|
) -> Result<Option<lsp_ext::Hover>> {
|
||||||
let _p = profile::span("handle_hover");
|
let _p = profile::span("handle_hover");
|
||||||
|
let position = from_proto::file_position(&snap, params.text_document_position_params)?;
|
||||||
|
let info = match snap.analysis.hover(&snap.config.hover(), position)? {
|
||||||
|
None => return Ok(None),
|
||||||
|
Some(info) => info,
|
||||||
|
};
|
||||||
|
|
||||||
|
let line_index = snap.file_line_index(position.file_id)?;
|
||||||
|
let range = to_proto::range(&line_index, info.range);
|
||||||
|
let hover = lsp_ext::Hover {
|
||||||
|
hover: lsp_types::Hover {
|
||||||
|
contents: HoverContents::Markup(to_proto::markup_content(info.info.markup)),
|
||||||
|
range: Some(range),
|
||||||
|
},
|
||||||
|
actions: prepare_hover_actions(&snap, &info.info.actions),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Some(hover))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn handle_hover_range(
|
||||||
|
snap: GlobalStateSnapshot,
|
||||||
|
params: lsp_ext::HoverRangeParams,
|
||||||
|
) -> Result<Option<lsp_ext::Hover>> {
|
||||||
|
let _p = profile::span("handle_hover_range");
|
||||||
let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?;
|
let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?;
|
||||||
let range = from_proto::file_range(&snap, params.text_document, params.range)?;
|
let range = from_proto::file_range(&snap, params.text_document, params.range)?;
|
||||||
|
|
||||||
let info = if range.range.is_empty() {
|
|
||||||
// It's a hover over a position
|
|
||||||
match snap
|
|
||||||
.analysis
|
|
||||||
.hover(&snap.config.hover(), FilePosition { file_id, offset: range.range.start() })?
|
|
||||||
{
|
|
||||||
None => return Ok(None),
|
|
||||||
Some(info) => info,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// It's a hover over a range
|
|
||||||
log::info!("Triggered range hover");
|
log::info!("Triggered range hover");
|
||||||
match snap.analysis.hover_range(&snap.config.hover(), range)? {
|
let info = match snap.analysis.hover_range(&snap.config.hover(), range)? {
|
||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
Some(info) => info,
|
Some(info) => info,
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let line_index = snap.file_line_index(range.file_id)?;
|
let line_index = snap.file_line_index(range.file_id)?;
|
||||||
|
|
|
||||||
|
|
@ -376,14 +376,22 @@ pub struct SnippetTextEdit {
|
||||||
pub enum HoverRequest {}
|
pub enum HoverRequest {}
|
||||||
|
|
||||||
impl Request for HoverRequest {
|
impl Request for HoverRequest {
|
||||||
type Params = HoverParams;
|
type Params = lsp_types::HoverParams;
|
||||||
type Result = Option<Hover>;
|
type Result = Option<Hover>;
|
||||||
const METHOD: &'static str = "textDocument/hover";
|
const METHOD: &'static str = "textDocument/hover";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum HoverRangeRequest {}
|
||||||
|
|
||||||
|
impl Request for HoverRangeRequest {
|
||||||
|
type Params = HoverRangeParams;
|
||||||
|
type Result = Option<Hover>;
|
||||||
|
const METHOD: &'static str = "rust-analyzer/hoverRange";
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug)]
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct HoverParams {
|
pub struct HoverRangeParams {
|
||||||
pub text_document: TextDocumentIdentifier,
|
pub text_document: TextDocumentIdentifier,
|
||||||
pub range: Range,
|
pub range: Range,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -542,6 +542,7 @@ impl GlobalState {
|
||||||
.on::<lsp_ext::CodeActionRequest>(handlers::handle_code_action)
|
.on::<lsp_ext::CodeActionRequest>(handlers::handle_code_action)
|
||||||
.on::<lsp_ext::CodeActionResolveRequest>(handlers::handle_code_action_resolve)
|
.on::<lsp_ext::CodeActionResolveRequest>(handlers::handle_code_action_resolve)
|
||||||
.on::<lsp_ext::HoverRequest>(handlers::handle_hover)
|
.on::<lsp_ext::HoverRequest>(handlers::handle_hover)
|
||||||
|
.on::<lsp_ext::HoverRangeRequest>(handlers::handle_hover_range)
|
||||||
.on::<lsp_ext::ExternalDocs>(handlers::handle_open_docs)
|
.on::<lsp_ext::ExternalDocs>(handlers::handle_open_docs)
|
||||||
.on::<lsp_ext::OpenCargoToml>(handlers::handle_open_cargo_toml)
|
.on::<lsp_ext::OpenCargoToml>(handlers::handle_open_cargo_toml)
|
||||||
.on::<lsp_ext::MoveItem>(handlers::handle_move_item)
|
.on::<lsp_ext::MoveItem>(handlers::handle_move_item)
|
||||||
|
|
|
||||||
|
|
@ -56,9 +56,49 @@ export function createClient(serverPath: string, workspace: Workspace, extraEnv:
|
||||||
traceOutputChannel,
|
traceOutputChannel,
|
||||||
middleware: {
|
middleware: {
|
||||||
async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, _next: lc.ProvideHoverSignature) {
|
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(
|
const editor = vscode.window.activeTextEditor;
|
||||||
|
const selection = editor?.selection;
|
||||||
|
return selection?.contains(position)
|
||||||
|
? client
|
||||||
|
.sendRequest(
|
||||||
|
ra.hoverRange,
|
||||||
|
{
|
||||||
|
textDocument:
|
||||||
|
client.code2ProtocolConverter.asTextDocumentIdentifier(
|
||||||
|
document
|
||||||
|
),
|
||||||
|
range: client.code2ProtocolConverter.asRange(
|
||||||
|
editor?.selection
|
||||||
|
),
|
||||||
|
},
|
||||||
|
token
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
(result) =>
|
||||||
|
client.protocol2CodeConverter.asHover(result),
|
||||||
|
(error) => {
|
||||||
|
client.handleFailedRequest(
|
||||||
|
lc.HoverRequest.type,
|
||||||
|
undefined,
|
||||||
|
error,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
return Promise.resolve(null);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
: client
|
||||||
|
.sendRequest(
|
||||||
|
lc.HoverRequest.type,
|
||||||
|
client.code2ProtocolConverter.asTextDocumentPositionParams(
|
||||||
|
document,
|
||||||
|
position
|
||||||
|
),
|
||||||
|
token
|
||||||
|
)
|
||||||
|
.then(
|
||||||
(result) => {
|
(result) => {
|
||||||
const hover = client.protocol2CodeConverter.asHover(result);
|
const hover =
|
||||||
|
client.protocol2CodeConverter.asHover(result);
|
||||||
if (hover) {
|
if (hover) {
|
||||||
const actions = (<any>result).actions;
|
const actions = (<any>result).actions;
|
||||||
if (actions) {
|
if (actions) {
|
||||||
|
|
@ -68,9 +108,15 @@ export function createClient(serverPath: string, workspace: Workspace, extraEnv:
|
||||||
return hover;
|
return hover;
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
client.handleFailedRequest(lc.HoverRequest.type, token, error, null);
|
client.handleFailedRequest(
|
||||||
|
lc.HoverRequest.type,
|
||||||
|
token,
|
||||||
|
error,
|
||||||
|
null
|
||||||
|
);
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
},
|
},
|
||||||
// Using custom handling of CodeActions to support action groups and snippet edits.
|
// Using custom handling of CodeActions to support action groups and snippet edits.
|
||||||
// Note that this means we have to re-implement lazy edit resolving ourselves as well.
|
// Note that this means we have to re-implement lazy edit resolving ourselves as well.
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,30 @@ export function matchingBrace(ctx: Ctx): Cmd {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function hoverRange(ctx: Ctx): Cmd {
|
||||||
|
return async () => {
|
||||||
|
const editor = ctx.activeRustEditor;
|
||||||
|
const client = ctx.client;
|
||||||
|
if (!editor || !client) return;
|
||||||
|
|
||||||
|
client
|
||||||
|
.sendRequest(ra.hoverRange, {
|
||||||
|
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(
|
||||||
|
editor.document
|
||||||
|
),
|
||||||
|
range: client.code2ProtocolConverter.asRange(editor.selection),
|
||||||
|
})
|
||||||
|
.then(
|
||||||
|
(result) => client.protocol2CodeConverter.asHover(result),
|
||||||
|
(error) => {
|
||||||
|
client.handleFailedRequest(lc.HoverRequest.type, undefined, error, null);
|
||||||
|
return Promise.resolve(null);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export function joinLines(ctx: Ctx): Cmd {
|
export function joinLines(ctx: Ctx): Cmd {
|
||||||
return async () => {
|
return async () => {
|
||||||
const editor = ctx.activeRustEditor;
|
const editor = ctx.activeRustEditor;
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,13 @@ export const serverStatus = new lc.NotificationType<ServerStatusParams>("experim
|
||||||
|
|
||||||
export const reloadWorkspace = new lc.RequestType0<null, void>("rust-analyzer/reloadWorkspace");
|
export const reloadWorkspace = new lc.RequestType0<null, void>("rust-analyzer/reloadWorkspace");
|
||||||
|
|
||||||
|
export const hoverRange = new lc.RequestType<HoverRangeParams, lc.Hover | null, void>("rust-analyzer/hoverRange");
|
||||||
|
|
||||||
|
export interface HoverRangeParams {
|
||||||
|
textDocument: lc.TextDocumentIdentifier;
|
||||||
|
range: lc.Range;
|
||||||
|
}
|
||||||
|
|
||||||
export interface SyntaxTreeParams {
|
export interface SyntaxTreeParams {
|
||||||
textDocument: lc.TextDocumentIdentifier;
|
textDocument: lc.TextDocumentIdentifier;
|
||||||
range: lc.Range | null;
|
range: lc.Range | null;
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,7 @@ async function initCommonContext(context: vscode.ExtensionContext, ctx: Ctx) {
|
||||||
ctx.registerCommand('reloadWorkspace', commands.reloadWorkspace);
|
ctx.registerCommand('reloadWorkspace', commands.reloadWorkspace);
|
||||||
ctx.registerCommand('matchingBrace', commands.matchingBrace);
|
ctx.registerCommand('matchingBrace', commands.matchingBrace);
|
||||||
ctx.registerCommand('joinLines', commands.joinLines);
|
ctx.registerCommand('joinLines', commands.joinLines);
|
||||||
|
ctx.registerCommand('hoverRange', commands.hoverRange);
|
||||||
ctx.registerCommand('parentModule', commands.parentModule);
|
ctx.registerCommand('parentModule', commands.parentModule);
|
||||||
ctx.registerCommand('syntaxTree', commands.syntaxTree);
|
ctx.registerCommand('syntaxTree', commands.syntaxTree);
|
||||||
ctx.registerCommand('viewHir', commands.viewHir);
|
ctx.registerCommand('viewHir', commands.viewHir);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue