I wrote a quick snippet of VimL to display, in my statusline, the type of the currently focused Haskell expression It looks like this (click for better quality (as gfy)):
I've included the code below,
but the only important part is the system
call.
The call takes about 0.04 s to execute,
which is fine with me;
there's really no noticeable delay.
However, what does bother me greatly
is that if I send a key event while the system call is running,
the key is echoed to the display
and overwrites a character.
Of course, it doesn't actually modify the buffer,
and hitting <C-L>
is sufficient to fix it,
but this happens whenever I'm pressing keys rapidly in sequence
or holding down a key,
so writing <C-L>
all the time is very frustrating.
(Worse, it means that I can't trust my own eyes!)
How can I solve this problem?
To reproduce this, create a file with ten or so lines
(like 10Ohello<Esc>
) and save it as sample.txt
.
Save the below text block as sample.vimrc
.
Then run vim sample.txt -u sample.vimrc
and hold down j
;
you should see a bunch of j
s appear.
Hit <C-L>
to clear them.
Here's sample.vimrc
:
set nocompatible
set statusline=%{SlowOutput()}
function! SlowOutput()
silent call system("sleep 0.1")
return "I'm awake; I'm awake!"
endfunction
set laststatus=2
" tried with and without this (I would *very* much prefer to keep it on):
" set lazyredraw
The actual code I'm using, in case I'm missing something important or you just want the code for yourself, follows (it depends on bling/vim-airline and bitc/vim-hdevtools):
let g:airline_section_gutter = "%{HaskellCursorType()}%="
function! HaskellCursorType()
if &l:ft != "haskell"
return ""
else
let l:file = expand("%")
if l:file == ''
return ""
endif
if !filereadable(l:file)
return ""
endif
let l:line = line('.')
let l:col = col('.')
let l:cmd = hdevtools#build_command('type', shellescape(l:file) . ' ' . l:line . ' ' . l:col)
silent let l:output = system(l:cmd)
let l:lines = split(l:output, '\n')
if len(l:lines) == 0
return "(no type)"
endif
return matchstr(l:lines[0], '"\zs[^"]\+\ze"')
endif
endfunction
system
call)? Also, do you have a recent Vim version - newer versions may have that graphical glitch solved. Also, ideally you would never run lengthy operations to update the statusline; some other operation should update a variable, which the statusline should read when it needs to update itself.CursorHold
/CursorHoldI
events to update the variable, if possible. IIRC this is the method used by tagbar.vim (which also has an vim-airline extension).