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

Insert mode lags #1165

Closed
habamax opened this issue Jan 13, 2020 · 16 comments
Closed

Insert mode lags #1165

habamax opened this issue Jan 13, 2020 · 16 comments
Labels

Comments

@habamax
Copy link

habamax commented Jan 13, 2020

In insert mode I can see quite a lag especially when I do enter Russian letters.

Expected behavior:
Should be no lag

Actual behavior:
Lag

ultisnips-issue1

Steps to reproduce

Well, not sure. I just had it installed for quite a long time

Settings that I had regarding ultisnips

	let g:UltiSnipsExpandTrigger = '<tab>'
	let g:UltiSnipsJumpForwardTrigger = '<tab>'
	let g:UltiSnipsJumpBackwardTrigger = '<s-tab>'
	let g:UltiSnipsListSnippets = '<c-tab>'

My snippets were:

https://github.com/habamax/.vim/tree/03dce7b57131e993b5ccdc88775196c2f5fe7ef6/UltiSnips

If I remove Ultisnips (use vsnips instead):
ultisnips-issue3

PS

If I remove au! Ultisnips_AutoTrigger it becomes way faster. But only for english. Russian lags the same.

ultisnips-issue2


  • Operating System: Win10
  • Vim Version: 8.2.114
  • UltiSnips Version: current master
  • Python inside Vim: 3.8.1
@lacygoill
Copy link
Contributor

lacygoill commented Jan 13, 2020

Steps to reproduce

Well, not sure.

Without a MWE there's no way to know what causes your issue. Bisect your config until you find one, then post it here.

Here's what a MWE could look like:

" in `/tmp/vimrc`
let g:UltiSnipsSnippetDirectories = ['/tmp/snippets']
let g:UltiSnipsExpandTrigger = '<tab>'
set rtp-=$HOME/.vim
set rtp^=$HOME/.vim/plugged/ultisnips
set rtp+=$HOME/.vim/plugged/ultisnips/after
set rtp^=$HOME/.vim
filetype plugin on

# in `/tmp/snippets/vim.snippets`
snippet trigger
my snippet has been expanded
endsnippet

" start Vim like this:
$ vim -Nu /tmp/vimrc /tmp/vim.vim

" type those keys: ....

See also reproducing-bugs.


Just a guess, but in your gifs, the text contains fold markers; folding can introduce lag.
Check whether you can reproduce after temporarily setting 'foldmethod' to manual (:setl fdm=manual), or try vim-fastfold.

@lacygoill
Copy link
Contributor

lacygoill commented Jan 13, 2020

Also, try to get a profile:

:prof start /tmp/profile.log
:prof! file /path/to/ultisnips/**/*.vim
:ru! /path/to/ultisnips/**/*.vim
" reproduce the issue, then quit Vim; the profile should be written in `/tmp/profile.log`

See :h profile.

@habamax
Copy link
Author

habamax commented Jan 14, 2020

Just a guess, but in your gifs, the text contains fold markers; folding can introduce lag.
Check whether you can reproduce after temporarily setting 'foldmethod' to manual (:setl fdm=manual), or try vim-fastfold.

That is not the case:

  1. without ultisnips it doesn't lag with the same file, same folding settings
  2. it lags the same on a new file without folding at all (set fdm=manual)

@lacygoill
Copy link
Contributor

Ok, then you'll have to bisect your config to find a minimal reproducible example.

@habamax
Copy link
Author

habamax commented Jan 14, 2020

Ok, then you'll have to bisect your config to find a minimal reproducible example.

Busy at work, will try to do it when I have time. Thx.

@habamax
Copy link
Author

habamax commented Jan 14, 2020

Well, I've spent last 1.5 hour bisecting my config, removing/reinstalling plugins and couldn't find the exact thing that makes ultisnips slow.

without any plugins installed next lines in my vimrc makes ultisnips slower (not THAT slow as in my previous gifs but I can see it):

func! SetDefaultFiletype()
	if @% == "" && &filetype == ""
		setfiletype txt
	endif
endfunc
augroup default_filetype
	autocmd!
	autocmd BufEnter * call SetDefaultFiletype()
augroup END

When I start adding other plugins one by one, ultisnips become slightly more laggy with each plugin I install until the result u see in gifs. I couldn't find single plugin that adds all the laggines fo far.

I think you can close the issue and reopen it when there will be other reports on it (I will continue using vsnip for now as I don't have time at the moment to investigate root cause)

Thank you!

@SirVer
Copy link
Owner

SirVer commented Jan 18, 2020

This is very unfortunate behavior and I am deeply sorry that it bothered your editing experience. Windows support is traditionally the poorest in UltiSnips. The reason is that I do not have access to a Windows machine and have in fact not worked on any Windows machine for ten years or so.

traditionally, the Python <-> Vim bridge in Windows was not very performant. My hunch (without any data) is that string conversions (Vim uses UTF8, while Windows traditionally uses Unicode 16 or so, which I think python on Windows also uses internally) are expensive and that could be the reason you see slow downs. However, I do not have the means to investigate this.

I'll leave this open for a while to see if somebody else jumps on it and can add additional data.

@habamax Thanks for investing so much time and energy into this bug report!

@SirVer SirVer added can't reproduce triaged Bugs that I had a look at windows only labels Jan 18, 2020
@jperrett256
Copy link

Just wanted to say I have experienced this on both Linux and Windows.

@ws051682
Copy link

Just wanted to say I have experienced this on both Linux and Windows.

Indeed, i'm using ubuntu and I do have similar issue.

@mnemster
Copy link

mnemster commented May 25, 2023

I can confirm that I have the same issue on GVIM on Windows (but not on GVIM on KDE Linux, though). The lag is specially noticeable when editing text files (perhaps because I type prose much faster than code?) and creating a new snippet file for texts with :UltiSnipsEdit seems to alleviate the lag a little (any snippet will do, just need to create the file).

@skywind3000
Copy link

Same issue for GVim+win10

@skywind3000
Copy link

skywind3000 commented Sep 5, 2023

I thought I found something, and figure out how to reproduce this on Linux.

I am experiencing serious insert mode lag too:

One thing I noticed is that: when I was using a minimal vimrc (with only one plugin, ultisnips installed), the lag was small, but still noticable. Then I started to add other plugins and found: the more plugin I had, the more input lag I got .

Is it related to the number of runtimepath ? What if I only add some empty runtimepaths without adding any other actual plugin? To prove this, I made a minimal vimrc to add 300 empty runtimepaths:

set nocompatible

set ttimeout
set ttimeoutlen=50
set display=lastline
set encoding=utf-8
set fileencoding=utf-8
set fileencodings=ucs-bom,utf-8,gbk,gb18030,big5,euc-jp,latin1
set showcmd

syntax enable
syntax on

filetype plugin indent on

set rtp+=c:/users/Linwei/.vim/bundles/ultisnips

let BASE = 'd:/temp/ultisnips'

for i in range(300)
	let tmpname = printf("%s/rtp-%d", BASE, i)
	exec 'set rtp+=' . fnameescape(tmpname)
	call mkdir(tmpname, 'p')
endfor

setlocal ft=cpp

The lag became intolerable with this minimal vimrc:

And I've recorded a profile log for this:

FUNCTIONS SORTED ON TOTAL TIME
count  total (s)   self (s)  function
  106  26.851451             UltiSnips#TrackChange()
   91   0.015417   0.014351  <SNR>23_Highlight_Matching_Pair()
   91   0.000902             <SNR>23_Remove_Matches()

FUNCTIONS SORTED ON SELF TIME
count  total (s)   self (s)  function
  106             26.851451  UltiSnips#TrackChange()
   91   0.015417   0.014351  <SNR>23_Highlight_Matching_Pair()
   91              0.000902  <SNR>23_Remove_Matches()

see the most expensive function is UltiSnips#TrackChange(), it costs 253ms millisecs each call:

function! UltiSnips#TrackChange() abort
py3 UltiSnips_Manager._track_change()
endfunction

This function is listening on InsertCharPre, TextChangedI, and TextChangedP:

augroup UltiSnips_AutoTrigger
au!
au InsertCharPre * call UltiSnips#TrackChange()
au TextChangedI * call UltiSnips#TrackChange()
if exists('##TextChangedP')
au TextChangedP * call UltiSnips#TrackChange()
endif
augroup END

This function will be called several times when I press a single letter, what does it do ?

Will it scan all the runtimepaths ? Can it be removed ? or only add to InsertLeave ?

I have 95+ plugins installed, which is normal nowadays, Windows I/O is slower than Linux, so this function made me unable to edit.

@SirVer , I believe you can reproduce it too on Linux by just adding 300, or more, empty runtimepaths.

@SirVer
Copy link
Owner

SirVer commented Sep 5, 2023

@skywind3000 Thanks for investing time into this issue, I highly appreciate it.

TrackChanges is doing a diff between the buffer as it was before the last cursor move and after the current cursor move. This is needed to understand how the buffer change to update tabstops, mirrors and therelike. It is a potentially very expensive function if the buffer has changed tremendously (e.g. if you paste a lot of text while a snippet is active), however it is surprising to me that it would depend on the runtime path.

It also calls try_expand which will try to expand autotrigger snippets on cursor move. This function will once load the snippets for the current file type - this will indeed traverse all runtimepaths - but then only ever reload them when a .snippets file is saved in the current vim session. I just verified this with some quick debug printf that this indeed works as intended (on my system).

I think a bit more digging is required on your end - I cannot reproduce lag in simple buffers even with 300 entries in my runtimepath. Edit: to clarify: If I add 1000 directories to my rtp, i notice a clear lack upon expanding the first time the cursor moves, but not thereafter.

@AlxHnr
Copy link

AlxHnr commented Sep 27, 2023

I doubt this depends on the amount of paths in the rtp. But rather on the latency of the underlying filesystem. When using neovim inside a linux VM to edit files on a virtiofs mount, the delay while typing makes it barely usable. (With my snippets and plugins are also on this virtiofs mount). The only current workaround is to delete the augroup UltiSnips_AutoTrigger as described here back in 2018. But even outside a VM, the difference is perceivable without this augroup when you pay attention.

@SirVer
Copy link
Owner

SirVer commented Oct 14, 2023

I do not get where this would come from though - UltiSnips does not access the filesystem unless reloading snippets, which only happens on the first expand or after a .snippet file was edited inside Vim.

mg979 added a commit to mg979/ultisnips that referenced this issue Mar 6, 2024
Ultisnips was traversing the whole runtimepath every time an expansion
was attempted, something that happens for every key press since there is
autotrigger.

Even without autotrigger, traversal was done at every snippet expansion,
which caused slowdowns in that case.

With this change, traversal happens only the first time, or after
a source must be refreshed (because a snippets file has been updated).
@SirVer SirVer closed this as completed in 49dc8cb Mar 15, 2024
@skywind3000
Copy link

appreciated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants