From b6d6277362366e7ddd2b355d83227041d8b6fa12 Mon Sep 17 00:00:00 2001 From: Steffen Lyngbaek Date: Mon, 9 Mar 2020 18:10:25 -0700 Subject: Completition for type name? #3418 Iterate through TupleStructPat's until a MatchArm if one exists. Store in a new is_pat_bind_and_path bool and allow the `complete_scope` to find matches. Added some tests to ensure it works in simple and nested cases. --- crates/ra_ide/src/completion/completion_context.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'crates/ra_ide/src/completion/completion_context.rs') diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs index 54589a2a8..d867ff6b2 100644 --- a/crates/ra_ide/src/completion/completion_context.rs +++ b/crates/ra_ide/src/completion/completion_context.rs @@ -36,6 +36,9 @@ pub(crate) struct CompletionContext<'a> { /// If a name-binding or reference to a const in a pattern. /// Irrefutable patterns (like let) are excluded. pub(super) is_pat_binding: bool, + // A bind battern which may also be part of a path. + // if let Some(En<|>) = Some(Enum::A) + pub(super) is_pat_binding_and_path: bool, /// A single-indent path, like `foo`. `::foo` should not be considered a trivial path. pub(super) is_trivial_path: bool, /// If not a trivial path, the prefix (qualifier). @@ -95,6 +98,7 @@ impl<'a> CompletionContext<'a> { impl_def: None, is_param: false, is_pat_binding: false, + is_pat_binding_and_path: false, is_trivial_path: false, path_prefix: None, after_if: false, @@ -186,12 +190,20 @@ impl<'a> CompletionContext<'a> { // suggest declaration names, see `CompletionKind::Magic`. if let Some(name) = find_node_at_offset::(&file_with_fake_ident, offset) { if let Some(bind_pat) = name.syntax().ancestors().find_map(ast::BindPat::cast) { - let parent = bind_pat.syntax().parent(); + let mut parent = bind_pat.syntax().parent(); if parent.clone().and_then(ast::MatchArm::cast).is_some() - || parent.and_then(ast::Condition::cast).is_some() + || parent.clone().and_then(ast::Condition::cast).is_some() { self.is_pat_binding = true; } + + while let Some(_) = parent.clone().and_then(ast::TupleStructPat::cast) { + parent = parent.and_then(|p| p.parent()); + if parent.clone().and_then(ast::MatchArm::cast).is_some() { + self.is_pat_binding_and_path = true; + break; + } + } } if is_node::(name.syntax()) { self.is_param = true; -- cgit v1.2.3