Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Completion sources #1015

Open
QiBaobin opened this issue Nov 8, 2021 · 13 comments
Open

Completion sources #1015

QiBaobin opened this issue Nov 8, 2021 · 13 comments
Labels
A-helix-term Area: Helix term improvements C-enhancement Category: Improvements E-help-wanted Call for participation: Extra attention is needed E-medium Call for participation: Experience needed to fix: Medium / intermediate

Comments

@QiBaobin
Copy link
Contributor

QiBaobin commented Nov 8, 2021

Describe your feature request

It's sweet to use the complete when there is a lsp server, but for all other cases, there is none of useful completion. Could we have some of below vim features, like completions keywords or lines from open files, I think it's also useful when lsp enabled. Thanks!

Completion can be done for:

1. Whole lines						|i_CTRL-X_CTRL-L|
2. keywords in the current file				|i_CTRL-X_CTRL-N|
3. keywords in 'dictionary'				|i_CTRL-X_CTRL-K|
4. keywords in 'thesaurus', thesaurus-style		|i_CTRL-X_CTRL-T|
5. keywords in the current and included files		|i_CTRL-X_CTRL-I|
6. tags							|i_CTRL-X_CTRL-]|
7. file names						|i_CTRL-X_CTRL-F|
8. definitions or macros				|i_CTRL-X_CTRL-D|
9. Vim command-line					|i_CTRL-X_CTRL-V|
10. User defined completion				|i_CTRL-X_CTRL-U|
11. omni completion					|i_CTRL-X_CTRL-O|
12. Spelling suggestions				|i_CTRL-X_s|
13. keywords in 'complete'				|i_CTRL-N| |i_CTRL-P|

@QiBaobin QiBaobin added the C-enhancement Category: Improvements label Nov 8, 2021
@kirawi kirawi added the A-helix-term Area: Helix term improvements label Nov 8, 2021
@pickfire pickfire added E-help-wanted Call for participation: Extra attention is needed E-medium Call for participation: Experience needed to fix: Medium / intermediate labels Nov 17, 2021
@pickfire
Copy link
Contributor

pickfire commented Nov 17, 2021

I think we should keep this issue small, maybe we can start with something simple such keyword completion, whole lines or files. Then close this issue, and open as we see fit.

@bram209
Copy link
Contributor

bram209 commented Dec 17, 2021

I find that path completion also comes in handy (currently using nvim-cmp with https://github.com/hrsh7th/cmp-path completion source enabled)

@bram209
Copy link
Contributor

bram209 commented Dec 17, 2021

when having multiple completion sources:

  • Results need to be prioritized (if LSP is enabled, those completions will likely be better suggestions since they are context-aware)
  • It may be annoying if the simple keyword completions already show up, before the slightly delayed LSP is done processing the request
  • if however, you are dealing with a big codebase and a slow language server (looking at you, tsserver), it may take a while for the LSP to come with completions, in these scenario's it would come in handy to have a fallback on the simple keyword completions in the meanwhile

Some configurable threshold(s) could work, i.e. if LSP is enabled and completion request takes longer than X, show Y completion source(s) instead

thoughts?

@bram209
Copy link
Contributor

bram209 commented Dec 17, 2021

@pickfire by keeping it small, are you intending to initially start with just some fallback completions in the case LSP is not loaded, or would you prefer that the completion system is set up in a way that completion sources are pluggable and multiple sources may be allowed at the same time?

@pickfire
Copy link
Contributor

Of course multiple sources and asynchronous results is the best, but I believe no one is focusing on this yet.

@altair-albert
Copy link

anyone focus on this issue?

@pickfire
Copy link
Contributor

pickfire commented May 8, 2022

@altair-albert see the latest pull request on #2403, but other than that most likely no. If you would like, feel free to give it a try to work on this issue.

@QiBaobin
Copy link
Contributor Author

Support word and line completions here #4816

@matklad
Copy link
Contributor

matklad commented Dec 14, 2022

Having code completion in ~/.config/helix/config.toml would be super extra nice, and having a generic completion provider infra would help with that.

@bram209
Copy link
Contributor

bram209 commented Dec 14, 2022

Having code completion in ~/.config/helix/config.toml would be super extra nice, and having a generic completion provider infra would help with that.

Would be nice if we have a (generated) json schema for the helix config, related: #1282

@the-mikedavis
Copy link
Member

Also related to that: #2894, #3901, #3383 (comment)

Philipp-M added a commit to Philipp-M/helix that referenced this issue Feb 16, 2023
…ith multiple different item sources (async, sync, refetch)

This PR unifies the functionality of the `Picker` and the `Menu` in the struct `OptionsManager` (i.e. matching/filtering, sorting, cursor management etc.), and extends the logic of `score` by being able to retain the cursor position (which is useful, if new entries are added async).

The main reason for this PR though is to have multiple option `ItemSource`s, which can be async and which may be refetched (see helix-editor#5055) to provide the options for the `OptionsManager`. It currently allows 3 different input sources: synchronous data, asynchronous data, and asynchronous functions which provide the data, which are reexecuted after an `IdleTimeout` occured (similar as helix-editor#5055).
This PR is or will be a requirement for helix-editor#2507 (currently provided by helix-editor#3082), which I will rebase onto this PR soon.

Noticeable effects right now:

* The `Menu` now has the more sophisticated logic of the picker (mostly better caching while changing the query)
* The `Menu` currently *doesn't* reset the cursor position, if `score()` is called (effectively different pattern query), I'm not sure  if we should keep this behavior, I guess it needs some testing and feedback. I have kept the original behavior of the Picker (everytime `score()` changes it resets the cursor)

This PR is an alternative to helix-editor#3082, which I wasn't completely happy with (adding options async was/is kind of a hack to keep it simple) thus this PR will supersede it. It was originally motivated by helix-editor#5055 and how to integrate that logic into helix-editor#2507 (which is not done yet). The PR unfortunately grew a little bit more than I've anticipated, but in general I think it's the cleaner and more future proof way to be able to have async item sources, which may change the options overtime.
For example the same logic of helix-editor#5055 could be simply implemented for the completion menu with different multiple completion sources, whether it makes sense or not (though also one of the motivations of this PR to have this possibility).
This should also cleanup and greatly (hopefully) simplify helix-editor#2507.

To make reviewing easier (I hope) I provide a technical summary of this PR:

* `OptionsManager` contains all logic that is necessary to manage options (d'oh), that means:
    * Filtering/matching of options with `score()` which takes a few more parameters now:
        * *Optional* pattern to be able to recalculate the score without providing a pattern (necessary for async addition of the options)
        * Boolean flag to retain the cursor, since it will likely be annoying, if an item source takes so long that the user is already selecting options of a different item source and it gets resetted because score has to be called again for matches that respect the new option source).
        * force_recalculation, kind of an optimization, if nothing external has changed (except new async options)
    * The `OptionsManager` is fed by `ItemSource`s
        * Fetching of items from the item source is started by the creation of the `OptionsManager` (`create_from_item_sources`), and as soon one item source provides some items a construction callback is executed (see below)
        * Async fetching is done by looping over `FuturesUnordered` async requests and adding the options via an `mpsc`, I wanted to avoid any `Mutex` or something alike to keep the rest of the logic as is (and likely to be more performant as well). Thus instead the editor `redraw_handle` is notified when new options are available and in the render functions new options are polled (via `poll_for_new_options`). Although not optimal, it was IMHO the best tradeoff (I tried different solutions, and came to that conclusion).
        * Options are stored with an additional index to the item source to be able to easily change the options on the fly, it provides some iterator wrapper functions to access the options/matches outside as usual.
    * When using the `OptionManager` with async sources, I have decided (to mostly mirror current logic) to use a "constructor callback" in the `create_from_item_sources` for creating e.g. the actual `Menu` or `Picker` when at least one item is available (this callback is only then executed), otherwise an optional other callback can show e.g. editor status messages, when there was no item source provided any data.
    * The `(File-)Picker` and `Menu` now takes the `OptionsManager` instead of the items or editor data (this is now provided in the `ItemSource`)
    * For sync data it's also possible to directly create the `OptionsManager` without a callback using `create_from_items` but only with this function.
* I've imported the `CompletionItem` from helix-editor#2507 to provide additional information where the item came from (which language server id and offset encoding) when multiple language servers are used as Item source, it's currently an enum to avoid unnecessary refactoring if other completion sources are added (such as helix-editor#2608 or helix-editor#1015), though it's not really relevant for this PR currently (as the doc has just one language server anyway), but I think it may be easier to review it here separated from helix-editor#2507 and it's also the (only) dependency of helix-editor#2507 for helix-editor#2608
* The `DynamicPicker` is removed as this behavior can now be modeled with a `ItemSource::AsyncRefetchOnIdleTimeoutWithPattern` which is done for the `workspace_symbol_picker`
@suqin-haha
Copy link

suqin-haha commented Aug 14, 2023

it would be better if it support highlight all the same variable presents. As well as, put the goto reference file list in a split window like file tree, and highlight all the keyword presents in file, that would really helpful to keep tracking changes to those references. What i mentioned already in vscode and i found it helpful when I am using them. :)

@fonskip
Copy link

fonskip commented Aug 22, 2024

  • How should suggestions be prioritized for, say, words ? Does it make sense to prioritize words that appear the most in the current file ? Or the closest ones to the cursor ? A mix of both ? The "closest ones" rule should be less resource intensive, I guess, as we could stop the search on the first few matches, but it makes sense to give a weight to words that are more frequently used.

  • Should words that are less than 3 chars long be excluded ? I think so.

  • Should the search be limited to a portion of the current file around the cursor if it is too big ? I guess it makes sense because I don’t see a scenario where it is super useful to autocomplete a word that appeared 10 000 lines before (and if you need it, you probably need an LSP Server anyway).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-helix-term Area: Helix term improvements C-enhancement Category: Improvements E-help-wanted Call for participation: Extra attention is needed E-medium Call for participation: Experience needed to fix: Medium / intermediate
Projects
None yet
Development

No branches or pull requests

9 participants