Skip to content

Commit 1b5f046

Browse files
committed
fix: visibility completion
1 parent 6c9fc4f commit 1b5f046

File tree

9 files changed

+103
-57
lines changed

9 files changed

+103
-57
lines changed

crates/ide-completion/src/lib.rs

+28-24
Original file line numberDiff line numberDiff line change
@@ -143,36 +143,40 @@ pub fn completions(
143143
db: &RootDatabase,
144144
config: &CompletionConfig,
145145
position: FilePosition,
146+
trigger_character: Option<&str>,
146147
) -> Option<Completions> {
147148
let ctx = &CompletionContext::new(db, position, config)?;
148149
let mut acc = Completions::default();
149150

150151
{
151152
let acc = &mut acc;
152-
completions::attribute::complete_attribute(acc, ctx);
153-
completions::attribute::complete_derive(acc, ctx);
154-
completions::attribute::complete_known_attribute_input(acc, ctx);
155-
completions::dot::complete_dot(acc, ctx);
156-
completions::expr::complete_expr_path(acc, ctx);
157-
completions::extern_abi::complete_extern_abi(acc, ctx);
158-
completions::flyimport::import_on_the_fly(acc, ctx);
159-
completions::fn_param::complete_fn_param(acc, ctx);
160-
completions::format_string::format_string(acc, ctx);
161-
completions::item_list::complete_item_list(acc, ctx);
162-
completions::keyword::complete_expr_keyword(acc, ctx);
163-
completions::lifetime::complete_label(acc, ctx);
164-
completions::lifetime::complete_lifetime(acc, ctx);
165-
completions::mod_::complete_mod(acc, ctx);
166-
completions::pattern::complete_pattern(acc, ctx);
167-
completions::postfix::complete_postfix(acc, ctx);
168-
completions::record::complete_record_literal(acc, ctx);
169-
completions::record::complete_record(acc, ctx);
170-
completions::snippet::complete_expr_snippet(acc, ctx);
171-
completions::snippet::complete_item_snippet(acc, ctx);
172-
completions::trait_impl::complete_trait_impl(acc, ctx);
173-
completions::r#type::complete_type_path(acc, ctx);
174-
completions::r#type::complete_inferred_type(acc, ctx);
175-
completions::use_::complete_use_tree(acc, ctx);
153+
// prevent `(` from triggering unwanted completion noise
154+
if trigger_character != Some("(") {
155+
completions::attribute::complete_attribute(acc, ctx);
156+
completions::attribute::complete_derive(acc, ctx);
157+
completions::attribute::complete_known_attribute_input(acc, ctx);
158+
completions::dot::complete_dot(acc, ctx);
159+
completions::expr::complete_expr_path(acc, ctx);
160+
completions::extern_abi::complete_extern_abi(acc, ctx);
161+
completions::flyimport::import_on_the_fly(acc, ctx);
162+
completions::fn_param::complete_fn_param(acc, ctx);
163+
completions::format_string::format_string(acc, ctx);
164+
completions::item_list::complete_item_list(acc, ctx);
165+
completions::keyword::complete_expr_keyword(acc, ctx);
166+
completions::lifetime::complete_label(acc, ctx);
167+
completions::lifetime::complete_lifetime(acc, ctx);
168+
completions::mod_::complete_mod(acc, ctx);
169+
completions::pattern::complete_pattern(acc, ctx);
170+
completions::postfix::complete_postfix(acc, ctx);
171+
completions::record::complete_record_literal(acc, ctx);
172+
completions::record::complete_record(acc, ctx);
173+
completions::snippet::complete_expr_snippet(acc, ctx);
174+
completions::snippet::complete_item_snippet(acc, ctx);
175+
completions::trait_impl::complete_trait_impl(acc, ctx);
176+
completions::r#type::complete_type_path(acc, ctx);
177+
completions::r#type::complete_inferred_type(acc, ctx);
178+
completions::use_::complete_use_tree(acc, ctx);
179+
}
176180
completions::vis::complete_vis_path(acc, ctx);
177181
}
178182

crates/ide-completion/src/render.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -410,15 +410,15 @@ mod tests {
410410

411411
#[track_caller]
412412
fn check_relevance_for_kinds(ra_fixture: &str, kinds: &[CompletionItemKind], expect: Expect) {
413-
let mut actual = get_all_items(TEST_CONFIG, ra_fixture);
413+
let mut actual = get_all_items(TEST_CONFIG, ra_fixture, None);
414414
actual.retain(|it| kinds.contains(&it.kind()));
415415
actual.sort_by_key(|it| cmp::Reverse(it.relevance().score()));
416416
check_relevance_(actual, expect);
417417
}
418418

419419
#[track_caller]
420420
fn check_relevance(ra_fixture: &str, expect: Expect) {
421-
let mut actual = get_all_items(TEST_CONFIG, ra_fixture);
421+
let mut actual = get_all_items(TEST_CONFIG, ra_fixture, None);
422422
actual.retain(|it| it.kind() != CompletionItemKind::Snippet);
423423
actual.retain(|it| it.kind() != CompletionItemKind::Keyword);
424424
actual.retain(|it| it.kind() != CompletionItemKind::BuiltinType);

crates/ide-completion/src/tests.rs

+20-7
Original file line numberDiff line numberDiff line change
@@ -79,20 +79,28 @@ pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig {
7979
};
8080

8181
pub(crate) fn completion_list(ra_fixture: &str) -> String {
82-
completion_list_with_config(TEST_CONFIG, ra_fixture, true)
82+
completion_list_with_config(TEST_CONFIG, ra_fixture, true, None)
8383
}
8484

8585
pub(crate) fn completion_list_no_kw(ra_fixture: &str) -> String {
86-
completion_list_with_config(TEST_CONFIG, ra_fixture, false)
86+
completion_list_with_config(TEST_CONFIG, ra_fixture, false, None)
87+
}
88+
89+
pub(crate) fn completion_list_with_trigger_character(
90+
ra_fixture: &str,
91+
trigger_character: Option<&str>,
92+
) -> String {
93+
completion_list_with_config(TEST_CONFIG, ra_fixture, true, trigger_character)
8794
}
8895

8996
fn completion_list_with_config(
9097
config: CompletionConfig,
9198
ra_fixture: &str,
9299
include_keywords: bool,
100+
trigger_character: Option<&str>,
93101
) -> String {
94102
// filter out all but one builtintype completion for smaller test outputs
95-
let items = get_all_items(config, ra_fixture);
103+
let items = get_all_items(config, ra_fixture, trigger_character);
96104
let mut bt_seen = false;
97105
let items = items
98106
.into_iter()
@@ -126,7 +134,7 @@ pub(crate) fn do_completion_with_config(
126134
code: &str,
127135
kind: CompletionItemKind,
128136
) -> Vec<CompletionItem> {
129-
get_all_items(config, code)
137+
get_all_items(config, code, None)
130138
.into_iter()
131139
.filter(|c| c.kind() == kind)
132140
.sorted_by(|l, r| l.label().cmp(r.label()))
@@ -173,7 +181,7 @@ pub(crate) fn check_edit_with_config(
173181
let ra_fixture_after = trim_indent(ra_fixture_after);
174182
let (db, position) = position(ra_fixture_before);
175183
let completions: Vec<CompletionItem> =
176-
crate::completions(&db, &config, position).unwrap().into();
184+
crate::completions(&db, &config, position, None).unwrap().into();
177185
let (completion,) = completions
178186
.iter()
179187
.filter(|it| it.lookup() == what)
@@ -214,9 +222,14 @@ pub(crate) fn check_pattern_is_applicable(code: &str, check: impl FnOnce(SyntaxE
214222
assert!(check(NodeOrToken::Token(token)));
215223
}
216224

217-
pub(crate) fn get_all_items(config: CompletionConfig, code: &str) -> Vec<CompletionItem> {
225+
pub(crate) fn get_all_items(
226+
config: CompletionConfig,
227+
code: &str,
228+
trigger_character: Option<&str>,
229+
) -> Vec<CompletionItem> {
218230
let (db, position) = position(code);
219-
let res = crate::completions(&db, &config, position).map_or_else(Vec::default, Into::into);
231+
let res = crate::completions(&db, &config, position, trigger_character)
232+
.map_or_else(Vec::default, Into::into);
220233
// validate
221234
res.iter().for_each(|it| {
222235
let sr = it.source_range();

crates/ide-completion/src/tests/fn_param.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
use expect_test::{expect, Expect};
22

3-
use crate::tests::completion_list;
3+
use crate::tests::{completion_list, completion_list_with_trigger_character};
44

55
fn check(ra_fixture: &str, expect: Expect) {
66
let actual = completion_list(ra_fixture);
77
expect.assert_eq(&actual);
88
}
99

10+
fn check_with_trigger_character(ra_fixture: &str, trigger_character: Option<&str>, expect: Expect) {
11+
let actual = completion_list_with_trigger_character(ra_fixture, trigger_character);
12+
expect.assert_eq(&actual)
13+
}
14+
1015
#[test]
1116
fn only_param() {
1217
check(
@@ -113,6 +118,17 @@ fn outer(text: &str) {
113118
)
114119
}
115120

121+
#[test]
122+
fn trigger_by_l_paren() {
123+
check_with_trigger_character(
124+
r#"
125+
fn foo($0)
126+
"#,
127+
Some("("),
128+
expect![[]],
129+
)
130+
}
131+
116132
#[test]
117133
fn shows_non_ident_pat_param() {
118134
check(

crates/ide-completion/src/tests/visibility.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
11
//! Completion tests for visibility modifiers.
22
use expect_test::{expect, Expect};
33

4-
use crate::tests::completion_list;
4+
use crate::tests::{completion_list, completion_list_with_trigger_character};
55

66
fn check(ra_fixture: &str, expect: Expect) {
77
let actual = completion_list(ra_fixture);
88
expect.assert_eq(&actual)
99
}
1010

11+
fn check_with_trigger_character(ra_fixture: &str, trigger_character: Option<&str>, expect: Expect) {
12+
let actual = completion_list_with_trigger_character(ra_fixture, trigger_character);
13+
expect.assert_eq(&actual)
14+
}
15+
1116
#[test]
1217
fn empty_pub() {
1318
cov_mark::check!(kw_completion_in);
14-
check(
19+
check_with_trigger_character(
1520
r#"
1621
pub($0)
1722
"#,
23+
Some("("),
1824
expect![[r#"
1925
kw crate
2026
kw in

crates/ide/src/lib.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -547,8 +547,11 @@ impl Analysis {
547547
&self,
548548
config: &CompletionConfig,
549549
position: FilePosition,
550+
trigger_character: Option<&str>,
550551
) -> Cancellable<Option<Vec<CompletionItem>>> {
551-
self.with_db(|db| ide_completion::completions(db, config, position).map(Into::into))
552+
self.with_db(|db| {
553+
ide_completion::completions(db, config, position, trigger_character).map(Into::into)
554+
})
552555
}
553556

554557
/// Resolves additional completion data at the position given.

crates/rust-analyzer/src/caps.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,12 @@ pub fn server_capabilities(config: &Config) -> ServerCapabilities {
2929
hover_provider: Some(HoverProviderCapability::Simple(true)),
3030
completion_provider: Some(CompletionOptions {
3131
resolve_provider: completions_resolve_provider(config.caps()),
32-
trigger_characters: Some(vec![":".to_string(), ".".to_string(), "'".to_string()]),
32+
trigger_characters: Some(vec![
33+
":".to_string(),
34+
".".to_string(),
35+
"'".to_string(),
36+
"(".to_string(),
37+
]),
3338
all_commit_characters: None,
3439
completion_item: None,
3540
work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },

crates/rust-analyzer/src/handlers.rs

+16-17
Original file line numberDiff line numberDiff line change
@@ -796,27 +796,26 @@ pub(crate) fn handle_completion(
796796
let _p = profile::span("handle_completion");
797797
let text_document_position = params.text_document_position.clone();
798798
let position = from_proto::file_position(&snap, params.text_document_position)?;
799-
let completion_triggered_after_single_colon = {
800-
let mut res = false;
801-
if let Some(ctx) = params.context {
802-
if ctx.trigger_character.as_deref() == Some(":") {
803-
let source_file = snap.analysis.parse(position.file_id)?;
804-
let left_token =
805-
source_file.syntax().token_at_offset(position.offset).left_biased();
806-
match left_token {
807-
Some(left_token) => res = left_token.kind() == T![:],
808-
None => res = true,
809-
}
810-
}
799+
let completion_trigger_character = params.context.and_then(|ctx| ctx.trigger_character);
800+
801+
if Some(":") == completion_trigger_character.as_deref() {
802+
let source_file = snap.analysis.parse(position.file_id)?;
803+
let left_token = source_file.syntax().token_at_offset(position.offset).left_biased();
804+
let completion_triggered_after_single_colon = match left_token {
805+
Some(left_token) => left_token.kind() == T![:],
806+
None => true,
807+
};
808+
if completion_triggered_after_single_colon {
809+
return Ok(None);
811810
}
812-
res
813-
};
814-
if completion_triggered_after_single_colon {
815-
return Ok(None);
816811
}
817812

818813
let completion_config = &snap.config.completion();
819-
let items = match snap.analysis.completions(completion_config, position)? {
814+
let items = match snap.analysis.completions(
815+
completion_config,
816+
position,
817+
completion_trigger_character.as_deref(),
818+
)? {
820819
None => return Ok(None),
821820
Some(items) => items,
822821
};

crates/rust-analyzer/src/integrated_benchmarks.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ fn integrated_completion_benchmark() {
148148
};
149149
let position =
150150
FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() };
151-
analysis.completions(&config, position).unwrap();
151+
analysis.completions(&config, position, None).unwrap();
152152
}
153153

154154
let completion_offset = {
@@ -185,7 +185,7 @@ fn integrated_completion_benchmark() {
185185
};
186186
let position =
187187
FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() };
188-
analysis.completions(&config, position).unwrap();
188+
analysis.completions(&config, position, None).unwrap();
189189
}
190190
}
191191

0 commit comments

Comments
 (0)