Thursday, December 16, 2010

Make (next) found match to appear in the screen's center

Turned out to be easier than expected:

nnoremap n nzz
nnoremap N Nzz

Simply adds the zz (see :h z.) to n and N commands.

P.S. Original question and answer as SO.

Edit1 Problem with the solution is that the message search hit BOTTOM, continuing at TOP, due to the zz command, now doesn't appear on the screen anymore. Trying now to use the other tip: set scrolloff=5. Will see how that works.

Edit2 Yep, the set scrolloff=5 works for me much better than the nzz.

Tuesday, October 19, 2010

diff this!

Found a cool VIM's command - :diffthis. Invoking it in two different buffers tells the editor to diff the buffers as if it was started as vimdiff. Best (most interesting to me) part is that one can diff two unsaved buffers. E.g.:

" split the screen vertically
" paste first code fragment into the left buffer and
" press ^W^W to switch to the right buffer, paste the second code fragment and again call

To cancel the effect of :diffthis one uses the :diffoff command. The command is too buffer specific and has to be invoked in both buffers.

Another interesting related command is :diffpatch {diff-file} which again invokes vimdiff diffing the file currently in buffer against the file with the patch applied.

Tuesday, September 07, 2010

vim vs. grep : external quickfix/error file, cont'd

As an enhancement to my old trick of using grep with the VIM, I have finally come up with a solution which doesn't use the temp file:

$ alias vq="vi -c ':cgetb' -c ':cfirst! ' -"
$ grep -nr whatever . | grep -v garbage | vq

The trick is to use the new VIM 7.x command :cgetb which retrieves the error list from the current buffer. So first suck in the output of the grep into the nameless buffer, tell VIM to use the buffer as a error list and then with :cfirst! to jump to first matching line (and discard the nameless buffer).

Note in alias the space after :cfirst!: it is a secret ingredient to avoid bash interpreting the ! as the history expansion mark.

Monday, August 16, 2010

Wednesday, August 04, 2010

[off-topic] Rakudo - Perl6 - wait is over!

Just compiled the Rakudo and it seems the wait for a Perl6 implementation is finally over!

~/src/rakudo $ time ./perl6 -e 'print "hello\n"'

real 0m3.052s
user 0m0.708s
sys 0m0.753s

I mean, ~3 [*CENSORED*] seconds to print a puny [*CENSORED*] string?

No folks, I'm not waiting for it anymore. I simply go on using the Perl5.

R.I.P. Perl6, we barely knew you.

P.S. I understand alpha/beta status and all. But I doubt that even release would be able to fix the 10-100x performance regression. And yes, I checked Parrot was all compiled with optimizations.

P.P.S. I tested inside of the VirtualBox. That might slow down an application. Yet the Perl5 performance in the very same conditions is totally OK:

~/src/rakudo $ time perl -e 'print "hello\n"'

real 0m0.041s
user 0m0.002s
sys 0m0.013s
~/src/rakudo $

P.P.P.S. On my up-to-date Sidux, strace tells that "perl" needed only 101 syscall to print a string. Rakudo - 1146. Among them 527 brk()s. That's a very RAM conscious application we have here.

Saturday, June 19, 2010

Getting the exit code from make in Vim

Just answered the question on SO and I think the final trick is worth documenting here. The problem is how to get after :make exit code of the make itself. As it is wrapped by VIM, it gets lost in the pipe: :echo v:shell_error always shows 0 (:h v:shell_error).

The bash-specific trick is:

:set shellpipe=2>&1\ \|\ tee\ %s;exit\ \${PIPESTATUS[0]}

The magic is in the ;exit ${PIPESTATUS[0]}.

man bash (search for PIPESTATUS) and :h 'shellpipe' (check the %s) for more info.

Monday, June 07, 2010

[link] VIM + ctags

Nothing new, yet useful to have for reference.

So can be useful at times.

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.

Thursday, April 29, 2010

vim vs. grep : external quickfix/error file

My usual trick of using vim with grep works well when single grep invocation is sufficient.

Yet quite often I end up piping one grep's output to another grep to refine the results. And that doesn't work with my old trick of wrapping the grep MethodName *.cpp into vim -c ":grep MethodName *.cpp" as the vim's internal grep doesn't support pipes.

Digging through the documentation I found that it is possible to accomplish and it fits well to my workflow.

Start grepping(*):

$ grep MethodName *.cpp # not fine enough...
$ grep MethodName *.cpp | grep -v rubbish # much better
    # and save to a file
$ grep -n MethodName *.cpp | grep -v rubbish > tmp1.out

N.B. -n to the grep is required as VIM needs line numbers to jump to the locations.

And now tell VIM to use the produced tmp1.out error file:

$ vim -q tmp1.out


$ vim -c ":cf tmp1.out"

or from inside running VIM:

:cf tmp1.out

Check the :h :cf for the official documentation.

(*) Obviously in the case it doesn't have to be grep - anything what produces similar output would do. I used once a perl script to generate VIM-compatible error file from diff output to preview potential merge conflicts.

Friday, April 16, 2010

Capture output of a command

I was playing around with ^K and wanted to see all possible combinations available. :help CTRL-K directed to the :digraphs command. The problem is that amount of output from :dig eclipses even that of the :set all.

So how one can somehow serialize the output into e.g. a VIM's buffer?

Search on the net unveiled the following tip:

:redir @a
:redir END

Or even cooler, putting the output into a variable:

:redir => varname
:redir END

followed by echo varname.

Final step is the dumping all that into a buffer/window: :put =varname.

P.S. The official Learn to use help article. Til now, I haven't knew that the :help could be abbreviated to the :h.

Monday, April 12, 2010

Save file owned by root

Have just seen the nice trick on the Interwebs.

It happens often: one starts editing a file owned by root. One gets used rather quickly to the VIM's warnings about editing a file one does not have permissions to. Only much later realizing that you can't save it.

So you opened a VIM and edited a file, but can't save it. Instead of saving a temp one can use the trick:

:w !sudo tee %

P.S. ZOMG PONYZ!!1 For what I was always adding a custom shortcut :map <F6> :b#<CR> turned out to have an official shortcut: ^6 (:help CTRL-6). In VIM 7.1, this is sole shortcut of the form CTRL-<number>.

Thursday, February 04, 2010

[link] Scripting the Vim editor, Part 3: Built-in lists

Scripting the Vim editor, Part 3: Built-in lists, part of Scripting the vim editor series over at IBM's dW.

Insightful read. Though I hope I would never need to script the VIM to such extent.