Skip to content

fix: use :startinsert instead of feedkeys to switch to terminal mode #2034

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

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

Conversation

phanen
Copy link
Contributor

@phanen phanen commented May 6, 2025

If user has their own startinsert, e.g. in the following case,
startinsert is trigger by :term, but later fzf term is focused.

nvim \
  +"au TermOpen * startinsert" \
  +"term" \
  +"lua vim.defer_fn(function() vim.cmd [[FzfLua files]] end, 100)"

Technically user should not startinsert on an incorrect window, but
currently there's no way to avoid it since builtin startinsert seems
defered but nvim_get_mode is fast (return actual mode immediately).

This PR periodly retry and only do startinsert in nt mode and on fzf term buffer.

TODO: test

@phanen phanen force-pushed the fix-feed2starti branch from 710190d to 3a69472 Compare May 6, 2025 15:34
@phanen phanen changed the title fix: don't use feedkeys don't swtich mode fix: use :startinsert instead of feedkeys to switch to terminal mode May 6, 2025
@ibhagwan
Copy link
Owner

ibhagwan commented May 6, 2025

Idk if we should touch this part, every time I messed with this (tried different strats) some edge case blew up (quite a few issues… including voodoo slowness), if the OP is the only issue so be it.

fzf-lua/lua/fzf-lua/fzf.lua

Lines 225 to 246 in ea6d8ce

-- A more robust way of entering TERMINAL mode "t". We had quite a few issues
-- sending `feedkeys|startinsert` after the term job is started, this approach
-- seems more consistent as it triggers when entering terminal normal mode "nt"
-- NOTE: **DO NOT USE** seems to cause valrious issues see #1672
-- vim.api.nvim_create_autocmd("ModeChanged", {
-- once = true,
-- buffer = 0,
-- callback = function(e)
-- if e.match:match(":nt") then
-- vim.defer_fn(function()
-- -- Prevents inserting "i" when spamming `ctrl-g` in `grep_lgrep`
-- -- Also verify we're not already in TERMINAL mode, could happen
-- -- if the user has an autocmd for TermOpen with `startinsert`
-- if vim.api.nvim_buf_is_valid(e.buf)
-- and vim.api.nvim_get_mode().mode ~= "t"
-- then
-- vim.cmd("startinsert")
-- end
-- end, 0)
-- end
-- end
-- })

@phanen
Copy link
Contributor Author

phanen commented May 6, 2025

Idk if we should touch this part, every time I messed with this (tried different strats) some edge case blew up (quite a few issues… including voodoo slowness), if the OP is the only issue so be it.

Sometimes use lsp_incoming_calls (maybe it's slow?) from builtin picker, i is also inserted into prompt unexpectedly.

Another edge case(found just now): press <c-g> too quickly in live_grep then I will have this error (however I cannot reproduce it in mini.sh which also just insert i into prompt)

vim.schedule callback: Vim(normal):Can't re-enter normal mode from terminal mode

@phanen
Copy link
Contributor Author

phanen commented May 7, 2025

Generally I think feedkeys "i" in terminal mode is not a good way. Since it's possible that we are really in terminal mode (startinsert already happened for some reason).

Another way maybe simpler, cannot we just use buffer-local TermOpen to startinsert?

That's seems the recommanded way from document :h :term | /TermOpen:

			To enter |Terminal-mode| automatically: >
			      autocmd TermOpen * startinsert

defer_fn hack here is just to avoid autocmd (maybe it's too complicated)

@phanen phanen force-pushed the fix-feed2starti branch from 3a69472 to 9bcee3d Compare May 7, 2025 00:05
@ibhagwan
Copy link
Owner

ibhagwan commented May 7, 2025

Another edge case(found just now): press too quickly in live_grep then I will have this error (however I cannot reproduce it in mini.sh which also just insert i into prompt)

This never happens to me even if I continue holding ctrl-g forever and stop randomly.

Another way maybe simpler, cannot we just use buffer-local TermOpen to startinsert?

I’ve looked into many different methods, forgot why this one didn’t work, I’m willing to explore this again just know that this is somewhat sensitive and as of now nobody complains or has issues with it.

@phanen
Copy link
Contributor Author

phanen commented May 7, 2025

This never happens to me even if I continue holding ctrl-g forever and stop randomly.

I just found the root cause of the error is a bug of my another plugin... Now no problem in my config even with lsp picker. (Although I can still insert i in mini.sh with a high key repeat rate e.g. xset r rate 140 100).

Maybe leave it here until some report more bug.

I also implement inline screenshot (like nvim's screen:expect) in test suite. Not sure if this feature needed. I can split this out to another PR.

9bcee3d (#2034)

@ibhagwan
Copy link
Owner

ibhagwan commented May 7, 2025

I also implement inline screenshot (like nvim's screen:expect) in test suite. Not sure if this feature needed. I can split this out to another PR.

I saw, looks great, if you are unsure about this PR and want the screenshots merged you can split it and I’ll merge.

Repository owner deleted a comment May 10, 2025
Repository owner deleted a comment May 10, 2025
Repository owner deleted a comment May 10, 2025
Repository owner deleted a comment May 10, 2025
Repository owner deleted a comment May 10, 2025
Repository owner deleted a comment May 10, 2025
Repository owner deleted a comment May 10, 2025
Repository owner deleted a comment May 10, 2025
Repository owner deleted a comment May 10, 2025
@ibhagwan ibhagwan force-pushed the fix-feed2starti branch 2 times, most recently from d923a4d to 9cf367c Compare May 14, 2025 00:29
@ibhagwan
Copy link
Owner

@phanen, I rebased and removed the CI commit since we already merged that, would you like to explore this further?

I tested the autocmd for TermOpen, it has a drawback when starting a new picker while the buffer is open, for example:

  • FzfLua builtin, select any picker = picker starts in normal mode
  • FzfLua live_grep + ctrl-g = normal mode

@phanen
Copy link
Contributor Author

phanen commented May 14, 2025

Wrap defer_fn can make it work. But would it be better to find another approach? I check some old issues e.g. it cause some laggy on wsl.

@ibhagwan
Copy link
Owner

Wrap defer_fn can make it work. But would it be better to find another approach? I check some old issues e.g. it cause some laggy on wsl.

TBH the current approach mostly works, I don’t know of any issues aside from what you wrote in the OP.

phanen added 2 commits May 28, 2025 15:13
```
nvim --headless --clean --server $NVIM --remote-send "<cmd>FzfLua complete_path<cr>"
```
@phanen phanen force-pushed the fix-feed2starti branch from 3aa9530 to 46a0df7 Compare May 28, 2025 07:14
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.

2 participants