This is similar to #1035. I'm experiencing heavy slowdown of cursor movement when editing files in a Mercurial repository with vim-lawrencium installed in parallel with vim-airline. Slowdown increases when the repository is on a network path and more when the Mercurial mq extension is not enabled.
My debugging effort (via vim function profiling) has pinned down the issue in these locations:
Here fnamemodify(resolve(@%), ":p:h") is called effectively on every cursor move, and though not _terribly_ slow, it takes a bit of time. Even when exiting the function directly after line 143, cursor movement still remains sluggish - this is caused by fnamemodify().
Since the filename does not change often during the lifetime of the buffer, I would suggest using a buffer-level variable b:path and an autocmd to update it at the appropriate times. Doing this showed noticeable improvement for me.
The bigger contributor to slowness is this call {s:vcs_config[vcs].update_branch}(l:path), which calls into:
which in turn calls hg qtop - again, on every cursor move. When the mq extension is not enabled, this slows down hg's response (hg: unknown command 'qtop') and the call is useless in this case on top of that. I suppose even with mq enabled this is not a call that needs to be done quite that often.
For now I'm exiting the function after line 125, before the call to hg qtop is made, which brings editing speed back to acceptable levels. But in general, multiple things come to mind:
mq supportmq extension by probing hg help, setting the flag accordinglycursormovedhg at all - this is what lawrencium does for many things, too.
VIM - Vi IMproved 8.0 - click to expand full details
VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Sep 12 2016 22:10:00)
MS-Windows 32-bit console version
Included patches: 1-3
Compiled by appveyor@APPVYR-WIN
Huge version without GUI. Features included (+) or not (-):
+acl +cursorbind -hangul_input -mouseshape +ruby/dyn -toolbar
+arabic +cursorshape +iconv/dyn +multi_byte_ime/dyn +scrollbind +user_commands
+autocmd +dialog_con +insert_expand +multi_lang +signs +vertsplit
-balloon_eval +diff +job +mzscheme/dyn +smartindent +virtualedit
-browse +digraphs +jumplist -netbeans_intg +startuptime +visual
++builtin_terms -dnd +keymap +num64 +statusline +visualextra
+byte_offset -ebcdic +lambda +packages -sun_workshop +viminfo
+channel +emacs_tags +langmap +path_extra +syntax +vreplace
+cindent +eval +libcall +perl/dyn +tag_binary +wildignore
+clientserver +ex_extra +linebreak +persistent_undo +tag_old_static +wildmenu
+clipboard +extra_search +lispindent -postscript -tag_any_white +windows
+cmdline_compl +farsi +listcmds +printer +tcl/dyn +writebackup
+cmdline_hist +file_in_path +localmap +profile +termguicolors -xfontset
+cmdline_info +find_in_path +lua/dyn +python/dyn -tgetent -xim
+comments +float +menu +python3/dyn -termresponse -xpm_w32
+conceal +folding +mksession +quickfix +textobjects -xterm_save
+cryptv -footer +modify_fname +reltime +timers
+cscope +gettext/dyn +mouse +rightleft +title
system vimrc file: "$VIM\vimrc"
user vimrc file: "$HOME\_vimrc"
2nd user vimrc file: "$HOME\vimfiles\vimrc"
3rd user vimrc file: "$VIM\_vimrc"
user exrc file: "$HOME\_exrc"
2nd user exrc file: "$VIM\_exrc"
defaults file: "$VIMRUNTIME\defaults.vim"
Compilation: cl -c /W3 /nologo -I. -Iproto -DHAVE_PATHDEF -DWIN32 -DFEAT_CSCOPE -DFEAT_JOB_CHANNEL -DWINVER=0x500 -D_WIN32_WINNT=0x500 /Fo.\ObjCULYHTRZi386/ -DHAVE_STDINT_H /Ox /GL -DNDEBUG /Zl /MT -DFEAT_MBYTE_IME -DDYNAMIC_IME -DFEAT_MBYTE -DDYNAMIC_ICONV -DDYNAMIC_GETTEXT -DFEAT_TCL -DDYNAMIC_TCL -DDYNAMIC_TCL_DLL=\"tcl86.dll\" -DDYNAMIC_TCL_VER=\"8.6\" -DFEAT_LUA -DDYNAMIC_LUA -DDYNAMIC_LUA_DLL=\"lua53.dll\" -DFEAT_PYTHON -DDYNAMIC_PYTHON -DDYNAMIC_PYTHON_DLL=\"python27.dll\" -DFEAT_PYTHON3 -DDYNAMIC_PYTHON3 -DDYNAMIC_PYTHON3_DLL=\"python35.dll\" -DFEAT_MZSCHEME -I "C:\Program Files (x86)\Racket\include" -DMZ_PRECISE_GC -DDYNAMIC_MZSCHEME -DDYNAMIC_MZSCH_DLL=\"libracket3m_a0solc.dll\" -DDYNAMIC_MZGC_DLL=\"libracket3m_a0solc.dll\" -DFEAT_PERL -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DDYNAMIC_PERL -DDYNAMIC_PERL_DLL=\"perl524.dll\" -DFEAT_RUBY -DDYNAMIC_RUBY -DDYNAMIC_RUBY_VER=22 -DDYNAMIC_RUBY_DLL=\"msvcrt-ruby220.dll\" -DFEAT_HUGE /Fd.\ObjCULYHTRZi386/ /Zi
Linking: link /RELEASE /nologo /subsystem:console /LTCG:STATUS oldnames.lib kernel32.lib advapi32.lib shell32.lib gdi32.lib comdlg32.lib ole32.lib uuid.lib /machine:i386 /nodefaultlib libcmt.lib user32.lib /nodefaultlib:lua53.lib /STACK:8388608 /nodefaultlib:python27.lib /nodefaultlib:python35.lib "C:\Tcl\lib\tclstub86.lib" WSock32.lib /PDB:vim.pdb -debug
on Windows 7 x64.
vim-airline is installed @ https://github.com/vim-airline/vim-airline/commit/470e9870f13830580d1938a2dae1be5b6e43d92a
The behavior reproducible with nothing but vim-airline and vim-lawrencium in the vimrc. My airline configuration does not have any changes from the default.
Slow cursor movements.
Fast cursor movements. :)
thanks for the thorough investigation. I appreciated and have just pushed 2 small fixes.
Parsing the mq patch status file directly, without invoking hg at all - this is what lawrencium does for many things, too.
I'd like to do that if possible, however until now I haven't figured out how to do it better.
I'm not sure if that's even a good idea, because it will break when mq decides to change the file format. I have not looked at the details of the file as I am not using mq at the moment, but depending on non-public API is not optimal either way.
mq is deprecated anyhow, isn't it? :)
Let's just leave it like this for now, perhaps only check for mq patches after a ShellCmdPost and otherwise leave it alone. Not sure, what a good indicator would be.
Also, s:update_hg_branch does not seem to do anything with the path argument - it might, in the future, but as of now, calculating the path in this case isn't even necessary.
I'm not sure about that either, but cutting the triggers down to buffer activation would ease a lot of the superfluous load - maybe checking the branch is not necessary on every keypress, either. I'm not into vimscript and vim internal events enough to pin it down.
Also, s:update_hg_branch does not seem to do anything with the path argument - it might, in the future, but as of now, calculating the path in this case isn't even necessary.
That is because we are using a generic approach and depending on whether we are actually using git or hg call the same function. So it should take the same arguments :)
Yes, but you _could_ pass an empty string until the day when more is necessary. It's all internal functions anyway. :)
No, Then I would need to add an additional check, for whether we are actually using hg. Let's just document it for now (and use ... as function declaration)
I know, it's micro-optimization. When the b:path is only calculated sparingly it won't make any difference.
Okay, I have pushed a couple of fixes. Can you check, if this works better for you now?
Nope, still slow, unfortunately. I'm going to dig into this more tomorrow.
okay, thanks. Let me know what you find out.
@chrisbra Is there a functional difference between fnamemodify(expand('%'), ':p') and expand('%:p')?
no I don't think so. Earlier Vim versions did not have fnamemodify(), I believe some early 7.3 or so.
I believe this is solved?
@chrisbra After still experiencing sluggish cursor movement, I got stuck in making my own changes to branch.vim last week, but I made slow progress and it never got to a point where I could say "that's it".
In the meantime you seem to have made some further improvements yourself - it seems to be solved now. Cursor movement is as snappy as ever. Thank you! :)
thanks for coming back