Tuesday, March 31, 2009

Windows Key Re-maps

On Windows, Vim has slightly different behavior for a few basic keys. Namely, ctrl-v, ctrl-x, and ctrl-z are re-mapped to make them more familiar to Windows users. Ctrl-v, which is probably the most widely used of these, is re-mapped to ctrl-q. To get the equivalent of a ctrl-z (background process), you can issue the :suspend ex command. I don't believe there are re-mappings for ctrl-a (add) and ctrl-x (subtract); although, you can probably override them in mswin.vim.

Survival Hacks

Many years back when I was first starting to get savvy with Linux, a co-worker approached me with a problem. He had yanked the harddrive out of his old Linux router and placed it in a different machine. The old machine had on-board ethernet and used a different driver than the new machine's PCI ethernet card. His only other computer was a laptop, which was currently offline due to the router issue. Thinking it would be an easy job, I downloaded a binary copy of the PCI driver and copied it onto a floppy at work. When I got to his house, I realized there was a bigger issue. My friend didn't have a monitor of any sort for the machine we'd be working on. We could have just given up and borrowed one from work the next day, but we decided to see how far we could get without one. We hooked up a keyboard and booted the machine waiting a few extra minutes to be sure we had a login prompt. From there, we very carefully logged in as root and mounted the floppy. The light on the floppy drive gave us a good indication that we were good so far. Not being able to remember the name of the driver forced me to do a glob copy based on the file extension to the /tmp directory, but again, the light on the floppy drive showed things were working. From there, we had another problem. We weren't sure if modprobe, the command to load a kernel module, would accept wildcards, so the globbing was no good this time. Still totally blind, I typed the following into the command line:

for I in *.ko; do modprobe ./$I; done

Fingers crossed, I hoped for the best and typed:

ifconfig eth0 192.168.0.1 netmask 255.255.255.0

From there, we plugged in his laptop, and tried to ping the machine. Much to our surprise, it was up and responding. Feeling accomplished, we did an ssh login from there, and got everything setup as it should be. Now, I'm not saying this was totally elite or anything, but it does go to show that a little creative thinking can get you pretty far. Feel free to share your own survival hacks in the comments if you have a similar story.

Friday, March 20, 2009

Out of the box Autocompletion

Thanks to Chris Sutter for contributing the following tip:

(The following applies to versions of vim higher than 7.0)

If you are editing a file in vim which ends with .php, .html, .css, .js, .sql, .rb, or .py, you can type (while in insert mode) ctrl-x followed by ctrl-o and vim's "omnifunc" feature combines with its built-in autocomplete feature to show autocomplete options specific to the corresponding language/markup. You can subsequently press ctrl-n and ctrl-p to browse through this list. In short, vim has autocomplete functionality for all common web development contexts (and probably some others) out of the box. But it's not just autocomplete.

If you are editing php (or, i imagine, ruby/python but i didn't try) and the text on which you are autocompleting is the beginning of a valid (builtin) function name, a small window will open at the top of your vim screen showing the method signature with argument names! No more jumping over to php.net to see if it's (needle, haystack) or (haystack, needle)...

Example:
Edit a file called foo.php, enter insert mode, type

<?php
str_r

Now press ctrl-x ctrl-o and vim shows a box below the cursor containing the following, with the first entry highlighted:

str_repeat( f
str_replace( f
str_rot13( f

The "f"s indicate that each entry is a function. If you had entered $_ and pressed c-x c-o, the results would have been "$_COOKIE", "$_ENV", and so on, labeled with "v" for variable)

The window opened above (since the selection is a function) shows:

str_repeat(string input, int multiplier | string

telling you the full function name, the argument types and names and finally the return type.

Admittedly, the c-x c-o and c-n/c-p stuff is awkward. I imagine you could remap to tab/shift-tab which is more common for autocompletion browsing in unix environments. The SuperTab plugin for vim does this for normal file-wise autocompletion (otherwise done in insert mode with c-n and c-p). It could probably be hacked to incorporate omnifunc stuff, too. If I see anything like that out there, I'll send something about it.

Please let me know if there's anything you think vim can't do and I'll see to ensuring you that, in fact, it can and it's easier than you think!

Tuesday, March 17, 2009

Vim + Cygwin Improvements

I've been stuck in a Windows environment at work for the last month or so doing Blackberry development. To try and make things more tolerable, I've been doing most of my work in a Cygwin environment; however, the Cygwin Vim build is sub-optimal compared to the native Windows build. This lead me to try and find a way to use Windows Vim seamlessly from inside Cygwin. The following alias worked out nicely:

[bash-fu borrowed from this tip]

alias vim='VIM=`cygpath -d "$VIM"` HOME=`cygpath -d "$HOME"` "`cygpath -u "$VIM"`/vim72/vim.exe"'

In this case, the $VIM environment variable is initially set to C:\Program Files\Vim. It's also important to change the vim72 version number to whatever matches your install.

The second thing I did, which is making life a lot easier, is switch to using Console2 as a replacement for the standard Windows cmd.exe. The combo of Console2, Cygwin, and a decent Vim build is a good bet if you're committed to Windows for whatever reason.

Tuesday, March 10, 2009

Change Last, First to First Last

Here's a tip borrowed from the Vim help file. Say that you have a list of names like:

Doe, John
Smith, Peter

and you want to change that to:

John Doe
Peter Smith

You can use the following substitute pattern to easily do so:

:%s/\([^,]*\), \(.*\)/\2 \1/

Basically, you're capturing zero or more NOT commas followed by a comma and space and then capturing zero or more of anything. The comma and space are outside the parens, so they're not stored. The parens store the captured groups in the special variables \1, \2, \3, \N from left to right, so the replacement pattern is substituting in the groups in the reverse order they were captured.

Monday, March 9, 2009

Tab Buffer Browsing

Using the following mappings in normal mode provides a convenient way to easily switch between the next and previous buffers.

nmap <tab> :bn<cr>
nmap <s-tab> :bp<cr>

Thanks to Chris for the tip!