Binding Caps-lock to Control and Escape

As a Vim user, the ESC key is an important one. To do Vim the proper way you’re constantly switching in and out of insert mode. The escape key, however, is a fair distance from the fingertips of most typists. The caps-lock key is the polar opposite – it’s rarely useful, yet in a prominent position on the keyboard.

Many developers rebind their caps-lock key to control. Control is used fairly often (particularly for those spending hours in a shell), but sometimes awkward to reach, especially on laptop keyborads.

On Mac OS X, using the aptly-named KeyRemap4MacBook, you can solve these two problems in one by binding the caps-lock key to escape if pressed alone, or to control if pressed in combination with another key.

In OS X’s keyboard settings, bind caps-lock to control:

Then, in KeyRemap4MacBook’s preferences, enable this setting:

This post was contributed by @mark_js.

comments powered by Disqus… Click Here

Recording Macros for Super Efficiency

Macros in Vim can be a great time saver, especially for complex and repetitive line-editing tasks. A macro is a way of recording a series of actions as a single command. I find this especially useful when I need to make some formatting changes to a set of lines. This is perhaps best illustrated by an example, but prior to that let us quickly look at the syntax for recording and using macros in Vim.

Recording a macro is split into three steps:

q followed by a letter to start recording. The letter can be any valid register of your choice, e.g. m. If successful you will see recording in the bottom left of the screen.
Carry out whichever actions you require. This isn’t constrained to just one line of actions, though often this is practical.
Press q again to stop recording.

Using a macro is simply a case of typing @ followed by the register character chosen, m in the previous example.

A brief example

An example may make the benefits of macros clearer. Let’s say that we have the following data in a file and we want to transform this into a CSV file. This chunk of data is from a wireless sensor network log file that really did need converting to CSV.

StandDev (ToF): 2260ps, Mean (ToF): 64037ps, Errors: 0
StandDev (ToF): 2265ps, Mean (ToF): 66037ps, Errors: 0
StandDev (ToF): 2184ps, Mean (ToF): 82858ps, Errors: 1
StandDev (ToF): 3184ps, Mean (ToF): 82860ps, Errors: 1
StandDev (ToF): 1439ps, Mean (ToF): 55893ps, Errors: 0
StandDev (ToF): 2439ps, Mean (ToF): 75893ps, Errors: 3

We can change this to form part of a CSV file with a quick macro:

  • Move to the first line we wish to edit (remember, the macro will capture all commands, so if you execute a move command in your macro it will happen on each run).
Click Here

Awesome JS Auto Completion

One area that Vim often falls down compared to other editors is in auto completion and for a while I’ve been looking at ways to improve it.

Today I came across YouCompleteMe, a code completion engine for Vim. It works best with C languages as it provides an engine to provide completition, but it is also able to hook into Vim’s omnicomplete to provide completion for languages like Ruby, Python, JavaScript, and so on. As I work in Ruby & JavaScript 99% of the time, that was what interested me most.

Installing YouCompleteMe isn’t the easiest – there’s an extra step to take after installing it, which is done through something like Vundle or Pathogen.

I won’t repeat the entire instruction guide – it’s in the README, but for me it was a case of:

  • Install the plugin with Pathogen
  • brew install cmake
  • cd ~/.vim/bundle/YouCompleteMe && ./install.sh

The README also says you should use the latest MacVim on OS X, but I use terminal Vim and didn’t have any problems. YMMV.

Once you’ve done that you’ll get autocompletion, although it won’t be at all intelligent. That’s where TernJS comes in. This is a project to provide better JS support within editors – and so far there are plugins for Vim, Emacs and Sublime Text 2. When installed, it hooks into Vim’s omnicomplete and updated it, and then YouCompleteMe picks it up.

Once again, there’s an extra installation step here. Install the plugin as normal with Vundle/Pathongen/etc, and then you’ll need to take some extra steps.… Click Here

Easier Reindenting

With a visual selection you can use < to indent left by 1 tab (or spaces, depending on your settings) and > to indent right by 1 tab. And of course we can prepend these with a motion to indent more than one tab at a time, such as 3>.

But what if you’re not sure how many you want to indent by? You can guess a number and then alter it after that, but that’s not efficient. You can use gv to select the previous visual selection, so what I tend to do is make a selection, and use < or >. If I need to indent again, I can do gv> to indent the same selection 1 more to the right.

From this, I decided to map < and to do this for me automatically:

" reselect visual block after indent/outdent
vnoremap < <gv
vnoremap gv

This means that when I run >, the selection I indented is selected for me again, so I can then keep hitting > however many times I need to get the code indented just right. This is one of my favourite snippets in my .vimrc.

Note: it’s been pointed out to me that instead of this I could just use the dot command (.), which repeats the last change. Normally I do, but in this instance I found it much easier to add the mapping above.

comments powered by Disqus… Click Here

Ruby text objects

Yesterday I discovered a text object within Vim that I’d not realised existed, which served as a perfect tip post up onto this blog (and to try and get back to doing it more regularly!).

Any seasoned Ruby + Vim user has probably got Drew Neil’s textobj-rubyblock plugin installed, which adds the text objects ar and ir to select around and inside a ruby block.

However, what I didn’t know about was the text object im, which is provided by vim-ruby (which comes with Vim by default), to select the contents within the current Ruby method, and its sibling am, to select around the method. Hat tip to @tomstuart for that one:

It took me a few minutes to work out how to select the body of a Ruby method in Vim, but I was happy when the answer turned out to be “vim”.

— Tom Stuart (@tomstuart) July 17, 2014
Drew Neil (@nelstrom)) then followed up explaining that it was recently added to vim-ruby:

@telemachus it’s a text object defined in the vim-ruby plugin: https://t.co/YZSmUPWr0P Should be available out the box in recent Vim builds.

— Drew Neil (@nelstrom) July 17, 2014

If you’re running a recent version of Vim you should have this functionality, but if you’re not, you can always install the latest version of vim-ruby as a plugin through Vundle / Pathogen. The best solution though if possible is to simply upgrade your Vim.

Whilst reading to produce this blog post I also discovered the objects iM and aM, which select in and around the current Ruby class, too.… Click Here

Deleting Lines that don’t Match a Pattern

Something that I found out last night at the Vim London Meetup that was demonstrated by Drew Neil was the ability to delete lines in your file that don’t match a particular pattern. All credit for this tip goes to Drew – I’m just typing it up on here!

Say we have a file that has lines that look a bit like this (I had to do this earlier today):

calculate
something_else
calculate
something_else
calculate
something_else
calculate
some_other_thing
calculate
some_more_things
calculate
some_other_things
something_else
something_else

And we want to delete all lines that don’t contain calculate. We can do that with :v. Simply running:

:v/calculate/d

Leaves me with:

calculate
calculate
calculate
calculate
calculate
calculate

This is part of the :global command.

Thanks again to Drew for demonstrating this! If you’re London based, I highly recommend making an effort to attend the meetups. They are completely free and I never come away from one without at least one new trick or tip that improves my usage of Vim.

comments powered by Disqus… Click Here

Swapping Pathogen for Vundle

I’ve been a big fan of Tim Pope’s pathogen for managing my Vim plugins. I wrote a small Ruby script to manage the process of cloning from GitHub, and everything was fine.

However, recently, a lot of people have been talking about Vundle. Vundle takes the process of cloning repositories and manages it all for you, so there’s a lot less work for you to do manually.

The process of setting up Vundle is very straight forward. Firstly, clone Vundle:

git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle

Now it’s just a case of editing your vimrc. Vundle requires you to add a few lines to your vimrc file. Make sure these lines are at the very top:

set nocompatible
filetype off
set rtp+=~/.vim/bundle/vundle/
call vundle#rc()

Vundle requires filetype to be off initially, but once you’re finished adding Bundles, you can set it to be on again. Next, load in some bundles. Note that you have to load in the vundle repo first:

Bundle 'gmarik/vundle'
Bundle 'tpope/vim-endwise'
Bundle 'tpope/vim-git'
Bundle 'tpope/vim-surround'
...and so on...

Vundle will look on GitHub by default for those URLs, but you can also pass it a direct Git URL or even a local Git path.

After all your Bundle calls, you are free to add whatever you like to your vimrc, including setting filetype back to on:

filetype on

Now, you can install your plugins by running :BundleInstall within Vim (you’ll need to restart Vim or source your vimrc once more before). In the future, if you want to update your plugins, you can run :BundleInstall!… Click Here

Jumping to last cursor position

When I open a file, I like the cursor to jump to the position it was in last time I had the file open. This can be achieved by adding the following snippet to your .vimrc:

augroup vimrcEx
  autocmd!
  autocmd BufReadPost *
    \ if line("'\"") 0 && line("'\"") <= line("$") |
    \   exe "normal g`\"" |
    \ endif
augroup END

You can collapse that autocmd statement onto a single line, removing the \s if you like, but I think it’s more readable this way.

The various conditions in the if statment ensure that the line position is still valid, in case the file has been changed by some other means since it was last open (think version control!). Credit goes to Gary Bernhardt for this.

I’ve had this in my .vimrc for a while, and it’s been working great, but there’s one thing about it that has been winding me up about it: whenever I write or edit a git commit message, I don’t want this behaviour. The problem arises from the fact that all git commit messages are in the same “file” as far as vim is concerned. Today I finally snapped, and added the following snippet to handle this:

augroup gitCommitEditMsg
  autocmd!
  autocmd BufReadPost *
    \ if @% == '.git/COMMIT_EDITMSG' |
    \   exe "normal gg" |
    \ endif
augroup END

You could probably roll both of the above snippets into one if you’re that way inclined, but I’m happy keeping them separate. It makes it easier to see what’s going on, and it’ll be easier to change if I ever want to modify the behaviour in the future.… Click Here

Tmux and Vim: the perfect combination

Last night at Vim London I spoke about some of my favourite plugins and settings for Tmux and Vim that allow me to work with them as I do. It’s very rare these days that I won’t be editing code from Vim, within a Tmux session, but out of the box the immediate advantages of this pairing are not always obvious. It takes some time to get things working.

The talk was recorded and I will update the post with it once it’s public, but for now I just wanted to link to some of the plugins and settings I mentioned in the talk that I use in my dotfiles.

tnew alias

I create all my tmux sessions through an alias I have which I’ve called tnew, which simply calls a function called new-tmux-from-dir-name (this is taken from the thoughbot dotfiles. The function looks like so:

sh function new-tmux-from-dir-name { tmux new-session -As `basename $PWD` }

This does two things: – when you create a new session, it names it based on the directory name – if you are in a directory that already has a tmux session associated, tnew will attach you back into the already existing session

Tmux + OS X, pbcopy

By default tmux on OS X breaks the pbcopy command. I’m not going to go into details, but thankfully Chris Johnsen’s fix

has detailed instructions on how to get that functionality back, and it’s not too tricky either.

Renumber windows

Out of the box, if you have 3 tmux windows numbered 0, 1, 2 and then you delete the one numbered ‘1’, you’re left with two windows: 0, and 2.… Click Here

Swapping background quickly

I often like to change the background from light to dark or vice-versa depending on my environment. I use the Solarized theme and it comes with two lovely variants, light and dark.

I used to do this by manually entering:

:set background=light

But why do that when it’s easy to set up a mapping to toggle them automatically for you:

map <Leaderbg :let &background = ( &background == "dark"? "light" : "dark" )<CR

Now it’s a simple case of ,bg (I have my leader set to ,) to toggle the background.

comments powered by Disqus… Click Here