mirror of
https://github.com/oxalica/nil.git
synced 2025-10-06 00:32:51 +02:00
save
This commit is contained in:
54
crates/ide/src/ide/inlay_hints.rs
Normal file
54
crates/ide/src/ide/inlay_hints.rs
Normal file
@@ -0,0 +1,54 @@
|
||||
use syntax::TextSize;
|
||||
|
||||
use crate::def::{Expr, ResolveResult};
|
||||
use crate::{DefDatabase, FileRange};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct InlayHint {
|
||||
pub pos: TextSize,
|
||||
pub kind: InlayKind,
|
||||
pub label: String,
|
||||
pub tooltip: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum InlayKind {
|
||||
WithHint,
|
||||
}
|
||||
|
||||
pub(crate) fn inlay_hints(
|
||||
db: &dyn DefDatabase,
|
||||
FileRange { file_id, range }: FileRange,
|
||||
) -> Vec<InlayHint> {
|
||||
let src = db.file_content(file_id);
|
||||
let module = db.module(file_id);
|
||||
let source_map = db.source_map(file_id);
|
||||
let nameres = db.name_resolution(file_id);
|
||||
nameres
|
||||
.iter()
|
||||
.filter_map(|(expr, res)| {
|
||||
let ResolveResult::WithExprs(withs) = res else {
|
||||
return None;
|
||||
};
|
||||
let ident_range = source_map.node_for_expr(expr)?.text_range();
|
||||
ident_range.intersect(range)?;
|
||||
|
||||
let label = "^".repeat(withs.len());
|
||||
let tooltip = withs
|
||||
.iter()
|
||||
.rev()
|
||||
.filter_map(|&with_expr| {
|
||||
let Expr::With(env_expr, _) = module[with_expr] else { unreachable!() };
|
||||
let range = source_map.node_for_expr(env_expr)?.text_range();
|
||||
Some(format!("with {};\n", &src[range]))
|
||||
})
|
||||
.collect::<String>();
|
||||
Some(InlayHint {
|
||||
pos: ident_range.start(),
|
||||
kind: InlayKind::WithHint,
|
||||
label,
|
||||
tooltip: format!("```\n{tooltip}\n```"),
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
@@ -5,6 +5,7 @@ mod expand_selection;
|
||||
mod goto_definition;
|
||||
mod highlight_related;
|
||||
mod hover;
|
||||
mod inlay_hints;
|
||||
mod links;
|
||||
mod references;
|
||||
mod rename;
|
||||
@@ -25,6 +26,7 @@ pub use completion::{CompletionItem, CompletionItemKind};
|
||||
pub use goto_definition::GotoDefinitionResult;
|
||||
pub use highlight_related::HlRelated;
|
||||
pub use hover::HoverResult;
|
||||
pub use inlay_hints::{InlayHint, InlayKind};
|
||||
pub use links::{Link, LinkTarget};
|
||||
pub use rename::RenameResult;
|
||||
pub use symbol_hierarchy::SymbolTree;
|
||||
@@ -165,4 +167,8 @@ impl Analysis {
|
||||
pub fn highlight_related(&self, fpos: FilePos) -> Cancellable<Vec<HlRelated>> {
|
||||
self.with_db(|db| highlight_related::highlight_related(db, fpos).unwrap_or_default())
|
||||
}
|
||||
|
||||
pub fn inlay_hints(&self, frange: FileRange) -> Cancellable<Vec<InlayHint>> {
|
||||
self.with_db(|db| inlay_hints::inlay_hints(db, frange))
|
||||
}
|
||||
}
|
||||
|
@@ -11,7 +11,8 @@ mod tests;
|
||||
pub use self::ide::{
|
||||
Analysis, AnalysisHost, Assist, AssistKind, Cancelled, CompletionItem, CompletionItemKind,
|
||||
GotoDefinitionResult, HlKeyword, HlOperator, HlPunct, HlRange, HlRelated, HlTag, HoverResult,
|
||||
Link, LinkTarget, NavigationTarget, RenameResult, RootDatabase, SymbolTree,
|
||||
InlayHint, InlayKind, Link, LinkTarget, NavigationTarget, RenameResult, RootDatabase,
|
||||
SymbolTree,
|
||||
};
|
||||
pub use base::{
|
||||
Change, FileId, FilePos, FileRange, FileSet, InFile, SourceDatabase, SourceRoot, SourceRootId,
|
||||
|
@@ -11,7 +11,7 @@ ide = { path = "../ide" }
|
||||
indexmap = "1.9.1"
|
||||
log = "0.4.17"
|
||||
lsp-server = "0.6.0"
|
||||
lsp-types = "0.93.0"
|
||||
lsp-types = { version = "0.93.0", features = ["proposed"] }
|
||||
serde = "1.0.140"
|
||||
serde_json = "1.0.82"
|
||||
text-size = "1.1.0"
|
||||
|
@@ -49,6 +49,7 @@ pub(crate) fn server_capabilities() -> ServerCapabilities {
|
||||
}),
|
||||
code_action_provider: Some(CodeActionProviderCapability::Simple(true)),
|
||||
document_highlight_provider: Some(OneOf::Left(true)),
|
||||
inlay_hint_provider: Some(OneOf::Left(true)),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +1,10 @@
|
||||
use crate::{semantic_tokens, LineMap, LspError, Result, Vfs};
|
||||
use ide::{
|
||||
Assist, AssistKind, CompletionItem, CompletionItemKind, Diagnostic, FileId, FilePos, FileRange,
|
||||
HlRange, HlRelated, HoverResult, NameKind, Severity, SymbolTree, TextEdit, WorkspaceEdit,
|
||||
HlRange, HlRelated, HoverResult, InlayHint, InlayKind, NameKind, Severity, SymbolTree,
|
||||
TextEdit, WorkspaceEdit,
|
||||
};
|
||||
use lsp::{InlayHintLabel, InlayHintTooltip};
|
||||
use lsp_server::ErrorCode;
|
||||
use lsp_types::{
|
||||
self as lsp, CodeAction, CodeActionKind, CodeActionOrCommand, DiagnosticRelatedInformation,
|
||||
@@ -50,10 +52,15 @@ pub(crate) fn to_location(vfs: &Vfs, frange: FileRange) -> Location {
|
||||
Location::new(uri, to_range(&line_map, frange.range))
|
||||
}
|
||||
|
||||
pub(crate) fn to_pos(line_map: &LineMap, pos: TextSize) -> Position {
|
||||
let (line, col) = line_map.line_col_for_pos(pos);
|
||||
Position::new(line, col)
|
||||
}
|
||||
|
||||
pub(crate) fn to_range(line_map: &LineMap, range: TextRange) -> Range {
|
||||
let (line1, col1) = line_map.line_col_for_pos(range.start());
|
||||
let (line2, col2) = line_map.line_col_for_pos(range.end());
|
||||
Range::new(Position::new(line1, col1), Position::new(line2, col2))
|
||||
let start = to_pos(line_map, range.start());
|
||||
let end = to_pos(line_map, range.end());
|
||||
Range::new(start, end)
|
||||
}
|
||||
|
||||
pub(crate) fn to_diagnostics(
|
||||
@@ -166,6 +173,7 @@ pub(crate) fn to_completion_item(line_map: &LineMap, item: CompletionItem) -> ls
|
||||
commit_characters: None,
|
||||
data: None,
|
||||
tags: None,
|
||||
label_details: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,3 +341,21 @@ pub(crate) fn to_document_highlight(
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub(crate) fn to_inlay_hint(line_map: &LineMap, hint: InlayHint) -> lsp::InlayHint {
|
||||
lsp::InlayHint {
|
||||
position: to_pos(line_map, hint.pos),
|
||||
label: InlayHintLabel::String(hint.label),
|
||||
kind: match hint.kind {
|
||||
InlayKind::WithHint => None,
|
||||
},
|
||||
text_edits: None,
|
||||
tooltip: Some(InlayHintTooltip::MarkupContent(MarkupContent {
|
||||
kind: MarkupKind::Markdown,
|
||||
value: hint.tooltip,
|
||||
})),
|
||||
padding_left: None,
|
||||
padding_right: None,
|
||||
data: None,
|
||||
}
|
||||
}
|
||||
|
@@ -4,10 +4,11 @@ use lsp_types::{
|
||||
CodeActionParams, CodeActionResponse, CompletionParams, CompletionResponse, Diagnostic,
|
||||
DocumentFormattingParams, DocumentHighlight, DocumentHighlightParams, DocumentLink,
|
||||
DocumentLinkParams, DocumentSymbolParams, DocumentSymbolResponse, GotoDefinitionParams,
|
||||
GotoDefinitionResponse, Hover, HoverParams, Location, Position, PrepareRenameResponse, Range,
|
||||
ReferenceParams, RenameParams, SelectionRange, SelectionRangeParams, SemanticTokens,
|
||||
SemanticTokensParams, SemanticTokensRangeParams, SemanticTokensRangeResult,
|
||||
SemanticTokensResult, TextDocumentPositionParams, TextEdit, Url, WorkspaceEdit,
|
||||
GotoDefinitionResponse, Hover, HoverParams, InlayHint, InlayHintParams, Location, Position,
|
||||
PrepareRenameResponse, Range, ReferenceParams, RenameParams, SelectionRange,
|
||||
SelectionRangeParams, SemanticTokens, SemanticTokensParams, SemanticTokensRangeParams,
|
||||
SemanticTokensRangeResult, SemanticTokensResult, TextDocumentPositionParams, TextEdit, Url,
|
||||
WorkspaceEdit,
|
||||
};
|
||||
use std::path::Path;
|
||||
use std::process;
|
||||
@@ -328,3 +329,17 @@ pub(crate) fn document_highlight(
|
||||
let ret = convert::to_document_highlight(&line_map, &ret);
|
||||
Ok(Some(ret))
|
||||
}
|
||||
|
||||
pub(crate) fn inlay_hints(
|
||||
snap: StateSnapshot,
|
||||
params: InlayHintParams,
|
||||
) -> Result<Option<Vec<InlayHint>>> {
|
||||
let (file, line_map) = convert::from_file(&snap.vfs(), ¶ms.text_document)?;
|
||||
let (_, range) = convert::from_range(&snap.vfs(), file, params.range)?;
|
||||
let hints = snap.analysis.inlay_hints(FileRange::new(file, range))?;
|
||||
let hints = hints
|
||||
.into_iter()
|
||||
.map(|hint| convert::to_inlay_hint(&line_map, hint))
|
||||
.collect();
|
||||
Ok(Some(hints))
|
||||
}
|
||||
|
@@ -227,6 +227,7 @@ impl Server {
|
||||
.on::<req::DocumentLinkRequest>(handler::document_links)
|
||||
.on::<req::CodeActionRequest>(handler::code_action)
|
||||
.on::<req::DocumentHighlightRequest>(handler::document_highlight)
|
||||
.on::<req::InlayHintRequest>(handler::inlay_hints)
|
||||
.finish();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user