Friday, May 07, 2010

VIM inline calculator

Map the F11 key to VIM's eval() function (I hope the Blogger will not eat any characters):

:map <silent> <F11> :exec "s!^\\([^=]\\{-}\\)\\( *=.*\\)\\=$!\\1 = ".eval(substitute(getline(".")," *=.*$","",""))."!"<CR>

Came up during lengthy analysis of log files and source code. Some calculators allow expression. Some support history. But all that is quite limited and often is mouse driven. Check into the VIM's :help :let + digging around pointed in direction of the eval() and thus the monster macro was born.

2 statements are at the core:

1. eval(substitute(getline(".")," *=.*$","","")) strip "= whatever" from the end of the string and feed it to eval(). :h eval()

2. :exec "s!!!" where we take everything from the line, save in \1 string before "=", replace the line with "\1 = " plus result of eval(). Requires :set magic. Backslashes had to be doubled since :exec looks for them.

After adding that to vimrc or executing in place, open VIM, type on empty line "2*2", press Esc and F11. You should see "2*2 = 4".

Edit1 Apparently, the eval() function isn't available in VIM 6.x. Equivalent using :exec ":let":

function CalcX(line_num)
let l = getline(a:line_num)
let expr = substitute( l, " *=.*$","","" )
exec ":let g:tmp_calcx = ".expr
call setline(a:line_num, expr." = ".g:tmp_calcx)
:map <silent> <F11> :call CalcX(".")<CR>

Edit2 VIM 7.2 supports floating point numbers. Would be interesting to experiment with it, but I haven't bothered to upgrade yet.

Another little thing. :echo too evaluates its parameters. Typing :echo 2*2[Enter] would display 4.

Monday, May 03, 2010

Disable syntax highlighting for a large file

Got to edit today a 150MB XML file. That was painful. Tried to disable the syntax highlighting - improved the performance a lot. So I added the trick to my vimrc:

au BufReadPost * if getfsize(bufname("%")) > 512*1024 |
\ set syntax= |
\ endif

That tells VIM to disable syntax (:set syntax=) for any file whose size (while opening, :h BufReadPost) is greater than a half meg (if getfsize(bufname("%")) > 512*1024).

Edit1 A more generic solution is to use the LargeFile script from, as found out by reader David in the comments below. Starting from version 5 (at the moment of writing available only on author's, Charles Campbell, personal web page.), the script handles properly(*) the buffers with content populated using external commands. The script's main purpose in life is, when opening a large file, to set buffer options to make editing of large files more palatable experience: disable swap file, disable syntax highlighting, discard buffer with large file as soon as it is closed, disable folding, disable undo and so on.

(*) Event used is the BufReadPost, and the size of buffer is evaluated with line2byte(line("$")+1).

[link] Vim 7.2 Scripting

Rundown on a number of simple things one encounters when starting scripting: version check, OS check, debugging.