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

WIP: First pass at terminal-mode completions #665

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

wurli
Copy link

@wurli wurli commented Dec 19, 2024

Hi :)

Following #305 I thought I'd have a crack at terminal-mode completions. This is very much at proof-of-concept stage, but I've enjoyed tinkering with it so far so would be happy to keep working on it if you don't mind feeding back on current progress and advising about design for next steps.

Key things to note:

  • I created cmp/lib/term_events.lua to listen for edits in the terminal. I used vim.on_key() to achieve this as there's no terminal equivalent for the InsertCharPre event. I was pretty torn about simply lifting the code from cmp/lib/cmdline_events.lua, but decided against this as there's a few things there I didn't quite understand, e.g. the use of timers and everything being accomplished by on_cursor_moved(). If you don't mind explaining what these are doing I'll be happy to add equivalent functionality if needed :)

  • AFAIK Neovim doesn't provide a convenient API for inserting text into the terminal prompt, so I had to cobble something together using vim.feedkeys(). I also experimented with vim.paste(), but the results didn't feel good.

  • Still to do:

    • Autocompletion immediately triggers after accepting a suggestion. It looks like after accepting a suggestion like Bla, the final character in the accepted text, in this case a, is once again used to trigger a completion. Unfortunately I couldn't work out how this is avoided in cmdline/insert mode, so very grateful for any pointers here. My guess is that this has something to do with my omission of on_cursor_moved(), but playing with this functionality hasn't (yet) led me to a fix.

    • I haven't added any user-facing configuration for terminal mode. I can imagine this is something most users will want quite fine-grained control over, so I thought I'd seek some pointers on this before diving in.

Thanks in advance for review!

@wurli wurli marked this pull request as draft December 19, 2024 23:55
@Shougo
Copy link

Shougo commented Dec 20, 2024

AFAIK Neovim doesn't provide a convenient API for inserting text into the terminal prompt, so I had to cobble something together using vim.feedkeys(). I also experimented with vim.paste(), but the results didn't feel good.

You can use chansend() instead.

@Shougo
Copy link

Shougo commented Dec 20, 2024

Autocompletion immediately triggers after accepting a suggestion. It looks like after accepting a suggestion like Bla, the final character in the accepted text, in this case a, is once again used to trigger a completion. Unfortunately I couldn't work out how this is avoided in cmdline/insert mode, so very grateful for any pointers here. My guess is that this has something to do with my omission of on_cursor_moved(), but playing with this functionality hasn't (yet) led me to a fix.

It is known issue. I think auto insert feature should be disabled in terminal mode.

@wurli
Copy link
Author

wurli commented Dec 20, 2024

You can use chansend() instead.

Thanks, done! This has also fixed the issue with completions being triggered after accepting :)

It is known issue. I think auto insert feature should be disabled in terminal mode.

Thanks, good to know. Agreed - I'll look into this.

@Saghen
Copy link
Owner

Saghen commented Dec 20, 2024

Wow, this looks great, thank you!

I was pretty torn about simply lifting the code from cmp/lib/cmdline_events.lua, but decided against this as there's a few things there I didn't quite understand, e.g. the use of timers and everything being accomplished by on_cursor_moved()

That code is truly cursed 😂 The idea is that when the user types, we trigger the on_text_changed(char) and when the user moves the cursor or deletes a character, we trigger on_cursor_moved(). There's no CursorMovedC event in neovim 0.10 (coming in 0.11), so for on_cursor_moved, I've written a hack that checks every 16ms if the cursor position has changed, and that the text hasn't changed (unless backspace was pressed). It's likely that with your on_key solution, you could use CursorMoved directly similar to buffer_events.lua, rather than hacking around.

I haven't added any user-facing configuration for terminal mode. I can imagine this is something most users will want quite fine-grained control over, so I thought I'd seek some pointers on this before diving in.

For now, I think it would be enough to support keymaps.term and sources.term as that would match where cmdline is at

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants