airblade/vim-gitgutter

Suggestion: Can autocmd be avoided?

sak96 opened this issue · 18 comments

sak96 commented

What is the latest commit SHA in your installed vim-gitgutter?
52d0066
What vim/nvim version are you on?
VIM - Vi IMproved 9.0 (2022 Jun 28, compiled Aug 21 2022 14:20:23)

There is autocmd which check if gitgutter should run. This tends to update v:shell_error which may cause issue like: vifm/vifm.vim#80.

Not sure if there is easy way to avoid it but it is worth check out.

The autocommands aren't your problem, it's v:shell_error getting set. If two plugins are both executing shell commands via a mechanism like system() or :! there's going to be a conflict over which writes v:shell_error last.

Gitgutter obviously runs git shell commands. Git uses exit codes to indicate outcomes. Vim automatically sets v:shell_error when running shell commands synchronously. However most of the time gitgutter uses jobs, running asynchronously, where exit codes are reported to the job handler not v:shell_error. The only time it runs synchronously is at startup, due to a Vim bug (#619), unless you are using an ancient Vim (you didn't specify your version above) or you have configured gitgutter not to run async.

However in the linked issue gitgutter was responding to a ShellCmdPost autocommand, so it wasn't at startup.

I don't understand why your gitgutter appears to be running synchronously. Please could you set let g:gitgutter_log=1, reproduce the problem, and upload the log file here? It'll be gitgutter.log in the directory where gitgutter is installed.

sak96 commented


==== start log session ====

  0.000037 function <SNR>35_StartVifm[103]..ShellCmdPost Autocommands for "*"..function gitgutter#all[8]..gitgutter#process_buffer[14]..<SNR>117_setup_path[3]..gitgutter#utility#set_repo_path[20]..gitgutter#utility#system[1]:
  0.000037 cd /tmp/temp && git  ls-files -v --error-unmatch --full-name -z -- a.txt

  0.810794 CursorHold Autocommands for "*"..function gitgutter#process_buffer[14]..<SNR>117_setup_path[3]..gitgutter#utility#set_repo_path[20]..gitgutter#utility#system[1]:
  0.810794 cd /tmp/temp && git  ls-files -v --error-unmatch --full-name -z -- a.txt

==== start log session ====

  0.000016 function <SNR>35_StartVifm[103]..ShellCmdPost Autocommands for "*"..function gitgutter#all[8]..gitgutter#process_buffer[14]..<SNR>117_setup_path[3]..gitgutter#utility#set_repo_path[20]..gitgutter#utility#system[1]:
  0.000016 cd /tmp/temp && git  ls-files -v --error-unmatch --full-name -z -- a.txt

  0.905991 CursorHold Autocommands for "*"..function gitgutter#process_buffer[14]..<SNR>117_setup_path[3]..gitgutter#utility#set_repo_path[20]..gitgutter#utility#system[1]:
  0.905991 cd /tmp/temp && git  ls-files -v --error-unmatch --full-name -z -- a.txt

note when i turned on the gitgutter_log i got some failures:


Messages maintainer: Bram Moolenaar <Bram@vim.org>
"/tmp/temp/a.txt" 0L, 0B
Error detected while processing function <lambda>3[1]..gitgutter#process_buffer[14]..<SNR>117_setup_path[3]..gitgutter#utility#set_repo_path[20]..gitgutter#utility#system[1]..gitgutter#debug#log:
line    8:
E930: Cannot use :redir inside execute()
Error detected while processing function <lambda>3[1]..gitgutter#process_buffer[31]..function <lambda>3[1]..gitgutter#process_buffer[23]..script /home/sak/.vim/plugged/vim-gitgutter/autoload/gitgutter/diff.vim[13]..function <SNR>125_git_supports_command_line_config_override[1]..gitgutter#utility#system[1]..gitgutter#debug#log:
line    8:
E930: Cannot use :redir inside execute()
sak96 commented

also note updated the version of vim and gitgutter to allow re-producing.

Plug 'vifm/vifm.vim', {'commit': 'a8393ee7d3a37483e9770b9e849719d8364c299f' } " add vifm support

I don't know why you get E930 when you turn on gitgutter's logging. Or more accurately, I don't know why I don't get it. The logging sends messages to a file like this:

execute 'redir >> '.s:log_file

According to the docs for E930 it's not allowed but it has worked for over a decade. Weird. Update: E930 applies to the execute() function but this code uses the execute ex command. For some reason your vim is interpreting the command as a function – perhaps some bug in Vim 9? You could try prefixing the line above with a colon, i.e. :execute ....

Anyway, I realised that gitgutter executes a system() call when it is loaded initially, to determine whether git supports command-line overrides. I suppose that could be made async.

But more relevantly, your log shows that gitgutter is executing all its shell commands synchronously. Do you have let g:gitgutter_async=0 in your config?

Or do you have an old version of gitgutter which is still getting loaded and conflicting with the new version? You could try :filter /gitgutter/ scriptnames to see what's loaded.

sak96 commented

based on the :filter /gitgutter/ scriptnames it is using ~/.vim/plugged/vim-gitgutter

$ cd ~/.vim/plugged/vim-gitgutter
$ git rev-parse HEAD
52d006682314a353a2ea951a8e443067f1db7eb4
echo g:gitgutter_async

returns 1

sak96 commented


==== start log session ====

  0.000016 function <SNR>35_StartVifm[103]..ShellCmdPost Autocommands for "*"..function gitgutter#all[8]..gitgutter#process_buffer[14]..<SNR>117_setup_path[3]..gitgutter#utility#set_repo_path[20]..gitgutter#utility#system[1]:
  0.000016 cd /tmp/temp && git  ls-files -v --error-unmatch --full-name -z -- a.txt

  1.068629 CursorHold Autocommands for "*"..function gitgutter#process_buffer[14]..<SNR>117_setup_path[3]..gitgutter#utility#set_repo_path[20]..gitgutter#utility#system[1]:
  1.068629 cd /tmp/temp && git  ls-files -v --error-unmatch --full-name -z -- a.txt

  3.577659 function <SNR>35_StartVifm[103]..ShellCmdPost Autocommands for "*"..function gitgutter#all[8]..gitgutter#process_buffer[14]..<SNR>117_setup_path[3]..gitgutter#utility#set_repo_path[20]..gitgutter#utility#system[1]:
  3.577659 cd /tmp/temp && git  ls-files -v --error-unmatch --full-name -z -- a.txt

  4.645264 CursorHold Autocommands for "*"..function gitgutter#process_buffer[14]..<SNR>117_setup_path[3]..gitgutter#utility#set_repo_path[20]..gitgutter#utility#system[1]:
  4.645264 cd /tmp/temp && git  ls-files -v --error-unmatch --full-name -z -- a.txt

==== start log session ====

  0.000027 CursorHold Autocommands for "*"..function gitgutter#process_buffer[14]..<SNR>117_setup_path[3]..gitgutter#utility#set_repo_path[20]..gitgutter#utility#system[1]:
  0.000027 cd /tmp/temp && git  ls-files -v --error-unmatch --full-name -z -- a.txt

  1.413714 CursorHold Autocommands for "*"..function gitgutter#process_buffer[14]..<SNR>117_setup_path[3]..gitgutter#utility#set_repo_path[20]..gitgutter#utility#system[1]:
  1.413714 cd /tmp/temp && git  ls-files -v --error-unmatch --full-name -z -- a.txt

==== start log session ====

  0.000033 function <SNR>35_StartVifm[103]..ShellCmdPost Autocommands for "*"..function gitgutter#all[8]..gitgutter#process_buffer[14]..<SNR>117_setup_path[3]..gitgutter#utility#set_repo_path[20]..gitgutter#utility#system[1]:
  0.000033 cd /tmp/temp && git  ls-files -v --error-unmatch --full-name -z -- a.txt

  1.040018 CursorHold Autocommands for "*"..function gitgutter#process_buffer[14]..<SNR>117_setup_path[3]..gitgutter#utility#set_repo_path[20]..gitgutter#utility#system[1]:
  1.040018 cd /tmp/temp && git  ls-files -v --error-unmatch --full-name -z -- a.txt

still getting issue with even after adding : before execute at suggested line

Messages maintainer: Bram Moolenaar <Bram@vim.org>
"a.txt" 0L, 0B
Error detected while processing function <lambda>3[1]..gitgutter#process_buffer[14]..<SNR>117_setup_path[3]..gitgutter#utility#set_repo_path[20]..gitgutter#utility#system[1]..gitgutter#debug#log:
line    8:
E930: Cannot use :redir inside execute()
Error detected while processing function <lambda>3[1]..gitgutter#process_buffer[31]..function <lambda>3[1]..gitgutter#process_buffer[23]..script /home/sak/.vim/plugged/vim-gitgutter/autoload/gitgutter/diff.vim[13]..function <SNR>125_git_supports_command_line_config_override[1]..gitgutter#utility#system[1]..gitgutter#debug#log:
line    8:
E930: Cannot use :redir inside execute()
Error detected while processing CursorHold Autocommands for "*"..function gitgutter#process_buffer[31]..CursorHold Autocommands for "*"..function gitgutter#process_buffer:
line   23:
E117: Unknown function: gitgutter#diff#run_diff
sak96 commented

Just a FYI

cd /tmp
mkdir temp && cd temp && git init
touch a.txt b.txt
vim a.txt

when i open a.txt i start getting above issue of E930

when i open a.txt i start getting above issue of E930

Is that with or without gitgutter's logging switched on?

What does :echo gitgutter#async#available() produce?

sak96 commented

:echo gitgutter#async#available() produces 0

also

\ (has('patch-7-4-1826') && !has('gui_running')) ||

:echo has('patch-7-4-1826') also produces 0


Is that with or without gitgutter's logging switched on?
with gitgutter logging on.

sak96 commented

as you pointed out the sync part is causing the issue.
if i hard code

return s:available

to

  return 1

then the v:shell_error issue (vifm/vifm.vim#80) disappears.

sak96 commented

echo v:version give 900 which mean the above patch should have been there.

As per help has-patch 900 > 704 and hence :echo has('patch-7-4-1826') should be 1.

That's weird. I'm running Vim 9.0.0065 and :echo has('patch-7-4-1826') gives me 1. What patch level is your Vim 9?

What does :echo has('patch-7.4.1826') give? (I don't think it matters whether the number separators are '.' or '-' but something weird is going on so it's worth checking.)

A workaround would be if v:version >= 800 || (...) but it would be nice to solve the problem.

A couple of recent versions of Vim have changed the way it parses has('patch-...'), making it stricter. E.g. 9.0.0113 (d90f91fe3). Maybe that rejects the dashed version string gitgutter currently uses, and you have this patch?

sak96 commented

help has-patch gives

<							*has-patch*
3.  Beyond a certain version or at a certain version and including a specific
    patch.  The "patch-7.4.248" feature means that the Vim version is 7.5 or
    later, or it is version 7.4 and patch 248 was included.  Example: >
	:if has("patch-7.4.248")
<    Note that it's possible for patch 248 to be omitted even though 249 is
    included.  Only happens when cherry-picking patches.
    Note that this form only works for patch 7.4.237 and later, before that
    you need to check for the patch and the  v:version.  Example (checking
    version 6.2.148 or later): >
	:if v:version > 602 || (v:version == 602 && has("patch148"))

based on this i tried

echo has('patch-7.4.1826') " gives 1 (as per help has-patch example)
echo has('patch-10.4.1826') " gives 0 (to check for neg case)
echo has('patch-7-4-1826') " gives 0 ( to check for what vim-gutter uses)

my noob brain suggests: may be the patches should use . separator instead of - ??

I can't remember why I used dashes 6 years ago, but it has worked until now. Anyway, I have changed the patch version strings to use the conventional format.

Please could you tell me which patches your Vim 9 includes? It's the third line of :version.

sak96 commented

i will raise the pr if that is not a issue ?


Please could you tell me which patches your Vim 9 includes? It's the third line of :version.

VIM - Vi IMproved 9.0 (2022 Jun 28, compiled Aug 21 2022 14:20:23)
Included patches: 1-236

Thank you for telling me your patch version. Evidently somewhere between the patch I'm on (65) and the patch you're on (236) the version string parsing changed. As I mentioned above, it was probably patch 113.

sak96 commented

f19b620 fixes the issue