use lsp_types::{
self, CreateFile, DiagnosticSeverity, DocumentChangeOperation, DocumentChanges, Documentation,
- Location, LocationLink, MarkupContent, MarkupKind, Position, Range, RenameFile, ResourceOp,
- SemanticTokenModifier, SemanticTokenType, SymbolKind, TextDocumentEdit, TextDocumentIdentifier,
- TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier,
- WorkspaceEdit,
+ Location, LocationLink, MarkupContent, MarkupKind, ParameterInformation, ParameterLabel,
+ Position, Range, RenameFile, ResourceOp, SemanticTokenModifier, SemanticTokenType,
+ SignatureInformation, SymbolKind, TextDocumentEdit, TextDocumentIdentifier, TextDocumentItem,
+ TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, WorkspaceEdit,
};
use ra_ide::{
translate_offset_with_edit, CompletionItem, CompletionItemKind, FileId, FilePosition,
FileRange, FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag,
- InsertTextFormat, LineCol, LineIndex, NavigationTarget, RangeInfo, ReferenceAccess, Severity,
- SourceChange, SourceFileEdit,
+ InlayHint, InlayKind, InsertTextFormat, LineCol, LineIndex, NavigationTarget, RangeInfo,
+ ReferenceAccess, Severity, SourceChange, SourceFileEdit,
};
-use ra_syntax::{SyntaxKind, TextRange, TextUnit};
+use ra_syntax::{SyntaxKind, TextRange, TextSize};
use ra_text_edit::{AtomTextEdit, TextEdit};
use ra_vfs::LineEndings;
use crate::{
req,
- semantic_tokens::{self, ModifierSet, CONSTANT, CONTROL, MUTABLE, UNSAFE},
+ semantic_tokens::{self, ModifierSet, CONSTANT, CONTROL_FLOW, MUTABLE, UNSAFE},
world::WorldSnapshot,
Result,
};
-use semantic_tokens::{ATTRIBUTE, BUILTIN_TYPE, ENUM_MEMBER, LIFETIME, TYPE_ALIAS, UNION};
+use semantic_tokens::{
+ ATTRIBUTE, BUILTIN_TYPE, ENUM_MEMBER, FORMAT_SPECIFIER, LIFETIME, TYPE_ALIAS, UNION,
+ UNRESOLVED_REFERENCE,
+};
pub trait Conv {
type Output;
CompletionItemKind::Method => Method,
CompletionItemKind::TypeParam => TypeParameter,
CompletionItemKind::Macro => Method,
+ CompletionItemKind::Attribute => EnumMember,
}
}
}
// LSP does not allow arbitrary edits in completion, so we have to do a
// non-trivial mapping here.
for atom_edit in self.text_edit().as_atoms() {
- if self.source_range().is_subrange(&atom_edit.delete) {
+ if atom_edit.delete.contains_range(self.source_range()) {
text_edit = Some(if atom_edit.delete == self.source_range() {
- atom_edit.conv_with(ctx)
+ atom_edit.conv_with((ctx.0, ctx.1))
} else {
assert!(self.source_range().end() == atom_edit.delete.end());
let range1 =
- TextRange::from_to(atom_edit.delete.start(), self.source_range().start());
+ TextRange::new(atom_edit.delete.start(), self.source_range().start());
let range2 = self.source_range();
let edit1 = AtomTextEdit::replace(range1, String::new());
let edit2 = AtomTextEdit::replace(range2, atom_edit.insert.clone());
- additional_text_edits.push(edit1.conv_with(ctx));
- edit2.conv_with(ctx)
+ additional_text_edits.push(edit1.conv_with((ctx.0, ctx.1)));
+ edit2.conv_with((ctx.0, ctx.1))
})
} else {
- assert!(self.source_range().intersection(&atom_edit.delete).is_none());
- additional_text_edits.push(atom_edit.conv_with(ctx));
+ assert!(self.source_range().intersect(atom_edit.delete).is_none());
+ additional_text_edits.push(atom_edit.conv_with((ctx.0, ctx.1)));
}
}
let text_edit = text_edit.unwrap();
detail: self.detail().map(|it| it.to_string()),
filter_text: Some(self.lookup().to_string()),
kind: self.kind().map(|it| it.conv()),
- text_edit: Some(text_edit),
+ text_edit: Some(text_edit.into()),
additional_text_edits: Some(additional_text_edits),
documentation: self.documentation().map(|it| it.conv()),
deprecated: Some(self.deprecated()),
+ command: if self.trigger_call_info() {
+ let cmd = lsp_types::Command {
+ title: "triggerParameterHints".into(),
+ command: "editor.action.triggerParameterHints".into(),
+ arguments: None,
+ };
+ Some(cmd)
+ } else {
+ None
+ },
..Default::default()
};
+ if self.score().is_some() {
+ res.preselect = Some(true)
+ }
+
if self.deprecated() {
res.tags = Some(vec![lsp_types::CompletionItemTag::Deprecated])
}
}
impl ConvWith<&LineIndex> for Position {
- type Output = TextUnit;
+ type Output = TextSize;
- fn conv_with(self, line_index: &LineIndex) -> TextUnit {
+ fn conv_with(self, line_index: &LineIndex) -> TextSize {
let line_col = LineCol { line: self.line as u32, col_utf16: self.character as u32 };
line_index.offset(line_col)
}
}
-impl ConvWith<&LineIndex> for TextUnit {
+impl ConvWith<&LineIndex> for TextSize {
type Output = Position;
fn conv_with(self, line_index: &LineIndex) -> Position {
type Output = TextRange;
fn conv_with(self, line_index: &LineIndex) -> TextRange {
- TextRange::from_to(self.start.conv_with(line_index), self.end.conv_with(line_index))
+ TextRange::new(self.start.conv_with(line_index), self.end.conv_with(line_index))
}
}
}
}
-impl Conv for ra_ide::FunctionSignature {
+impl ConvWith<bool> for ra_ide::FunctionSignature {
type Output = lsp_types::SignatureInformation;
- fn conv(self) -> Self::Output {
- use lsp_types::{ParameterInformation, ParameterLabel, SignatureInformation};
-
- let label = self.to_string();
-
- let documentation = self.doc.map(|it| it.conv());
+ fn conv_with(self, concise: bool) -> Self::Output {
+ let (label, documentation, params) = if concise {
+ let mut params = self.parameters;
+ if self.has_self_param {
+ params.remove(0);
+ }
+ (params.join(", "), None, params)
+ } else {
+ (self.to_string(), self.doc.map(|it| it.conv()), self.parameters)
+ };
- let parameters: Vec<ParameterInformation> = self
- .parameters
+ let parameters: Vec<ParameterInformation> = params
.into_iter()
.map(|param| ParameterInformation {
label: ParameterLabel::Simple(param),
// range.end.line from the folding region if there is more text after range.end
// on the same line.
let has_more_text_on_end_line = ctx.text
- [TextRange::from_to(self.range.end(), TextUnit::of_str(ctx.text))]
+ [TextRange::new(self.range.end(), TextSize::of(ctx.text))]
.chars()
.take_while(|it| *it != '\n')
.any(|it| !it.is_whitespace());
}
}
+impl ConvWith<&LineIndex> for InlayHint {
+ type Output = req::InlayHint;
+ fn conv_with(self, line_index: &LineIndex) -> Self::Output {
+ req::InlayHint {
+ label: self.label.to_string(),
+ range: self.range.conv_with(line_index),
+ kind: match self.kind {
+ InlayKind::ParameterHint => req::InlayKind::ParameterHint,
+ InlayKind::TypeHint => req::InlayKind::TypeHint,
+ InlayKind::ChainingHint => req::InlayKind::ChainingHint,
+ },
+ }
+ }
+}
+
impl Conv for Highlight {
type Output = (u32, u32);
HighlightTag::Comment => SemanticTokenType::COMMENT,
HighlightTag::Attribute => ATTRIBUTE,
HighlightTag::Keyword => SemanticTokenType::KEYWORD,
+ HighlightTag::UnresolvedReference => UNRESOLVED_REFERENCE,
+ HighlightTag::FormatSpecifier => FORMAT_SPECIFIER,
};
for modifier in self.modifiers.iter() {
let modifier = match modifier {
HighlightModifier::Definition => SemanticTokenModifier::DECLARATION,
- HighlightModifier::Control => CONTROL,
+ HighlightModifier::ControlFlow => CONTROL_FLOW,
HighlightModifier::Mutable => MUTABLE,
HighlightModifier::Unsafe => UNSAFE,
};
.into_iter()
.map(|nav| (file_id, RangeInfo::new(range, nav)))
.try_conv_with_to_vec(world)?;
- if world.options.supports_location_link {
+ if world.config.client_caps.location_link {
Ok(links.into())
} else {
let locations: Vec<Location> = links