tmux-plugins / vim-tmux-focus-events

Make terminal vim and tmux work better together.
MIT License
351 stars 23 forks source link

Error detected while processing function FocusGained Autocommands #33

Open mckellygit opened 3 years ago

mckellygit commented 3 years ago

Hi, Thank you for this great plugin. Recently I have been sometimes getting this when starting a new vim -

Error detected while processing function <SNR>58_do_autocmd[3]..FocusGained Autocommands for "*"..function tmux_focus_events#focus_gained:
line    8:

Just wondered if there was a try/catch or some way to fix/avoid this ? thx, -m

bruno- commented 3 years ago

Can you disable other plugins and reproduce it consistently?

mckellygit commented 3 years ago

I'll try. It only started recently. Hard to reproduce reliably, I mean it happens a few times per day but I cannot repro it exactly when I want.

namjul commented 3 years ago

For me this happens when switching back to tmux/vim when I left vim in command mode. I tested with all plugins disabled and had the same behavior.

Error detected while processing function tmux_focus_events#focus_gained:
line    8:
E1155: Cannot define autocommands for ALL events

I am using neovim.

mckellygit commented 3 years ago

ok, I can reproduce it reliably if I hit / or : immediately after starting vim, not waiting for the screen/file loading etc. This fixes it, but I am not sure if its the correct fix -

diff --git a/autoload/tmux_focus_events.vim b/autoload/tmux_focus_events.vim
index 9147b3a..c57a561 100644
--- a/autoload/tmux_focus_events.vim
+++ b/autoload/tmux_focus_events.vim
@@ -29,11 +29,14 @@ function! tmux_focus_events#focus_gained()
     return
   endif
   if <SID>cursor_in_cmd_line()
-    augroup focus_gained_checktime
-      au!
-      " perform checktime ASAP when outside cmd line
-      au * * call <SID>delayed_checktime()
-    augroup END
+    try
+      augroup focus_gained_checktime
+        au!
+        " perform checktime ASAP when outside cmd line
+        au * * call <SID>delayed_checktime()
+      augroup END
+    catch /E1155/
+    endtry

I just added a try/catch for E1155 around the focus_gained_checktime autocmd. thx, -m

bruno- commented 3 years ago

We can add try/catch there but that would probably mean you would NOT get this autocommand installed. The Focus lost/gained events would not trigger is some cases in that vim instance.

Btw. are you on neovim? I can't get any info for E1155 with vanilla vim.

mckellygit commented 3 years ago

Hi, Vim source shows - INIT(= N_("E1155: Cannot define autocommands for ALL events")); So it looks the same for both vim and neovim. I'll try to find a different way to install this autocmd.

mckellygit commented 3 years ago

Total hack, but something like this seems to work -

diff --git a/autoload/tmux_focus_events.vim b/autoload/tmux_focus_events.vim
index 9147b3a..4272c9a 100644
--- a/autoload/tmux_focus_events.vim
+++ b/autoload/tmux_focus_events.vim
@@ -24,16 +24,32 @@ function! s:delayed_checktime()
   endtry
 endfunction

-function! tmux_focus_events#focus_gained()
-  if !&autoread
-    return
-  endif
-  if <SID>cursor_in_cmd_line()
+function! s:RetryAU(au_timer)
+  try
     augroup focus_gained_checktime
       au!
       " perform checktime ASAP when outside cmd line
       au * * call <SID>delayed_checktime()
     augroup END
+  catch /E1155/
+    let au_timer = timer_start(100, function('s:RetryAU'))
+  endtry
+endfunction
+
+function! tmux_focus_events#focus_gained()
+  if !&autoread
+    return
+  endif
+  if <SID>cursor_in_cmd_line()
+    try
+      augroup focus_gained_checktime
+        au!
+        " perform checktime ASAP when outside cmd line
+        au * * call <SID>delayed_checktime()
+      augroup END
+    catch /E1155/
+      let au_timer = timer_start(100, function('s:RetryAU'))
+    endtry
   else
     silent checktime
   endif
mckellygit commented 3 years ago

It could be simplified to just call s:RetryAU(0) in focus_gained() Perhaps something like this -

function! s:RetryAU(au_timer)
  try
    augroup focus_gained_checktime
      au!
      " perform checktime ASAP when outside cmd line
      au * * call <SID>delayed_checktime()
    augroup END
  catch /E1155/
    let au_timer = timer_start(50, function('s:RetryAU'))
  endtry
endfunction

function! tmux_focus_events#focus_gained()
  if !&autoread
    return
  endif
  if <SID>cursor_in_cmd_line()
    call <SID>RetryAU(0)
  else
    silent checktime
  endif
endfunction
bruno- commented 3 years ago

Looks good, wanna submit a PR?

mckellygit commented 3 years ago

ok, sure, will do in a few. thx, -m

mckellygit commented 3 years ago

PR https://github.com/tmux-plugins/vim-tmux-focus-events/pull/35 thx again, -m

mckellygit commented 3 years ago

We need to revert this PR https://github.com/tmux-plugins/vim-tmux-focus-events/pull/35 And come up with a better solution.

mckellygit commented 3 years ago

Hi, Thanks for reverting my bad PR, sorry about that. This seems to work and I confirmed delayed_checktime() is getting called once in vim and nvim, but I am shy about another PR without more review and testing. Still not sure I understand the add the autocmd and then remove it step.

      au CmdLineEnter,CmdLineChanged * call <SID>delayed_checktime()

thx, -m

mckellygit commented 3 years ago

This change seems ok to me so far ... Anyone else have ideas or comments ? thx, -m

ddickstein commented 3 years ago

I've had decent luck with autocmd CmdLineLeave * call timer_start(0, { _ -> expr }) for running expr after the user leaves the command line. Maybe that could work here (in this case, expr would be s:delayed_checktime())?