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

Neovim occasional hang/freeze when using ctrl-c to exit fzf-lua #1091

Open
kaiphat opened this issue Mar 19, 2024 · 44 comments
Open

Neovim occasional hang/freeze when using ctrl-c to exit fzf-lua #1091

kaiphat opened this issue Mar 19, 2024 · 44 comments
Labels
upstream An issue upstream (neovim, fzf, etc)

Comments

@kaiphat
Copy link

kaiphat commented Mar 19, 2024

Neovim often totally stucks when i use fzf-lua. How i can debug it and find a reason?

@ibhagwan
Copy link
Owner

ibhagwan commented Mar 19, 2024

Can you elaborate more on the circumstances of the hang? Are you using <C-c> by any chance?

There is a known issue which I opened upstream when using <C-c> while lua code is running which makes neovim hang: neovim/neovim#20726

That’s the reason why I hard mapped <C-c> to <Esc> until this is resolved.

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

Lines 237 to 241 in 5104ac1

if vim.keymap then
vim.keymap.set("t", "<C-c>", "<Esc>", { buffer = 0 })
else
vim.api.nvim_buf_set_keymap(0, "t", "<C-c>", "<Esc>", { noremap = true })
end

You can also read my debugging comments and process in the comments:

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

Lines 194 to 236 in 5104ac1

-- I'm not sure why this happens (probably a neovim bug) but when pressing
-- <C-c> in quick successsion immediately after opening the window neovim
-- hangs the CPU at 100% at the last `coroutine.yield` before returning from
-- this function. At this point it seems that the fzf subprocess was started
-- and killed but `on_exit` is never called. In order to avoid calling `yield`
-- I tried checking the job/coroutine status in different ways:
-- * coroutine.status(co): always returns 'running'
-- * vim.fn.job_pid: always returns the corrent pid (even if it doesn't
-- exist anymore)
-- * vim.fn.jobwait({job_pid}, 0): always returns '-1' (even when looping
-- with 'vim.defer_fn(fn, 100)')
-- * uv.os_priority(job_pid): always returns '0'
-- `sudo strace -s 99 -ffp <pid> when neovim is stuck:
-- [pid 27433] <... epoll_wait resumed>[{events=EPOLLIN, data={u32=18, u64=18}}], 1024, -1) = 1
-- [pid 27432] <... write resumed>) = 8
-- [pid 27433] read(18, "\1\0\0\0\0\0\0\0", 1024) = 8
-- [pid 27432] epoll_wait(9, <unfinished ...>
-- [pid 27433] epoll_wait(15, <unfinished ...>
-- [pid 27432] <... epoll_wait resumed>[], 1024, 0) = 0
-- [pid 27432] epoll_wait(9, [], 1024, 0) = 0
-- [pid 27432] epoll_wait(9, [], 1024, 0) = 0
-- [pid 27432] epoll_wait(9, [], 1024, 0) = 0
-- [pid 27432] write(32, "\3", 1) = 1
-- [pid 27432] write(18, "\1\0\0\0\0\0\0\0", 8 <unfinished ...>
-- [pid 27433] <... epoll_wait resumed>[{events=EPOLLIN, data={u32=18, u64=18}}], 1024, -1) = 1
-- [pid 27432] <... write resumed>) = 8
-- [pid 27433] read(18, "\1\0\0\0\0\0\0\0", 1024) = 8
-- [pid 27432] epoll_wait(9, <unfinished ...>
-- [pid 27433] epoll_wait(15, <unfinished ...>
-- [pid 27432] <... epoll_wait resumed>[], 1024, 0) = 0
-- [pid 27432] epoll_wait(9, [], 1024, 0) = 0
-- [pid 27432] epoll_wait(9, [], 1024, 0) = 0
-- [pid 27432] epoll_wait(9, [], 1024, 0) = 0
-- [pid 27432] write(32, "\3", 1) = 1
-- [pid 27432] write(18, "\1\0\0\0\0\0\0\0", 8 <unfinished ...>
--
-- As a workaround we map buffer <C-c> to <Esc> for the fzf buffer
-- `vim.keymap.set` to avoid breaking compatibility with older neovim versions
--
-- Removed as an experiment since the removal of the `save_query` code
-- that was running on WinLeave which seems to make the `<C-c>` issue
-- better or even non-existent? RESTORED AGAIN
--

@kaiphat
Copy link
Author

kaiphat commented Mar 19, 2024

I think yes, but maybe there is another case, i'm going to observer. Thank you!

Sometimes i see message like Job still running. It connects with this problem?

@ibhagwan
Copy link
Owner

ibhagwan commented Mar 19, 2024

A good start would be some details on your setup:

  • Linux/Mac/Win?
  • When does it get stuck?
  • When opening the interface or closing?
  • Any specific picker or all?

Sometimes i see message like Job still running. It connects with this problem?

Where does the message appear? :messages?

@kaiphat
Copy link
Author

kaiphat commented Mar 19, 2024

Mac m1, fish shell and tmux

See, i tried to save with wqa and get error.
image
In buffers:
image

When nvim completely stucked and fzf was opened (in this case i can't close nvim and i just close tmux pane). After that i open nvim one more time and press <C-o> i see the same buffer sh-3.2$.

@kaiphat
Copy link
Author

kaiphat commented Mar 19, 2024

Also sometimes i got weird behaviour when fzf opened and i resize pane in tmux.

@ibhagwan
Copy link
Owner

See, i tried to save with wqa and get error.

This could not be related to fzf-lua as the code doesn’t have any auto commands running outside fzf-lua’s own buffers/windows.

When nvim completely stucked and fzf was opened (in this case i can't close nvim and i just close tmux pane). After that i open nvim one more time and press i see the same buffer sh-3.2$.

Does this happen on other buffer types or only on terminal buffers?

Also sometimes i got weird behaviour when fzf opened and i resize pane in tmux.

Can you describe “weird behavior”?

@ibhagwan
Copy link
Owner

ibhagwan commented Mar 20, 2024

When nvim completely stucked and fzf was opened (in this case i can't close nvim and i just close tmux pane). After that i open nvim one more time and press i see the same buffer sh-3.2$.

Another question, when you’re stuck when fzf-lua is open is it possible you exited to normal mode by mistake (some keybind)? What happens if you press i or : at that stage?

When neovim is stuck if you look at the processes is neovim taking 100% CPU?

@kaiphat
Copy link
Author

kaiphat commented Mar 20, 2024

when you’re stuck when fzf-lua is open is it possible you exited to normal mode

No, nvim doesn't respond at all. Screenshot below after <C-c>. Proc isn't high loaded.
image

@kaiphat
Copy link
Author

kaiphat commented Mar 20, 2024

And after <C-o> in new nvim instance.
image

@kaiphat
Copy link
Author

kaiphat commented Mar 20, 2024

Else
image

@kaiphat
Copy link
Author

kaiphat commented Mar 20, 2024

ilyapu           17502   0.0  0.2 409860576  72240 s005  S+    7:40PM   0:00.28 fzf --height 100% --ansi --preview VIMRUNTIME="/opt/homebrew/Cellar/neovim/0.9.5/share/nvim/runtime" "/opt/homebrew/Cellar/neovim/0.9.5/bin/nvim" -n --headless --clean --cmd "lua vim.g.did_load_filetypes=1; loadfile([[/Users/ilyapu/.local/share/nvim/lazy/fzf-lua/lua/fzf-lua/shell_helper.lua]])().rpc_nvim_exec_lua({fzf_lua_server=[[/var/folders/m5/qpxq89051c76_ydvxzcd93sm0000gn/T/nvim.ilyapu/4Swf1U/fzf-lua.1710960015.15838.1]], fnc_id=5 })" -- {} --preview-window nohidden:right:0 --disabled --expect ctrl-s,esc,alt-l,ctrl-q,ctrl-g,ctrl-t,ctrl-v,ctrl-c --print-query --header   --multi --bind alt-a:toggle-all,ctrl-e:end-of-line,ctrl-f:half-page-down,ctrl-z:abort,ctrl-u:preview-page-up,zero:execute-silent(mkdir "/var/folders/m5/qpxq89051c76_ydvxzcd93sm0000gn/T/nvim.ilyapu/4Swf1U/21" && VIMRUNTIME="/opt/homebrew/Cellar/neovim/0.9.5/share/nvim/runtime" "/opt/homebrew/Cellar/neovim/0.9.5/bin/nvim" -n --headless --clean --cmd "lua vim.g.did_load_filetypes=1; loadfile([[/Users/ilyapu/.local/share/nvim/lazy/fzf-lua/lua/fzf-lua/shell_helper.lua]])().rpc_nvim_exec_lua({fzf_lua_server=[[/var/folders/m5/qpxq89051c76_ydvxzcd93sm0000gn/T/nvim.ilyapu/4Swf1U/fzf-lua.1710960015.15838.1]], fnc_id=6 })" -- ),ctrl-d:preview-page-down,f4:toggle-preview,ctrl-a:beginning-of-line,f3:toggle-preview-wrap,ctrl-b:half-page-up --color hl+:#85c1dd,fg:#737995,hl:#85c1dd,bg+:#51576e,query:#85c1dd,pointer:#85c1dd,fg+:#737995,info:#85c1dd,gutter:-1 --info inline-right --history /Users/ilyapu/.local/share/nvim/fzf-lua-grep-history --cycle --query  --no-separator --no-scrollbar --marker ❯ --pointer   --prompt   ❯  --border none --layout reverse --bind=change:first --bind=change:reload:VIMRUNTIME="/opt/homebrew/Cellar/neovim/0.9.5/share/nvim/runtime" "/opt/homebrew/Cellar/neovim/0.9.5/bin/nvim" -n --headless --clean --cmd "lua vim.g.did_load_filetypes=1; loadfile([[/Users/ilyapu/.local/share/nvim/lazy/fzf-lua/lua/fzf-lua/libuv.lua]])().spawn_stdio([==[e2FyZ3ZfZXhwciA9IHRydWUsIGdsb2JfZmxhZyA9ICItLWlnbG9iIiwgY21kID0gInJnIC0tY29sdW1uIC0tbm8taGVhZGluZyAtLWNvbG9yPWFsd2F5cyAtLXNtYXJ0LWNhc2UgLS1tYXgtY29sdW1ucz00MDk2IC0tdHJpbSAtZz0hZGF0YS8gLWc9IS5kYXRhLyAtZz0hdGVzdC8gLWc9IXRlc3RzLyAtZz0hKiovX190ZXN0c19fLyogLWc9ISoqL19fbW9ja3NfXy8qIC1nPSFwYWNrYWdlLWxvY2suanNvbiAtZz0hKi5sb2cgLWc9IS5naXRpZ25vcmUgLWc9ISoubWQgLWc9IS5naXQvIC1nPSFkaXN0LyAtZz0hbm9kZV9tb2R1bGVzLyAtZz0hYnVpbGQvIC1nPSFkb2NrZXJfdm9sdW1lc19kYXRhLyAtZz0heWFybi5sb2NrIC1nPSFDYXJnby5sb2NrIC1nPSFjb3ZlcmFnZS8gLWUge2FyZ3Z6fSAiLCByZ19nbG9iID0gdHJ1ZSwgZyA9IHtfZnpmX2x1YV9zZXJ2ZXIgPSAiL3Zhci9mb2xkZXJzL201L3FweHE4OTA1MWM3Nl95ZHZ4emNkOTNzbTAwMDBnbi9UL252aW0uaWx5YXB1LzRTd2YxVS9memYtbHVhLjE3MTA5NjAwMTUuMTU4MzguMSIsIF9kZXZpY29uc19wYXRoID0gIi9Vc2Vycy9pbHlhcHUvLmxvY2FsL3NoYXJlL252aW0vbGF6eS9udmltLXdlYi1kZXZpY29ucy8ifSwgY29sb3JfaWNvbnMgPSB0cnVlLCBmaWxlX2ljb25zID0gdHJ1ZSwgZ2l0X2ljb25zID0gZmFsc2UsIGdsb2Jfc2VwYXJhdG9yID0gIiVzJS0lLSJ9]==],[==[cmV0dXJuIHJlcXVpcmUoIm1ha2VfZW50cnkiKS5maWxl]==],[==[cmV0dXJuIHJlcXVpcmUoIm1ha2VfZW50cnkiKS5wcmVwcm9jZXNz]==])" -- {q} 2>&1 || true
ilyapu           17501   0.0  0.0 408627440   1808 s005  Ss+   7:40PM   0:00.01 /bin/sh -c fzf --height "100%" --ansi --preview 'VIMRUNTIME="/opt/homebrew/Cellar/neovim/0.9.5/share/nvim/runtime" "/opt/homebrew/Cellar/neovim/0.9.5/bin/nvim" -n --headless --clean --cmd "lua vim.g.did_load_filetypes=1; loadfile([[/Users/ilyapu/.local/share/nvim/lazy/fzf-lua/lua/fzf-lua/shell_helper.lua]])().rpc_nvim_exec_lua({fzf_lua_server=[[/var/folders/m5/qpxq89051c76_ydvxzcd93sm0000gn/T/nvim.ilyapu/4Swf1U/fzf-lua.1710960015.15838.1]], fnc_id=5 })" -- {}' --preview-window "nohidden:right:0" --disabled --expect "ctrl-s,esc,alt-l,ctrl-q,ctrl-g,ctrl-t,ctrl-v,ctrl-c" --print-query --header " " --multi --bind 'alt-a:toggle-all,ctrl-e:end-of-line,ctrl-f:half-page-down,ctrl-z:abort,ctrl-u:preview-page-up,zero:execute-silent(mkdir "/var/folders/m5/qpxq89051c76_ydvxzcd93sm0000gn/T/nvim.ilyapu/4Swf1U/21" && VIMRUNTIME="/opt/homebrew/Cellar/neovim/0.9.5/share/nvim/runtime" "/opt/homebrew/Cellar/neovim/0.9.5/bin/nvim" -n --headless --clean --cmd "lua vim.g.did_load_filetypes=1; loadfile([[/Users/ilyapu/.local/share/nvim/lazy/fzf-lua/lua/fzf-lua/shell_helper.lua]])().rpc_nvim_exec_lua({fzf_lua_server=[[/var/folders/m5/qpxq89051c76_ydvxzcd93sm0000gn/T/nvim.ilyapu/4Swf1U/fzf-lua.1710960015.15838.1]], fnc_id=6 })" -- ),ctrl-d:preview-page-down,f4:toggle-preview,ctrl-a:beginning-of-line,f3:toggle-preview-wrap,ctrl-b:half-page-up' --color "hl+:#85c1dd,fg:#737995,hl:#85c1dd,bg+:#51576e,query:#85c1dd,pointer:#85c1dd,fg+:#737995,info:#85c1dd,gutter:-1" --info "inline-right" --history "/Users/ilyapu/.local/share/nvim/fzf-lua-grep-history" --cycle --query "" --no-separator --no-scrollbar --marker "❯" --pointer " " --prompt "  ❯ " --border "none" --layout "reverse" --bind=change:first --bind='change:reload:VIMRUNTIME="/opt/homebrew/Cellar/neovim/0.9.5/share/nvim/runtime" "/opt/homebrew/Cellar/neovim/0.9.5/bin/nvim" -n --headless --clean --cmd "lua vim.g.did_load_filetypes=1; loadfile([[/Users/ilyapu/.local/share/nvim/lazy/fzf-lua/lua/fzf-lua/libuv.lua]])().spawn_stdio([==[e2FyZ3ZfZXhwciA9IHRydWUsIGdsb2JfZmxhZyA9ICItLWlnbG9iIiwgY21kID0gInJnIC0tY29sdW1uIC0tbm8taGVhZGluZyAtLWNvbG9yPWFsd2F5cyAtLXNtYXJ0LWNhc2UgLS1tYXgtY29sdW1ucz00MDk2IC0tdHJpbSAtZz0hZGF0YS8gLWc9IS5kYXRhLyAtZz0hdGVzdC8gLWc9IXRlc3RzLyAtZz0hKiovX190ZXN0c19fLyogLWc9ISoqL19fbW9ja3NfXy8qIC1nPSFwYWNrYWdlLWxvY2suanNvbiAtZz0hKi5sb2cgLWc9IS5naXRpZ25vcmUgLWc9ISoubWQgLWc9IS5naXQvIC1nPSFkaXN0LyAtZz0hbm9kZV9tb2R1bGVzLyAtZz0hYnVpbGQvIC1nPSFkb2NrZXJfdm9sdW1lc19kYXRhLyAtZz0heWFybi5sb2NrIC1nPSFDYXJnby5sb2NrIC1nPSFjb3ZlcmFnZS8gLWUge2FyZ3Z6fSAiLCByZ19nbG9iID0gdHJ1ZSwgZyA9IHtfZnpmX2x1YV9zZXJ2ZXIgPSAiL3Zhci9mb2xkZXJzL201L3FweHE4OTA1MWM3Nl95ZHZ4emNkOTNzbTAwMDBnbi9UL252aW0uaWx5YXB1LzRTd2YxVS9memYtbHVhLjE3MTA5NjAwMTUuMTU4MzguMSIsIF9kZXZpY29uc19wYXRoID0gIi9Vc2Vycy9pbHlhcHUvLmxvY2FsL3NoYXJlL252aW0vbGF6eS9udmltLXdlYi1kZXZpY29ucy8ifSwgY29sb3JfaWNvbnMgPSB0cnVlLCBmaWxlX2ljb25zID0gdHJ1ZSwgZ2l0X2ljb25zID0gZmFsc2UsIGdsb2Jfc2VwYXJhdG9yID0gIiVzJS0lLSJ9]==],[==[cmV0dXJuIHJlcXVpcmUoIm1ha2VfZW50cnkiKS5maWxl]==],[==[cmV0dXJuIHJlcXVpcmUoIm1ha2VfZW50cnkiKS5wcmVwcm9jZXNz]==])" -- {q} 2>&1 || true' > "/var/folders/m5/qpxq89051c76_ydvxzcd93sm0000gn/T/nvim.ilyapu/4Swf1U/23"

@ibhagwan
Copy link
Owner

Screenshot below after <C-c>

So can we say safely all of these are related to ctrl-c? If so we might have to wait for the upstream to be fixed.

@kaiphat
Copy link
Author

kaiphat commented Mar 20, 2024

I noticed one more thing. Every time when i open fzf i got this log:

ERR 2024-03-20T20:42:45.213 nvim.86900.0/c vim_gettempdir:5374: tempdir disappeared (antivirus or broken cleanup job?): /var/folders/m5/qpxq89051c76_ydvxzcd93sm0000gn/T/nvim.ilyapu/t2fYyq/

@ibhagwan
Copy link
Owner

I noticed one more thing. Every time when i open fzf i got this log:

ERR 2024-03-20T20:42:45.213 nvim.86900.0/c vim_gettempdir:5374: tempdir disappeared (antivirus or broken cleanup job?): /var/folders/m5/qpxq89051c76_ydvxzcd93sm0000gn/T/nvim.ilyapu/t2fYyq/

You mean when you open fzf-lua or fzf in the shell? Where exactly does this message appear?

@kaiphat
Copy link
Author

kaiphat commented Mar 20, 2024

Fzf-lua sure

Where exactly does this message appear?

here -> nvim ~/.local/state/nvim/log

@ibhagwan
Copy link
Owner

Fzf-lua sure

Where exactly does this message appear?

here -> nvim ~/.local/state/nvim/log

I’ll check but that might be totally normal, the headless wrapper deletes the temp dir at startup as it doesn’t need it, otherwise terminating fzf commands early may leave a lingering temp dir.

@kaiphat
Copy link
Author

kaiphat commented Mar 20, 2024

Screen.Recording.2024-03-20.at.21.00.30.mov

@ibhagwan
Copy link
Owner

ibhagwan commented Mar 20, 2024

I’ll check but that might be totally normal, the headless wrapper deletes the temp dir at startup as it doesn’t need it, otherwise terminating fzf commands early may leave a lingering temp dir.

Ok, so the temp dir error is ok, it’s due to the above.

@ibhagwan
Copy link
Owner

ibhagwan commented Mar 20, 2024

Quite honestly @kaiphat, if it’s just happening on ctrl-c, there is not much I can do until neovim/neovim#20726 gets fixed.

Try using Esc / Ctrl-q to exit fzf (instead of ctrl-c), if it doesn’t happen then it’s pretty much the same issue.

@ibhagwan
Copy link
Owner

Btw, here’s the section that deletes the temp dir in the wrapper (due to #329):

-- due to 'os.exit' neovim doesn't delete the temporary
-- directory, save it so we can delete prior to exit (#329)
-- NOTE: opted to delete the temp dir at the start due to:
-- (1) spawn_stdio doesn't need a temp directory
-- (2) avoid dangling temp dirs on process kill (i.e. live_grep)
local tmpdir = vim.fn.fnamemodify(vim.fn.tempname(), ":h")
if tmpdir and #tmpdir > 0 then
vim.fn.delete(tmpdir, "rf")
-- io.stdout:write("[DEBUG]: "..tmpdir.."\n")
end

@ibhagwan
Copy link
Owner

I’f you tell me this is for sure only when you press <C-c>, maybe I can attempt to setup a keymap that kills the process and exits, but even so, this seems to be happening in your system more than expected, the upstream bug happens pretty rarely.

@kaiphat
Copy link
Author

kaiphat commented Mar 21, 2024

Ok, so the temp dir error is ok, it’s due to the above.

Even if it's valid behaviour, i think it shouldn't spam to nvim logs.

@kaiphat
Copy link
Author

kaiphat commented Mar 21, 2024

I’f you tell me this is for sure only when you press , maybe I can attempt to setup a keymap that kills the process and exits, but even so, this seems to be happening in your system more than expected, the upstream bug happens pretty rarely.

I'll observe and try to remap.

@kaiphat
Copy link
Author

kaiphat commented Mar 21, 2024

Btw, here’s the section that deletes the temp dir in the wrapper (due to #329):

-- due to 'os.exit' neovim doesn't delete the temporary
-- directory, save it so we can delete prior to exit (#329)
-- NOTE: opted to delete the temp dir at the start due to:
-- (1) spawn_stdio doesn't need a temp directory
-- (2) avoid dangling temp dirs on process kill (i.e. live_grep)
local tmpdir = vim.fn.fnamemodify(vim.fn.tempname(), ":h")
if tmpdir and #tmpdir > 0 then
vim.fn.delete(tmpdir, "rf")
-- io.stdout:write("[DEBUG]: "..tmpdir.."\n")
end

This code is executed once, on start, isn't it?

@ibhagwan
Copy link
Owner

Ok, so the temp dir error is ok, it’s due to the above.

Even if it's valid behaviour, i think it shouldn't spam to nvim logs.

I don’t think this can be avoided, the message comes from an internal monitor in neovim and cannot be disabled.

@ibhagwan
Copy link
Owner

ibhagwan commented Mar 21, 2024

This code is executed once, on start, isn't it?

Nope, this code is executed with every command that uses the headless wrapper, say you’re running files, the fd … command will be run inside an external neovim process with additional lua code to add the icons, etc.

Basically every command that has multiprocess=true in the defaults will execute this code when fzf-lua interface is opened, that’s how you get decent performance and lag free UI, by using an external process.

This is what spawns the wrapper:

M.wrap_spawn_stdio = function(opts, fn_transform, fn_preprocess)
assert(opts and type(opts) == "string")
assert(not fn_transform or type(fn_transform) == "string")
local nvim_bin = os.getenv("FZF_LUA_NVIM_BIN") or vim.v.progpath
local nvim_runtime = os.getenv("FZF_LUA_NVIM_BIN") and ""
or string.format(
_is_win and [[set VIMRUNTIME=%s& ]] or "VIMRUNTIME=%s ",
_is_win and vim.fs.normalize(vim.env.VIMRUNTIME) or M.shellescape(vim.env.VIMRUNTIME)
)
local lua_cmd = ("lua vim.g.did_load_filetypes=1; loadfile([[%s]])().spawn_stdio(%s,%s,%s)")
:format(
_is_win and vim.fs.normalize(__FILE__) or __FILE__,
opts, fn_transform, fn_preprocess
)
local cmd_str = ("%s%s -n --headless --clean --cmd %s"):format(
nvim_runtime,
M.shellescape(_is_win and vim.fs.normalize(nvim_bin) or nvim_bin),
M.shellescape(lua_cmd)
)
return cmd_str
end

@ibhagwan
Copy link
Owner

I'll observe and try to remap.

Let me know your findings, the more info you have the more we can potentially find a workaround for this issue.

@ibhagwan
Copy link
Owner

@kaiphat, I rebased the trace branch, with this branch you can run:

require("fzf-lua").setup({
  debug_tracelog = "~/fzf-lua-trace.log",
  -- rest of your config
})

Note that:

  • This is only for debugging, this will slow down your neovim significantly as every lua function call is written to the log
  • The trace log will be reset with each neovim restart

The next time you can reproduce the freeze we can look in the trace log and see which lines of code are run right before the freeze.

@ibhagwan ibhagwan added bug Something isn't working upstream An issue upstream (neovim, fzf, etc) labels Mar 21, 2024
@ibhagwan ibhagwan changed the title [question] Can i enabled debug mode? Neovim occasional hang/freeze when using ctrl-c to exit fzf-lua Mar 21, 2024
@ibhagwan
Copy link
Owner

ibhagwan commented Mar 21, 2024

Another thing worth trying found in the replies of the upsream issue I opened is disabling fold by expr for terminal buffers, try the below and lmk if that helps?

autocmd TermOpen * setlocal foldmethod=manual

Actually scrap that, I added that in the latest commit as a potential workaround as there's no downside to setting foldmethod=manual for the fzf buffer, so try 1df84a4 and lmk if that helps?

@ibhagwan
Copy link
Owner

@kaiphat, there’s a good chance the latest commit 1df84a4 will solve your issue, I took a look in your dotfiles and you’re using foldexpr which according to the upstream is a major trigger for this issue:
https://github.com/kaiphat/dotfiles/blob/4ac217099896aee462cee23050e954bdd42f044f/nvim/lua/options.lua#L113-L114

wo.foldmethod = 'expr'
wo.foldexpr = 'nvim_treesitter#foldexpr()'

Please update to the latest and lmk if this is resolved?

@kaiphat
Copy link
Author

kaiphat commented Mar 22, 2024

You are unbelievable good:) Thank you, i'll try

@ibhagwan
Copy link
Owner

You are unbelievable good:) Thank you, i'll try

Ty for the kinds words @kaiphat, now let’s hope I’m right :)

@ibhagwan
Copy link
Owner

Following your comment in #1096 (comment)

The freeze might also be triggered nvim-cmp, I wonder why is nvim-cmp running inside the fzf buffer?

@ibhagwan
Copy link
Owner

I don’t think this is a cmp bug but this confirm it’s the same upstream issue, the lines of code from your debug log point to the same on_key event from the original bug:
https://github.com/hrsh7th/nvim-cmp/blob/630cdf7d547c4461ef6d7362c3794a08abfad4fb/plugin/cmp.lua#L45-L53

If you read my original post in neovim/neovim#20726 you can see similar trace log and the code looping the on_key event.

I can look into ways of running debug.sethook on main branch (what enables the trace log), detecting a freeze and a potential unlock by killing the process but (a) that may or may not work and (b) is a terrible hack with potential performance impact.

I will look into it nonetheless but your findings confirm the same upstream issue.

@ibhagwan ibhagwan removed the bug Something isn't working label Mar 22, 2024
@ibhagwan
Copy link
Owner

@kaiphat, I got the idea from your logs to hook the on_key callback and updated the trace branch, you can now add:

require("fzf-lua").setup({
  debug_tracelog = "~/fzf-lua-trace.log",
  nvim_freeze_workaround = true,
})

Enabling this will simply print the pressed key to the :messages stream with a timestamp:

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

Lines 215 to 222 in d6b42bb

if opts.nvim_freeze_workaround and vim.on_key then
ns_id = vim.api.nvim_create_namespace("fzf-lua")
if tonumber(ns_id) then
vim.on_key(function(key)
print("on_key:", os.date(), key)
end, ns_id)
end
end

If you can get it to freeze and our on_key code is still called I can attempt to kill the job and see if that unfreezes neovim, since on_key is only called on key press the perf impact of this should be acceptable so I’m willing to explore this.

Once you get it to freeze, see if the timestamp in the messages (under the cmd line) progresses and also if the debug trace log shows fzf-lua (instead of nvim-cmp in your previous log).

@ibhagwan
Copy link
Owner

ibhagwan commented Mar 23, 2024

@kaiphat, scrap my last comment, I implemented the logic to kill the job if we're stuck in a loop, let's hope this can solve your problem until the upstream is fixed, all you need is the nvim_freeze_workaround = true variable (although you can enable the trace log as well):

require("fzf-lua").setup({
  nvim_freeze_workaround = true,
})

For now this also logs the initial ctrl-c but if this works properly we'll remove that message, after pressing ctr-c you'll see this message:

[Fzf-lua] ctrl-c recieved for job 123 [pid:16840]...

If the process fails to terminate and goes into a loop, we'll hopefully get to this part of the code that terminates the process and if we're lucky also end the loop without any reprucussions :-)

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

Lines 224 to 231 in e77207c

else
sigint_recieved = sigint_recieved + 1
utils.warn(string.format(
"%s: ctrl-c seen %d times, terminating job %d [pid:%d]...",
os.date(), sigint_recieved, chan_id, pid))
vim.fn.jobstop(chan_id)
libuv.process_kill(pid)
end

The message from line 227 wll be printed to :messages as a warning, if you no longer get the freeze but you see this warning the workaround suceeded.

In my testing I managed to get to that part and it suceeded :-)
image

@kaiphat
Copy link
Author

kaiphat commented Mar 23, 2024

Is it trace branch?

@ibhagwan
Copy link
Owner

Is it trace branch?

Yes

@ibhagwan
Copy link
Owner

@kaiphat, latest commit 25da40e added an option to control the verbosity level of the ctrl-c keypresses:

require("fzf-lua").setup({
  -- 0: silent mode, no messages will be displayed
  -- 1: display the message only if process kill workaround is applied
  -- 2|true, display all `ctrl-c` keypresses (on normal fzf-lua UI close)
  -- I'm using `1` for testing so I can see the message only if proccess was required to be killed
  nvim_freeze_workaround = 1,
})

@ibhagwan
Copy link
Owner

ibhagwan commented Mar 23, 2024

I found out that killing the process isn't getting neovim out of the loop as the issue is deeper inside neovim, it seems that raising a lua error does interrupt the lua execution, I guess it's preferable to have an annoying error than a freeze, I can live with that if this turns out to be the solution until the upstream is fixed.

Update to af2c0fa (on trace branch) and when you're supposed to freeze you'll see this instead:
image

@kaiphat
Copy link
Author

kaiphat commented Apr 19, 2024

I've came back:) There were a lot of problems)

I checkouted to trace branch yesterday. Was freezed several times, but didn't see this message at all.

@kaiphat
Copy link
Author

kaiphat commented Apr 19, 2024

Also i noticed, that sometimes when i open fzf popup i am in normal mode. And if i do resume after that i see something like this.
image

@ibhagwan
Copy link
Owner

I don’t think the workaround in this thread will work, after debugging neovim with gdb, the issue is deeper, something appears to happen (my guess is the broke pipe signal to the term) that causes neovim to never clear the SIGINT and therefore it keeps thinking it received ctrl-c, not much I can do from fzf-lua’s end until the upstream is fixed.

@kaiphat
Copy link
Author

kaiphat commented May 22, 2024

I completely changed mind and currently use <C-e> instead of <C-c>. And i don't have any problem:)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
upstream An issue upstream (neovim, fzf, etc)
Projects
None yet
Development

No branches or pull requests

2 participants