I've recently installed a plugin called vim-troll-stopper.
Some unicode characters are drawn exactly the same but have different meanings.
I think they are called homoglyphs.
Some programmers may use this to troll people using their code, by replacing for example the semicolon (; unicode 003b) with a greek question mark (; unicode 037e).
The purpose of the plugin is to warn you by highlighting all suspicious characters in red, and by replacing them with their legitimate counterparts if you type the command :TrollStop
.
However I've noticed that the more I switch between buffers, the more the plugin causes lag.
Here's how to reproduce the lag :
Install the plugin ; if you use Vundle as a plugin manager, it simply means adding the line
Plugin 'vim-utils/vim-troll-stopper'
inside your vimrc, writing and sourcing it, then typing the command:PluginInstall
.open 2 files foo and bar :
vim foo bar
- write some text inside foo :
here's some text
- copy and paste the line a lot :
yy99p
- switch to buffer bar :
:b2
- write some text inside bar :
more text
- copy and paste the line a lot :
yy99p
- Now, switch back and forth a lot between the two buffers with the default mapping
<C-^>
, and look at the cpu load.
When I do this on my system, vim usually doesn't use more than 2% of the cpu and the movements inside the files (hjkl) remain quick.
However, with the plugin enabled, switching a lot between buffers causes vim to use between 25% and 30% of the cpu, and then the movements inside the files are very slow.
I don't know a lot about vimscript, but I noticed that the problem is not binary : vim is not quick then suddenly completely slow.
The more I switch buffers, the more it is slow.
So I supposed that something was happening every time I entered a buffer.
I looked at the code, and noticed this line :
autocmd BufEnter * call <SID>HighlighTrolling()
This command causes vim to call the HighlighTrolling()
function whenever you enter a buffer.
I suppose the function highlights the suspicious characters in red.
In the 14th chapter of Learn Vimscript the Hard Way, the author says that if you create an autocommand and define it twice, even though the autocommand is the same, it will be executed twice :
When you create an autocommand like this Vim has no way of knowing if you want it to replace an existing one. In our case, Vim created two separate autocommands that each happen to do the same thing.
He also says that the solution is to wrap the autocommand inside an autocommand group and clear the group :
Vim has a solution to the problem. The first step is to group related autocommands into named groups.
[...]
If you want to clear a group you can use autocmd! inside the group.
Now, going back to the plugin lag, I thought this could explain it. I tried fixing the code like this :
augroup highlight
autocmd!
autocmd BufEnter * call <SID>HighlighTrolling()
augroup END
Unfortunately, it didn't solve the lag issue.
So I tried to simply change the event that triggers the autocommand from BufEnter
to BufRead,BufNewFile
:
autocmd BufRead,BufNewFile * call <SID>HighlighTrolling()
It worked, the lag is now gone.
However, out of curiosity, I would like to know 3 things :
- Why is the plugin causing lag ? Is it because it duplicates an autocommand every time I enter a buffer ?
If so, is there a way to see those duplicates autocommands ?
I typed
:com
and didn't see them. - In the context of this plugin, what do you think would be the best event to trigger the autocommand that highlights the suspicious characters ?
- More generally, how would you modify the plugin so that it doesn't cause lag anymore ?