]> git.lizzy.rs Git - rust.git/blob - crates/ra_ide_api/src/completion.rs
Pass Documentation up to LSP and add "rust" to our codeblocks there
[rust.git] / crates / ra_ide_api / src / completion.rs
1 mod completion_item;
2 mod completion_context;
3
4 mod complete_dot;
5 mod complete_fn_param;
6 mod complete_keyword;
7 mod complete_snippet;
8 mod complete_path;
9 mod complete_scope;
10 mod complete_postfix;
11
12 use ra_db::SourceDatabase;
13 use ra_syntax::ast::{self, AstNode};
14
15 use crate::{
16     db,
17     FilePosition,
18     completion::{
19         completion_item::{Completions, CompletionKind},
20         completion_context::CompletionContext,
21     },
22 };
23
24 pub use crate::completion::completion_item::{CompletionItem, CompletionItemKind, InsertTextFormat};
25
26 /// Main entry point for completion. We run completion as a two-phase process.
27 ///
28 /// First, we look at the position and collect a so-called `CompletionContext.
29 /// This is a somewhat messy process, because, during completion, syntax tree is
30 /// incomplete and can look really weird.
31 ///
32 /// Once the context is collected, we run a series of completion routines which
33 /// look at the context and produce completion items. One subtelty about this
34 /// phase is that completion engine should not filter by the substring which is
35 /// already present, it should give all possible variants for the identifier at
36 /// the caret. In other words, for
37 ///
38 /// ```no-run
39 /// fn f() {
40 ///     let foo = 92;
41 ///     let _ = bar<|>
42 /// }
43 /// ```
44 ///
45 /// `foo` *should* be present among the completion variants. Filtering by
46 /// identifier prefix/fuzzy match should be done higher in the stack, together
47 /// with ordering of completions (currently this is done by the client).
48 pub(crate) fn completions(db: &db::RootDatabase, position: FilePosition) -> Option<Completions> {
49     let original_file = db.parse(position.file_id);
50     let ctx = CompletionContext::new(db, &original_file, position)?;
51
52     let mut acc = Completions::default();
53
54     complete_fn_param::complete_fn_param(&mut acc, &ctx);
55     complete_keyword::complete_expr_keyword(&mut acc, &ctx);
56     complete_keyword::complete_use_tree_keyword(&mut acc, &ctx);
57     complete_snippet::complete_expr_snippet(&mut acc, &ctx);
58     complete_snippet::complete_item_snippet(&mut acc, &ctx);
59     complete_path::complete_path(&mut acc, &ctx);
60     complete_scope::complete_scope(&mut acc, &ctx);
61     complete_dot::complete_dot(&mut acc, &ctx);
62     complete_postfix::complete_postfix(&mut acc, &ctx);
63     Some(acc)
64 }
65
66 pub fn function_label(node: &ast::FnDef) -> Option<String> {
67     let label: String = if let Some(body) = node.body() {
68         let body_range = body.syntax().range();
69         let label: String = node
70             .syntax()
71             .children()
72             .filter(|child| !child.range().is_subrange(&body_range)) // Filter out body
73             .filter(|child| ast::Comment::cast(child).is_none()) // Filter out comments
74             .map(|node| node.text().to_string())
75             .collect();
76         label
77     } else {
78         node.syntax().text().to_string()
79     };
80
81     Some(label.trim().to_owned())
82 }