make compleion item details private

This commit is contained in:
Aleksey Kladov 2018-12-21 15:19:46 +03:00
parent b5c5995bf1
commit 4092b8d0b5
5 changed files with 65 additions and 36 deletions

View File

@ -18,7 +18,7 @@ use crate::{
Cancelable, FilePosition Cancelable, FilePosition
}; };
pub use crate::completion::completion_item::CompletionItem; pub use crate::completion::completion_item::{CompletionItem, InsertText};
pub(crate) fn completions( pub(crate) fn completions(
db: &db::RootDatabase, db: &db::RootDatabase,
@ -109,13 +109,20 @@ mod tests {
use super::*; use super::*;
fn is_snippet(completion_item: &CompletionItem) -> bool {
match completion_item.insert_text() {
InsertText::Snippet { .. } => true,
_ => false,
}
}
fn check_scope_completion(code: &str, expected_completions: &str) { fn check_scope_completion(code: &str, expected_completions: &str) {
let (analysis, position) = single_file_with_position(code); let (analysis, position) = single_file_with_position(code);
let completions = completions(&analysis.imp.db, position) let completions = completions(&analysis.imp.db, position)
.unwrap() .unwrap()
.unwrap() .unwrap()
.into_iter() .into_iter()
.filter(|c| c.snippet.is_none()) .filter(|c| !is_snippet(c))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
assert_eq_dbg(expected_completions, &completions); assert_eq_dbg(expected_completions, &completions);
} }
@ -126,7 +133,7 @@ mod tests {
.unwrap() .unwrap()
.unwrap() .unwrap()
.into_iter() .into_iter()
.filter(|c| c.snippet.is_some()) .filter(is_snippet)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
assert_eq_dbg(expected_completions, &completions); assert_eq_dbg(expected_completions, &completions);
} }

View File

@ -1,11 +1,13 @@
#[derive(Debug)] #[derive(Debug)]
pub struct CompletionItem { pub struct CompletionItem {
/// What user sees in pop-up in the UI. label: String,
pub label: String, lookup: Option<String>,
/// What string is used for filtering, defaults to label. snippet: Option<String>,
pub lookup: Option<String>, }
/// What is inserted, defaults to label.
pub snippet: Option<String>, pub enum InsertText {
PlainText { text: String },
Snippet { text: String },
} }
impl CompletionItem { impl CompletionItem {
@ -17,6 +19,26 @@ impl CompletionItem {
snippet: None, snippet: None,
} }
} }
/// What user sees in pop-up in the UI.
pub fn label(&self) -> &str {
&self.label
}
/// What string is used for filtering.
pub fn lookup(&self) -> &str {
self.lookup
.as_ref()
.map(|it| it.as_str())
.unwrap_or(self.label())
}
/// What is inserted.
pub fn insert_text(&self) -> InsertText {
match &self.snippet {
None => InsertText::PlainText {
text: self.label.clone(),
},
Some(it) => InsertText::Snippet { text: it.clone() },
}
}
} }
#[must_use] #[must_use]

View File

@ -39,25 +39,19 @@ pub(super) fn completions(
} }
let module_scope = module.scope(db)?; let module_scope = module.scope(db)?;
acc.extend( module_scope
module_scope .entries()
.entries() .filter(|(_name, res)| {
.filter(|(_name, res)| { // Don't expose this item
// Don't expose this item match res.import {
match res.import { None => true,
None => true, Some(import) => {
Some(import) => { let range = import.range(db, module.source().file_id());
let range = import.range(db, module.source().file_id()); !range.is_subrange(&name_ref.syntax().range())
!range.is_subrange(&name_ref.syntax().range())
}
} }
}) }
.map(|(name, _res)| CompletionItem { })
label: name.to_string(), .for_each(|(name, _res)| CompletionItem::new(name.to_string()).add_to(acc));
lookup: None,
snippet: None,
}),
);
} }
NameRefKind::Path(path) => complete_path(acc, db, module, path)?, NameRefKind::Path(path) => complete_path(acc, db, module, path)?,
NameRefKind::BareIdentInMod => { NameRefKind::BareIdentInMod => {

View File

@ -30,7 +30,7 @@ use crate::{
}; };
pub use crate::{ pub use crate::{
completion::CompletionItem, completion::{CompletionItem, InsertText},
}; };
pub use ra_editor::{ pub use ra_editor::{
FileSymbol, Fold, FoldKind, HighlightedRange, LineIndex, Runnable, RunnableKind, StructureNode, FileSymbol, Fold, FoldKind, HighlightedRange, LineIndex, Runnable, RunnableKind, StructureNode,

View File

@ -8,7 +8,7 @@ use languageserver_types::{
PrepareRenameResponse, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit, PrepareRenameResponse, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit,
WorkspaceEdit, ParameterInformation, ParameterLabel, SignatureInformation, Hover, HoverContents, WorkspaceEdit, ParameterInformation, ParameterLabel, SignatureInformation, Hover, HoverContents,
}; };
use ra_analysis::{FileId, FoldKind, Query, RunnableKind, FilePosition}; use ra_analysis::{FileId, FoldKind, Query, RunnableKind, FilePosition, InsertText};
use ra_syntax::{TextUnit, text_utils::intersect}; use ra_syntax::{TextUnit, text_utils::intersect};
use ra_text_edit::text_utils::contains_offset_nonstrict; use ra_text_edit::text_utils::contains_offset_nonstrict;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
@ -423,15 +423,21 @@ pub fn handle_completion(
.into_iter() .into_iter()
.map(|item| { .map(|item| {
let mut res = CompletionItem { let mut res = CompletionItem {
label: item.label, label: item.label().to_string(),
filter_text: item.lookup, filter_text: Some(item.lookup().to_string()),
..Default::default() ..Default::default()
}; };
if let Some(snip) = item.snippet { match item.insert_text() {
res.insert_text = Some(snip); InsertText::PlainText { text } => {
res.insert_text_format = Some(InsertTextFormat::Snippet); res.insert_text = Some(text);
res.kind = Some(CompletionItemKind::Keyword); res.insert_text_format = Some(InsertTextFormat::PlainText);
}; }
InsertText::Snippet { text } => {
res.insert_text = Some(text);
res.insert_text_format = Some(InsertTextFormat::Snippet);
res.kind = Some(CompletionItemKind::Keyword);
}
}
res res
}) })
.collect(); .collect();