Robot Has No Heart

Xavier Shay blogs here

A robot that does not have a heart

Vim and tmux on OSX

I recently switched from MacVim to vim inside tmux, using iTerm in full screen mode (Command+Enter). It’s pretty rad. I tried screen first, but even after a lot of screwing around there was still a lot of brokeness, and I don’t like how it does split panes anyways. Follows are some notes about what is required for tmux.

Get the latest vim and tmux

Latest vim required for proper clipboard sharing, if you don’t want to install it you can use the pbcopy plugin mentioned below.

1
2
brew install --HEAD vim
brew install tmux

Set up pretty colors

my vim/tmux setup

I use the solarized color scheme. To make this work, ensure you are not overriding the TERM variable in your .{bash|zsh}rc, then create an alias for tmux:

1
2
# .zshrc
alias tmux="TERM=screen-256color-bce tmux"

I also have a tmux config:

1
2
# .tmux.conf
set -g default-terminal "screen-256color"

Clipboard sharing

Up until I wrote this blog post, I had been using the pbcopy plugin to share clipboard using a cute hack involving ssh’ing back into your machine to run pbcopy/pbpaste. In researching some more details on this though I found an excellent write up of the problem and a far better solution by Chris Johnsen that enables proper sharing without ssh’ing, and therefore also the * register (use "*y to copy, "*p to paste – note this does not work with the vim that ships with OSX).

Mouse integration

The mouse is good for two things: scrolling, and selecting text from your scrollback.

For the first, put the following config:

1
2
# ~/.tmux.conf
set -g mode-mouse on

For the second, hold the option key while you select.

Workflow

Find another reference for basic keys, this here are notes on top of that. Ctrl-B sucks as an escape sequence, rebind it to Ctrl-A to match screen. Most online references don’t mention it, but the default binding for horizontal split is prefix " (it’s in the man page). I tend to have a main pane for editing and a smaller pane for a REPL or log. If I need to investigate the smaller pane, I press Ctrl-A Ctrl-O, which switches the two panes to give me the log in the larger one.

I use the tslime.vim plugin to send text directly from vim to the supplementary pane. This is a killer feature. As well as the built in Ctrl-C shortcut, I also use a trick I learned from Gary Bernhardt and remap <leader>t on the fly to send whatever command I am currently testing to the other pane. Some examples:

1
2
3
4
; Load a file into a clojure repl
:map ;t :w\|:call Send_to_Tmux("\n\n\n(load-file \"./myfile.clj\")\n")<CR>
; Run rspec in zsh
:map ;t :w\|:call Send_to_Tmux("rspec spec/my_spec.rb\n")<CR>

If I need to interact with a shell I’ll usually Ctrl-Z vim, do what I need to do, then fg back again. If it’s a context switch, I’ll start a new tmux window then exit it after I’m done with the distraction.

I don’t use sessions. I prefer setting up from scratch each time since it takes no time at all, and eases my brain into the problem. Clean desk and all that.

That’s it. Nothing too fancy, but I’ve been meaning to make the switch from MacVim for a while and with this set up I can’t ever see myself going back.

Formatting ruby hashes in VIM

I’ve been meaning to write this script for a while. If you’re anal about your whitespace (like I), you’ll often pretty up your ruby hashes to make them easy to read by adding a bit of whitespace to the keys before the =>. I wrote a ruby script to do this automatically!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/usr/bin/env ruby

# format_hash.rb
#
# Formats ruby hashes
# a => 1
# ab => 2
# abc => 3
#
# becomes
# a   => 1
# ab  => 2
# abc => 3
#
# http://rhnh.net

lines = []
while line = gets
  lines &lt;&lt; line
end

indent = lines.first.index(/[^\s]/)

# Massage into an array of [key, value]
lines.collect! {|line| 
  line.split('=>').collect {|line| 
    line.gsub(/^\s*/, '').gsub(/\s*$/, '') 
  }
}

max_key_length = lines.collect {|line| line[0].length}.max

# Pad each key with whitespace to match length of longest key
lines.collect! {|line|
  line[0] = "%#{indent}s%-#{max_key_length}s" % ['', line[0]]
  line.join(' => ')
}

print lines.join("\n")

Put that in your path, then in VIM you can run the following command to format the current selection:

:‘<,’>!format_hash.rb

  1. Or map F2 to do it for you…
    :vmap <F2> !format_hash.rb<CR>
    -

The Switch to VIM

I’m been meaning to try out Vim for a while, especially since I now use two different platforms/editors for development (mac/textmate at work, linux/jedit at home). Finally got some time to try it out this weekend, and initial reports are positive! The thing that strikes me the most is how quickly you can navigate/select things without using the mouse. Vim’s navigation shortcuts are like CTRL-(LEFT|RIGHT) on crack. Regex search forward and back, move by multiple lines, seek to next/prev char. I haven’t internalized this navigation yet and already I’m loving it. Give me some experience and I’ll become an absolute machine. It’s a bit weird because I’m using colemak, so the “stick to the home row” mantra doesn’t really apply, but overall it’s still quite bearable. I need to figure out how to replicate the Apple-T shortcut in textmate (quick swith to file) and I think I’ll be sold. I’ll use it at work for the week and see how things go. For reference, I found the tutorial on the vi-improved site to be quite helpful.

A pretty flower Another pretty flower