2 mod completion_context;
6 mod complete_struct_literal;
15 use ra_db::SourceDatabase;
16 use ra_syntax::ast::{self, AstNode};
22 completion_item::{Completions, CompletionKind},
23 completion_context::CompletionContext,
28 use crate::completion::completion_item::{do_completion, check_completion};
30 pub use crate::completion::completion_item::{CompletionItem, CompletionItemKind, InsertTextFormat};
32 /// Main entry point for completion. We run completion as a two-phase process.
34 /// First, we look at the position and collect a so-called `CompletionContext.
35 /// This is a somewhat messy process, because, during completion, syntax tree is
36 /// incomplete and can look really weird.
38 /// Once the context is collected, we run a series of completion routines which
39 /// look at the context and produce completion items. One subtlety about this
40 /// phase is that completion engine should not filter by the substring which is
41 /// already present, it should give all possible variants for the identifier at
42 /// the caret. In other words, for
51 /// `foo` *should* be present among the completion variants. Filtering by
52 /// identifier prefix/fuzzy match should be done higher in the stack, together
53 /// with ordering of completions (currently this is done by the client).
54 pub(crate) fn completions(db: &db::RootDatabase, position: FilePosition) -> Option<Completions> {
55 let original_file = db.parse(position.file_id);
56 let ctx = CompletionContext::new(db, &original_file, position)?;
58 let mut acc = Completions::default();
60 complete_fn_param::complete_fn_param(&mut acc, &ctx);
61 complete_keyword::complete_expr_keyword(&mut acc, &ctx);
62 complete_keyword::complete_use_tree_keyword(&mut acc, &ctx);
63 complete_snippet::complete_expr_snippet(&mut acc, &ctx);
64 complete_snippet::complete_item_snippet(&mut acc, &ctx);
65 complete_path::complete_path(&mut acc, &ctx);
66 complete_scope::complete_scope(&mut acc, &ctx);
67 complete_dot::complete_dot(&mut acc, &ctx);
68 complete_struct_literal::complete_struct_literal(&mut acc, &ctx);
69 complete_pattern::complete_pattern(&mut acc, &ctx);
70 complete_postfix::complete_postfix(&mut acc, &ctx);
74 pub fn function_label(node: &ast::FnDef) -> Option<String> {
75 let label: String = if let Some(body) = node.body() {
76 let body_range = body.syntax().range();
77 let label: String = node
80 .filter(|child| !child.range().is_subrange(&body_range)) // Filter out body
81 .filter(|child| ast::Comment::cast(child).is_none()) // Filter out comments
82 .filter(|child| ast::Attr::cast(child).is_none()) // Filter out attributes
83 .map(|node| node.text().to_string())
87 node.syntax().text().to_string()
90 Some(label.trim().to_owned())
93 pub fn const_label(node: &ast::ConstDef) -> String {
94 let label: String = node
97 .filter(|child| ast::Comment::cast(child).is_none())
98 .filter(|child| ast::Attr::cast(child).is_none())
99 .map(|node| node.text().to_string())
102 label.trim().to_owned()
105 pub fn type_label(node: &ast::TypeDef) -> String {
106 let label: String = node
109 .filter(|child| ast::Comment::cast(child).is_none())
110 .filter(|child| ast::Attr::cast(child).is_none())
111 .map(|node| node.text().to_string())
114 label.trim().to_owned()