Syntax highlighting causes terrible lag in Vim - vim

I love Vim. But its giving me hard times right now.
I use a lot of plugins and during the last 6 months, I've found a lot of awesome ones. But my Vim got really sluggish too. I do constant cleanups, but it doesn't help much.
I'm at the point, where Vim is completely unusable. It feels like it renders at 2-5 frames per second, switching tabs/buffers takes about a second, scrolling with hjkl is awfully terrible, the lag is so bad, even typing a sentence in insert mode is confusing (due to lag).
Edit: Actually, when I open fresh instance of Vim its OK-ish, but than within 15 minutes it becomes unusable.
I've just spent 4 hours trying to figure out which plugin or config is causing the pain. I was unsuccessful.
However, I did find out, that removal of this setting causes all the lag to go away:
syntax on
These 3 lines in conjunction with syntax make everything even worse.
set t_Co=256
set background=dark
colorscheme candyman
Interesting. So, syntax highlighting is turning Vim from super snappy to incredibly sluggish?
I tried enabling syntax in "clean" mode:
vim -u NONE
And its not an issue there.
So what seems to be the issue is Syntax Highlighting in combination with one or more of my plugins. I tried disabling bunch, no luck.
Is there any way to do profiling? I'm fairly exhausted from manual testing.
Has anyone had similar experience? Maybe take a quick peek into my .vimrc, see if anything rings a bell.
https://bitbucket.org/furion/dotfiles
SOLUTION:
The plugin causing the mess was:
Bundle "gorodinskiy/vim-coloresque.git"
I recommend reading the answers tho, good insights.
Edit (1 month later): The coloresque plugin has seen some improvements.

EDIT: Blogged about how this all works, with screenshots and awesome-sauce.
https://eduncan911.com/software/fix-slow-scrolling-in-vim-and-neovim.html
Original answer below...
:syntime on
move around in your ruby file and then
:syntime report
It reported the following slowest matching for me, and you can see that there are not even 1 match.
I disabled rubyPredefinedConstant in ruby.vim file and problem solved. Vim regex engine does not like something in ruby syntax highlight regex. You will have to find the balance between enough syntax highligting and a good performance.
Here is the top 3 slowest syntax highlighting regex for ruby reported on my Mac OS 10.8.5, homebrew Vim 7.4 (console vim)
TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN
3.498505 12494 0 0.008359 0.000280 rubyPredefinedConstant \%(\%(\.\#<!\.\)\#<!\|::\)\_s*\zs\%(STDERR\|STDIN\|STDOUT\|TOPLEVEL_BINDING\|TRUE\)\>\%(\s*(\)\#!
2.948513 12494 0 0.006798 0.000236 rubyPredefinedConstant \%(\%(\.\#<!\.\)\#<!\|::\)\_s*\zs\%(MatchingData\|ARGF\|ARGV\|ENV\)\>\%(\s*(\)\#!
2.438253 12494 0 0.005346 0.000195 rubyPredefinedConstant \%(\%(\.\#<!\.\)\#<!\|::\)\_s*\zs\%(DATA\|FALSE\|NIL\)\>\%(\s*(\)\#!
Or you can try vim-ruby as pointed out by Dojosto

You have autocmd spam. You should wrap all of your autocmd statements in groups which clear the group before re-adding the autocmds. It looks like your .vimrc has most autocmds commented-out, so maybe there is a plugin that is causing the issue. Check the output of this command:
:au CursorMoved
If there's a bunch of duplicate handlers there, that's your problem.
Here's an example of autocmd discipline from my .vimrc:
augroup vimrc_autocmd
autocmd!
"toggle quickfix window
autocmd BufReadPost quickfix map <buffer> <leader>qq :cclose<cr>|map <buffer> <c-p> <up>|map <buffer> <c-n> <down>
autocmd FileType unite call s:unite_settings()
" obliterate unite buffers (marks especially).
autocmd BufLeave \[unite\]* if "nofile" ==# &buftype | setlocal bufhidden=wipe | endif
" Jump to the last position when reopening a file
autocmd BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g`\"" | endif
" ...etc...
augroup END
The autocmd! at the beginning of the augroup block clears out the current group (vimrc_autocmd, in this case) before re-adding the autocmds.

From another stack overflow question, I get vim fast by adding the following line in .vimrc file:
set re=1
This will force vim to use a older version of regex engine and it is actually FASTER for ruby.

I found that "set foldmethod=syntax" makes 7.4 almost unusable slow e.g. for js&ruby files (ubuntu 13.10) whereas "set foldmethod=indent" works fine.

I've noticed that vim can slow down to a halt if you're using anything that dynamically changes the background color. Try turning off :set cursorline or :set cursorcolumn (if you have them set).

I'd like to thank everyone helping me out on this issue. Good news is, my Vim is snappy again.
I've started with fresh Vim re-install. I've than added plugin by plugin, until I found the root of all evil.
Bundle "gorodinskiy/vim-coloresque.git"
Its a plugin that was causing me all this pain. Since I had it for a while, it wasn't a suspect, thats why I discovered it so late.
What this plugin does, is whenever it finds a word for color (eg red, green), or hex value (eg. #FFFFFF), it sets background color of the text to match the color that its describing. Brilliant idea, but seems like poor implementation.
Removing this plugin removed the lags.
But I didn't stop here. I've done a major cleanup of my .vimrc as well. Removed some more plugins I hadn't used. Grouped my autocmds and removed unnecessary ones.
My Vim is very snappy now. I'm happy again.

Syntax highlighting can be slow, but that should be limited to some (somewhat pathological) files, and particular syntax(es). The latest Vim 7.4 has a new command :syntime to troubleshoot syntax highlighting slowness.
Apart from that, often, a binary search where you disable half of your plugins, then only one half of that (when the problem is still there), or the other half (when the problem vanished) lets you get to the problematic script quickly.

I'm pretty sure that
set t_Co=256
set background=dark
colorscheme candyman
have nothing to do with that lag. The two first lines are useless (the number of usable colors is defined according to your $TERM and your colorscheme already does set background=dark) but not really harmful.
Common "Vim is slowing to a crawl" causes include poorly written autocmds, too many autocmds, reloading one's ~/.vimrc too often, poorly written plugins…
Please post your setup so that we can help you find out why you experience that lag.

I have had this problem for a long time, and it was driving me crazy. I tried installing vim-ruby. Not sure if that helped but at least now I have the most up-to-date version of ruby syntax highlighting (with any performance improvements since the last version of Vim was released).
But then I looked further, and discovered that vim-ruby has a mode that skips all the expensive highlighting. Try adding this line to your vimrc and see if it helps (it did for me, finally!):
let ruby_no_expensive=1

For me that was set relativenumber feature which was slowing it down. Try to disable it with set norelativenumber and test.

Just in case it helps anyone out there:
I had accidentally created an extremely large tag file for my project; so my syntax highlighter was searching the large file to highlight function names.
So check your tag file! (In my setup I was using easy-tags so mine was placed at ~/.vimtags

Very late, but I figured this may help someone in a similar boat as me.
The plugin vim-nerdtree-syntax-highlight turned out to be lagging my entire editor. They do mention on their Github that people have reported lag issues, and offer some solutions.
So if anyone happens to be using that plugin, try using some of the fixes listed; this one works, but you need to be selective about which languages you want to keep:
let g:NERDTreeSyntaxDisableDefaultExtensions = 1
let g:NERDTreeDisableExactMatchHighlight = 1
let g:NERDTreeDisablePatternMatchHighlight = 1
let g:NERDTreeSyntaxEnabledExtensions = ['c', 'h', 'c++', 'php', 'rb', 'js', 'css']

Related

vim execute command depending on file type

How can I get vim to execute a command depending on the file type?
Recently I have been editing a lot of Python files and comments autoindent to the 0th column.
One way to fix this is to run the command inoremap # X#<left><backspace><right>
How can I get this command to run every time I open a python (*.py) file for editing?
TL;DR
Use vim's filetype plugin mechanism.
File-type specific code
There are (at least) two solutions to this, with one preferable to the other.
autocmd FileType
This has already been posted as an answer, but the general form is
augroup your_group
autocmd!
autocmd FileType python your good code
augroup END
This works, and has the advantage of grouping code in your vimrc.
But there is a second, more powerful, probably more performant alternative. It
is my preferred
solution.
after/ftplugin
I've written
extensively about using filetype
plugins in vim.
The gist of it is that you need filetype detection and plugins (filetype plugin
on at a minimum, though you may want filetype plugin indent on). Then you
drop filetype specific code in ~/.vim/after/ftplugin/<filetype>.vim (or a few
variants, see :h add-filetype-plugin, :h ftplugin-name, :h ftplugin).
So ultimately,
" ~/.vim/after/ftplugin/python.vim
inoremap # X#<left><backspace><right>
A few notes
It is a good practice to set b:undo_ftplugin properly: it helps (trust me).
You can borrow my undo script on
Github.
Consider using <buffer>, -buffer, setlocal, and <LocalLeader> where
possible. This is for local stuff, after all.
On power
A script gives you more flexibility than a single line of autocommands. You have
to jump through more hoops to do anything complex in autocommands, where in a
script they can just sit. Besides, you feel more like you're writing a program
(which you are) than a one off config.
The modularity is also perfect for organization: all your python customization
code is in one place.
And it's a lot less typing :)
On performance
I have not measured anything. Don't shoot me.
Having lots of autocommands can slow down vim, because they have to be checked
when their events fire. Rather than clog up the autocommands with filetype
stuff, use a file that is already going to be sourced for you (an ftplugin).
By piggybacking on an existing customization mechanic, you get all the benefit
and none of the risk. Again, it is almost certainly more efficient to let vim
source a file on demand for you then to try to reimplement it's ftplugin wheel.
Does this solve your issue?
au FileType python inoremap # X#<left><backspace><right>
This autocommand runs your mapping for filetype python

Make Syntastic close just the error window

I've got the (Mac)Vim Syntastic plugin installed via Janus. When I open the :Errors window to view the reason for syntax errors, it shrinks the file with the errors to one line and uses the rest of the real estate for the Errors window.
Is there a way to make it hog less room for errors and more importantly, how do I close just the Errors window? The usual :q closes both the Errors window AND the original file, even if the cursor is in the Errors window. (That's not 100% correct -- it gratefully does not close the file if the file hasn't yet been saved).
Syntastic uses the location list (a window-local variant of the quickfix list), so a :lclose will close it, but keep the other buffers.
As per syntastic's help pages, the initial height can be configured:
:let g:syntastic_loc_list_height=5
But I suspect that your intrusive Janus distribution has a hand in that. Vim "distributions" like spf-13 and Janus lure you with a quick install and out of the box settings, but you pay the price with increased complexity (you need to understand both Vim's runtime loading scheme and the arbitrary conventions of the distribution) and inflexibility (the distribution may make some things easier, but other things very difficult). Vim is incredibly customizable, using someone else's customization makes no sense.
The command to close the Syntastic error window is:
:SyntasticReset
Syntastic gets confused when you're juggling multiple buffers on one screen so here's a script that will collect information about the situation, then do the right thing:
function JustCloseSyntasticWindow()
"Check which buffer we are in, and if not, return to the main one:
if &ft == "qf"
normal ZZ
endif
"Since different buffers have different command spaces, check if we've
"escaped the other buffer and then tell syntastic to stop.
if &ft != "qf"
SyntasticReset
" --- or ----
SyntasticToggleMode
endif
endfunction
au FileType buffer1_ft nnoremap :yourcmd<CR>:call JustCloseSyntasticWindow()<cr>
au FileType main_win_ft nnoremap :yourcmd<CR>:call JustCloseSyntasticWindow()<cr>
Don't be shy on the duct tape for this job, it's the only thing holding the unit together.
You can use :lclose to close it.

Vim: insert mode is very slow with 400+ lines

I have a file with 400+ lines (it's a thesis). When I edit it somewhere near
the top (say, on line 20), Vim is snappy as always. However, editing it near
the bottom (around line 400) causes a noticeable delay between me typing the character
and Vim showing it on the screen. As a consequence, it is almost impossible to
edit a file this big.
What is the reason for this and what can I do?
I've tried toggling the swapfile, syntax, scrolloff etc, but it doesn't
seem to help. The maximum number of lines for Vim should be 2147483647, so I
should actually have a long way to go here :)
In case this is related to setting maxmem, then what would be a reasonable
value, considering that I edit files up to 2500 lines?
Thanks very much for any help! Cheers.
Okay, folding was the problem here (I had some bad settings for foldlevelstart). So, based on my experiences and these issues:
set foldenable " can slow Vim down with some plugins
set foldlevelstart=99 " can slow Vim down with some plugins
set foldmethod=syntax " can slow Vim down with some plugins
Other things to check/toggle are syntax, filetype, wrap and line length (some plugins can be slow with very long lines).
Running Vim without your current settings is a good starting point. Thanks to #Frederik for pointing me to this:
vim -u NONE
After this, disabling all plugins is a good start. See also for general knowledge: :help slow
I recently came across this exact problem - lag while typing at the bottom of a relatively short (markdown) file. After uninstalling plugins and commenting out most of the settings in my .vimrc, I discovered that the issue was markdown folding coming from the vim-markdown plugin that is pre-installed with vim. Commenting out let g:markdown_folding = 1 did the trick.
I still wanted to have automatic folding on markdown files, so I installed vim-markdown-folding and there are no issues with performance.
In my case relative numbers with same file opened in multiple windows was lagging. I had to do either :set norelativenumber or close another windows.
Don't blame syntax only, several things can slow down editing in normal mode. e.g. auto completion; I had days of thinking that my Vim was slow because of syntax. I configured my autocompletion plugin to only trigger autocompletion once I have typed in at least 6 characters and the speed grew tremendously. I didn't even have to touch anything with syntax highlighting.

Using folds with synmaxcol in vim

Sometimes when I'm working on a project I want to play around with some data. Often times the data is on one line and is huge (>25k characters). I understand I could set nowrap and have this line just run off the screen, but I tend to like set wrap for other reasons. So, as a workaround I want to hide these long lines in a marker fold (e.g. {{{ long line }}}). This works fine but I run into a problem with synmaxcol for some reason. If the folded line exceeds synmaxcol then when I open the file, the syntax highlighting runs over. For example:
However, as soon as I open the fold the syntax corrects itself:
Having to open the fold every time is annoying though. As you can see in this example the line is not actually all that long -- it just exceeds synmaxcol. Since synmaxcol is exceeded at a "string" element, the rest of the file is highlighted as a string (so nothing but a singular double quote will stop it).
Why is this happening and how can I fix it? I've tried this with different syntax files and filetypes and it still occurs. I've also tried it with no plugins, a minimal vimrc (containing only syn on) and a modeline to set fdm=marker:synmaxcol=60 and it still happens.
You can manually enter :syntax sync fromstart to force Vim to rescan the syntax from the beginning of the opened file.
I would suggest defining a hotkey for convenience:
noremap <F5> <Esc>:syntax sync fromstart<CR>
inoremap <F5> <C-o>:syntax sync fromstart<CR>
Now you can press F5 to clean up most syntax highlighting problems.
Also, have a look at Vim's fixing syntax highlighting - wiki page
Moreover reading :help :syn-sync-first might shed some more light on the issue.
UPDATE:
I was able to reproduce this behavior on my machine (I'm running Vim 7.3.429).
However, when I wrapped the fold markers {{{ and }}} in block comments, vim correctly rendered the syntax. You can create appropriately wrapped fold-markers using the zf command. See Vim tips: Folding fun.
Normally Vim picks the correct blockcomment string based on the currently active syntax. However, my Vim is pretty vanilla and didn't recognize Ruby syntax. I could specify autocmd FileType ruby set commentstring==begin%s=end in my .vimrc file to set the proper block comment. See :fold-create-marker for more details.
Another solution is to set synmaxcol=0, which will effectively set it to infinity. This causes Vim to check the syntax of the entire line, no matter how long it is. However, I'm not sure what kind of performance penalty you'll have to pay for that.

vim syntax off when one buffer quit?

I have two buffers in my vim session, and I set syntax on in my vimrc , I used minibufexpl to manage bufs.
I used :q to quit the current buf, but the other buf would auto set the syntax off, I have to use :set syntax=on to open the syntax highlight manually. Could someone give me a solution that not set the syntax off automatic after one buf quit? Thanks!! (I tried :bd to quit the buf instead of :q, sometimes it stay the syntax on but sometimes no).
If you're using minibufexpl.vim, add the following to your .vimrc:
let g:miniBufExplForceSyntaxEnable = 1
It appears to be caused by a bug in vim. For the details, refer to the release notes for minibufexpl version 6.3.1
Note that this will work for :bd but not :q
This might be much too late, but I was experiencing the exact same problem and found that adding the line
set hidden
to my .vimrc solves this problem. This makes vim hide buffers rather than closing them when you enter ":q" It also seems to keep my syntax highlighting enabled between files when I navigate with minibufexplorer.
Hope this helps.
You can use syntax enable or syntax on in your vimrc. For more info use :h syntax.
Ok then check that your syntax files are correct, it should looke like this
au BufNewFile,BufRead *.cpp set syntax=cpp11 <-- it's the line I have for cpp files.
Hope this help.
May be you should add this line to gvimrc:
autocmd BufDelete * syntax on
A plugin is misbehaving.
After closing the buffer (and losing syntax highlighting), investigate, by e.g.
:verbose set syntax?
This will show something like
syntax=cpp
Last set from C:\Program Files\Vim\vim73\syntax\syntax.vim
You might also be able to see what goes wrong my doing
:debug quit
If all else fails, try eliminating sources of errors by disabling plugins one-by-one (or removing all, and enabling one-by-one). At some point the problem will appear/disappear and you have found the guilty party.

Resources