Skip to content

Tracking issue for ide-completion refactor #12144

Closed
@Veykril

Description

@Veykril

In #11397 I started refactoring the completions crate a bit and I haven't gotten back to finishing this up, so the crate is in a weird state where we use 3 differnt things to determine where certain completions apply. So with this I'll write down what I had in mind and where we are currently at in regards to that plan.

Completions are generated by fist calculating a CompletionContext which analyzes the surrounding context of the cursor position which we can then derive the completions from. Following that we just execute a bunch of functions that fill the completions accumulator with completions.

completions::attribute::complete_attribute(&mut acc, &ctx);
completions::attribute::complete_derive(&mut acc, &ctx);
completions::attribute::complete_known_attribute_input(&mut acc, &ctx);
completions::dot::complete_dot(&mut acc, &ctx);
completions::extern_abi::complete_extern_abi(&mut acc, &ctx);
completions::flyimport::import_on_the_fly(&mut acc, &ctx);
completions::fn_param::complete_fn_param(&mut acc, &ctx);
completions::format_string::format_string(&mut acc, &ctx);
completions::inferred_type(&mut acc, &ctx);
completions::keyword::complete_expr_keyword(&mut acc, &ctx);
completions::lifetime::complete_label(&mut acc, &ctx);
completions::lifetime::complete_lifetime(&mut acc, &ctx);
completions::mod_::complete_mod(&mut acc, &ctx);
completions::pattern::complete_pattern(&mut acc, &ctx);
completions::postfix::complete_postfix(&mut acc, &ctx);
completions::qualified_path::complete_qualified_path(&mut acc, &ctx);
completions::record::complete_record_literal(&mut acc, &ctx);
completions::record::complete_record(&mut acc, &ctx);
completions::snippet::complete_expr_snippet(&mut acc, &ctx);
completions::snippet::complete_item_snippet(&mut acc, &ctx);
completions::trait_impl::complete_trait_impl(&mut acc, &ctx);
completions::unqualified_path::complete_unqualified_path(&mut acc, &ctx);
completions::use_::complete_use_tree(&mut acc, &ctx);
completions::vis::complete_vis(&mut acc, &ctx);

The here was to have a function calculating completions for a specific "thing", this "thing" varies widely as to what it applies though. My goal with the refactor was to make this "thing" more consistent in what it covers.

We can group the things we actually complete into roughly the following:

  • keywords
  • Names
  • Lifetimes
  • NameRefs (paths and a few exceptios)
  • snippets
  • very specialized things (string literals, fmt strings, ...)

Obviously grouping the completion generation by just these is too rough, we want to do it differently. Completing by Names and NameRefs alone is messy, as we need to know about the context of where we are completing in (are we inside a type position, expression position, function return type, etc...), but this is what we kind of are doing right now if you take a look at the unqualified path module or the qualfied path module (these are practically the NameRef case). There are a bunch of different checks regarding where we are currently at placed around at various places making the code a mess.

So what I instead envision is for us to split these modules apart according to their position they apply to, with branches for the different thinsg that can be completed there (with a few exceptions for special completions). I've started with this for paths, where I have split out attributes, visibility paths, use paths and pattern paths.
This structure allows one to more easily reason about what completions apply where.

This refactor should get us closer to do "perfect completions".

I'll fully fill out the list of finer grained tasks here later this week:

  • Split apart [unqualfied path]https://github.com/rust-lang/rust-analyzer/blob/0ee4e6a22d79f58b6b459dbc874d6b90a4495d83/crates/ide-completion/src/completions/unqualified_path.rs) and qualfied path into the remaining variants
    • Expressions / Statements
    • Type
    • Derive
    • Attribute
    • Visibility
    • Pattern
    • Use
    • ItemList / AssocItemList (module and sourcefile / trait and impl, macro calls can appear there)
  • Split up keyword module
    • Implement proper keyword completions for items, respecting their order and similar. That is in unsafe const $0 we should only propose fn, not const or unsafe again.
  • Properly handle completions in generic argument position, currently its offered via type path completions with some special cases...
  • Split flyimport into the corresponding modules, this should probably be done last. We need to verify that the modules doing flyimport are disjoint so we don't do this multiple times.
  • Remove is_path_disallowed and other CompletionContext functions that look like temporary hacks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-completionautocompletionS-actionableSomeone could pick this issue up and work on it right now

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions