]> git.lizzy.rs Git - rust.git/blob - crates/ra_ide/src/completion.rs
feat: improve dot completions with scoring
[rust.git] / crates / ra_ide / src / completion.rs
1 //! FIXME: write short doc here
2
3 mod completion_item;
4 mod completion_context;
5 mod presentation;
6
7 mod complete_dot;
8 mod complete_record;
9 mod complete_pattern;
10 mod complete_fn_param;
11 mod complete_keyword;
12 mod complete_snippet;
13 mod complete_qualified_path;
14 mod complete_unqualified_path;
15 mod complete_postfix;
16 mod complete_macro_in_item_position;
17 mod complete_trait_impl;
18 #[cfg(test)]
19 mod test_utils;
20
21 use ra_ide_db::RootDatabase;
22
23 use crate::{
24     completion::{
25         completion_context::CompletionContext,
26         completion_item::{CompletionKind, Completions},
27     },
28     FilePosition,
29 };
30
31 pub use crate::completion::completion_item::{
32     CompletionItem, CompletionItemKind, CompletionScore, InsertTextFormat,
33 };
34
35 #[derive(Clone, Debug, PartialEq, Eq)]
36 pub struct CompletionConfig {
37     pub enable_postfix_completions: bool,
38     pub add_call_parenthesis: bool,
39     pub add_call_argument_snippets: bool,
40 }
41
42 impl Default for CompletionConfig {
43     fn default() -> Self {
44         CompletionConfig {
45             enable_postfix_completions: true,
46             add_call_parenthesis: true,
47             add_call_argument_snippets: true,
48         }
49     }
50 }
51
52 /// Main entry point for completion. We run completion as a two-phase process.
53 ///
54 /// First, we look at the position and collect a so-called `CompletionContext.
55 /// This is a somewhat messy process, because, during completion, syntax tree is
56 /// incomplete and can look really weird.
57 ///
58 /// Once the context is collected, we run a series of completion routines which
59 /// look at the context and produce completion items. One subtlety about this
60 /// phase is that completion engine should not filter by the substring which is
61 /// already present, it should give all possible variants for the identifier at
62 /// the caret. In other words, for
63 ///
64 /// ```no-run
65 /// fn f() {
66 ///     let foo = 92;
67 ///     let _ = bar<|>
68 /// }
69 /// ```
70 ///
71 /// `foo` *should* be present among the completion variants. Filtering by
72 /// identifier prefix/fuzzy match should be done higher in the stack, together
73 /// with ordering of completions (currently this is done by the client).
74 pub(crate) fn completions(
75     db: &RootDatabase,
76     position: FilePosition,
77     config: &CompletionConfig,
78 ) -> Option<Completions> {
79     let ctx = CompletionContext::new(db, position, config)?;
80
81     let mut acc = Completions::default();
82
83     complete_fn_param::complete_fn_param(&mut acc, &ctx);
84     complete_keyword::complete_expr_keyword(&mut acc, &ctx);
85     complete_keyword::complete_use_tree_keyword(&mut acc, &ctx);
86     complete_snippet::complete_expr_snippet(&mut acc, &ctx);
87     complete_snippet::complete_item_snippet(&mut acc, &ctx);
88     complete_qualified_path::complete_qualified_path(&mut acc, &ctx);
89     complete_unqualified_path::complete_unqualified_path(&mut acc, &ctx);
90     complete_dot::complete_dot(&mut acc, &ctx);
91     complete_record::complete_record(&mut acc, &ctx);
92     complete_pattern::complete_pattern(&mut acc, &ctx);
93     complete_postfix::complete_postfix(&mut acc, &ctx);
94     complete_macro_in_item_position::complete_macro_in_item_position(&mut acc, &ctx);
95     complete_trait_impl::complete_trait_impl(&mut acc, &ctx);
96
97     Some(acc)
98 }