Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to make vim's visualbell only flash the top/bottom lines?

Tags:

vim

Been using Vim for years now and this whole time I just accepted how bright and distracting the visual bell was. Recently someone showed me the Emacs visual bell, which only flashes the top and bottom lines of the screen. Does anyone know how to reproduce this behavior in Vim?

And if it's not currently configurable, does anyone know how hard it would be to patch that in? I have some C experience but no familiarity with the codebase.

like image 689
Wang Avatar asked Dec 16 '11 08:12

Wang


1 Answers

Vim and versions

The big problem with you question is, that this question depends on the vim version. By vim version I mean not the version (7.3...), but much more if you're using MacVim, gVim, the terminal edition, etc. The version is imporant, because the t_vb param (type :set t_vb? to get it) is different for different vim versions, but I write about that later.

I'm using Ubuntu. In my terminal I'm not even able to produce those visual flashes (probably Ubuntu just ignores them, at least that's what happend to the normal bell: This program sounds the bell!). gVim is different, the visual bell is working there. The same is happening with Emacs. The visual bell (top and bottom lines, like you described) is working perfectly fine in the X version. The terminal version is just quiet.

t_vb settings

As some have suspected, the t_vb param is responsible for the visual bell in vim. But it looks different in the terminal:

t_vb=^[[?5h$<100/>^[[?5l

and gVim:

t_vb=^[|f

So I think it would be different for MacVim, too.

By the way: If you are modifying the bell you must generate the ^[ with <C-V> followed by <ESC>. Don't copy the strings above, they will not work.

t_vb is simply a string that is sent to the terminal (or gvim). You could also define t_vb=abcd, which would temporarily output abcd at your cursor. This is just display magic, the flashes occur because of escape characters. There is no way to communicate with vim. You can however modify the whole vim display (delete lines, add lines, etc). But if the display is redrawn, everything will be gone. The main problem with this task is that the escape sequences don't have a sleep sequence. You could try to insert a line with white color and remove it, but this is just way to fast (I tried it).

The described behaviour is just the case for gVim. But I think the rest will probably behave very similar. However, if your terminal / pseudo terminal supports an escape sequence which highlights only some defined number of lines, you would be able to do what you want.

I might disappoint you, but I don't think there is a way to get the behaviour you want, without modifying the vim source (or modifying a terminal software, which I would definitely not recommend).

Modification of the original source code

If you want to edit the behaviour of the visual bell as you like, you can always edit the C files. I wouldn't recommend it, but it's definitely not impossible. You could start here:

http://code.google.com/p/vim/source/browse/src/misc1.c#3433

Remove "out_str(T_VB);" and insert something like this (pseudo code):

invert(fist_line)
invert(last_line)
sleep(100 ms)
invert(fist_line)
invert(last_line)

The sleep could be annoying. But this is just the easiest way (No timers, etc.). The problem would be to find such an invert function. I'd try to look for a command which executes vim-script and then try to find a matching vim command. I bet that would be possible.

like image 135
Dave Halter Avatar answered Oct 16 '22 14:10

Dave Halter