Vim-airline: Editing slowdown with vim-lawrencium

Created on 23 Aug 2017  路  17Comments  路  Source: vim-airline/vim-airline

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:

  • https://github.com/vim-airline/vim-airline/blob/470e9870f13830580d1938a2dae1be5b6e43d92a/autoload/airline/extensions/branch.vim#L142-L145

    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:

  • https://github.com/vim-airline/vim-airline/blob/470e9870f13830580d1938a2dae1be5b6e43d92a/autoload/airline/extensions/branch.vim#L123-L127

    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:

    • A global flag for disabling airline mq support
    • Testing for the existence of the mq extension by probing hg help, setting the flag accordingly
    • Figuring out better/less frequent triggers for this particular check than cursormoved
    • Parsing the mq patch status file directly, without invoking hg at all - this is what lawrencium does for many things, too.

environment


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.

actual behavior

Slow cursor movements.

expected behavior

Fast cursor movements. :)

All 17 comments

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

brotatos picture brotatos  路  21Comments

r004 picture r004  路  18Comments

zdm picture zdm  路  46Comments

jaredcobb picture jaredcobb  路  36Comments

svanharmelen picture svanharmelen  路  22Comments