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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
|
---
title: The Text Triumvirate
date: 2012-04-28T02:48:34Z
source: http://www.drbunsen.org/the-text-triumvirate/
tags: work, software, minimalism
---
### The Triumviri
In 62 BC, [Caesar][1] united a political alliance between himself, the statesman [Crassus][2], and the military general [Pompey][3]. Together, the three men formed a secret political faction called the [Triumvirate][4] that ruled the [Roman Republic][5]. The Text Triumvirate is an alliance between the [zsh][6], [vim][7], and [tmux][8]. Each of these venerable tools is extremely powerful in its own right; however, together they are an unmatched productivity force that rules all forms of text manipulation. This post aims to provide an overview of how to create a highly functional and easy to configure Text Triumvirate for those new to this tool chain. I try to focus on aspects of how to integrate zsh, vim, and tmux with particular focus on my experiences with two common problems—copy/paste functionality and color aesthetics.
* [Opinions][9]
* [Aesthetics][10]
* [Setup][11]
* [zsh][12]
* [vim][13]
* [tmux][14]
* [Plug-ins][15]
### Opinions
[Just like Rands][16], I'm rabid foaming at the mouth crazy about my tools. I think the Text Triumvirate is the most powerful tool chain available for text manipulation. If you don't use this tool chain, I would encourage you to drink the Kool-Aid and try the Text Triumvirate. I think you owe it to yourself if you spend hours each day wrangling text. At first it may be awkward to switch tools, but your diligence will be rewarded. The benefits to using zsh, vim, and tmux is that they are free, fast, endlessly customizable, work on any operating system, function in remote environments, are capable of remote [pair programming][17], and are deeply integrated with one another and all of Unix. The net result is greater efficiency and organization with all things text. The tool chain can be managed entirely by [git][18] and cloned onto a remote server or a new machine within a few seconds. Together, these advantages have made me a faster and more productive writer and coder.
One of the great advantages to the Text Triumvirate is the ubiquitous use of the split model for managing working environments. Split model management allows tmux to act as glue to organize work flows. I find by the end of a day I usually have several shell windows and a huge number of scratch files, data files, source code files, documentation files, and databases open. It's a huge pain to close each window only to come back the next day to open all the same files again. tmux and vim allows dozens of panes and windows to be open around a particular project and if you wish to switch to working on an entirely different project you can detach from those windows, go to another project, and then reattach to your first project in the same state you left it. I generally have multiple projects for both work and personal that I'm working on at a given time. The ability to attach and detach for working environments is essential.
Where we are going—zsh and vim wrapped in tmux [awesome sauce][19]:
![tmux_screen][20]
The tmux session above has three windows named demo, docs, and scatch, however only the top most demo window is visable in the screenshot. In this window there are four splits. The top left split is a Z-shell window, the bottom left window has an interactive python session, the top right window is running vim with python code, and the bottom right window contains markdown documentation.
### Aesthetics
I suggest setting up the Text Triumvirate with two color themes—one theme for work projects and another theme for personal projects. I make heavy use of [context-dependent memory][21], so using two themes helps me a great deal with cognition and demarcating work projects from personal projects. Below is what my personal theme (left) and work theme (right) look like. Both themes are versions of Ethan Schoonover's [solarized][22] project. I use the dark theme for play because I usually work on my own projects in the morning or evening when it's dark outside. A dark theme is much easier on my eyes at these times. For fonts, I used 14 point [Inconsolata][23].
![zsh][24]
### Setup
The first thing to do is [remap the Capslock key][25] to the Control key. The Capslock is a [vestige from the past][26] and it's important to make better usage of the valuable keyboard real estate. tmux in particular makes heavy usage of the Control key, so it's helpful to remap Control to a more ergonomic position.
To generate a respectable working environment for the Triumvirate, download the [iTerm2][27] terminal emulator. iTerm2 has a number of performance enhancements, features, and customizations over the stock Terminal.app. Once you start using iTerm2, go back and read the [full docs][28] to see its capabilities. One useful feature is `Command-?`, which overlays a nice visual for finding your current cursor position quickly. Most of iTerm2's really cool features are outside the scope of this post. Make sure you check out iTerm2's instant replay, regex search, click to open URLs, and jump to mark features.
Once iTerm2 is installed, add both light and dark solarized themes. The solarized repo has iTerm2 color palettes and [instructions][29] for configuring the themes in iTerm2, so it's straight-forward to setup. Another helpful iTerm2 configuration is to enable a system-wide key-binding that bring iTerm2 forward to the front most window. I find it faster to setup an explicit binding rather than using the Application Switcher to toggle through applications. This shortcut is set in `Preferences > Keys` and I use `Option-t` as my binding. The other customization I would suggest is to uncheck the iTerm2 bell sound under `Profiles > Terminal > Notifications`.
Since the Text Triumvirate is highly keyboard-centric, it is prudent to map out a sane key-binding strategy for iTerm, zsh, vim, tmux, and any other tools you use before configuring and committing your own bindings to muscle memory. For window movements, I use the Option key. `Option-t` brings iTerm2 to the front, `Option-i` brings Twitter to the front, etc. I also use [Moom][30] as my tiling manager on OS X with all shortcuts configured with the Option key to send windows to specific displays or destinations on the screen.
Next up, install [Homebrew][31] and then use Homebrew to install git, MacVim, tmux, and reattach-to-user-namespace. The purpose of installing MacVim is twofold. For one, the default vim that ships with OS X seems slow for a lot of people. I've found using the vim distribution that ships with MacVim to be much faster than the OS X version. The added advantage of installing MacVim is you will get a newer version of vim on your system. Secondly, copy/paste do not work optimally with the version of vim that ships with OS X.
Once git is installed, initialize a new repo for storing the Text Triumvirate config files. My repo is called _dotfiles_ and contains all my configurations for zsh, vim, and tmux. Read [Pro Git][32] or [Git Immersion][33] if you don't know how to setup version control for your files.
### zsh
Many great posts have been written about how to use zsh and why zsh is superior to bash. zsh basically has all of the functionality of bash as well as quite a few additional features. I use zsh over bash because it has extended globbing, superior tab completion, built-in spell correction, a better calculator (zcalc), and a built-in batch file renaming tool (zmv). The other killer zsh feature is [oh-my-zsh][34]—a community driven framework for zsh. oh-my-zsh comes prepackaged with very nice themes, plugins, and customizations that make zsh extremely powerful. If you take away nothing else from this post install iTerm2 and use zsh as your default shell.
I store my .zshrc, .vimrc, and .tmux.conf configuration files within my dotfiles directory and then symlink them to my home directory. This approach allows zsh, vim, and tmux customizations to be maintained all in one directory under version control. Since the Text Triumvirate uses vim, it makes sense to setup zsh and tmux to also use vim and vim key bindings and use vim as the default editor. Add these lines to the .zshrc file for vim support in zsh:
export EDITOR="vim"
bindkey -v
# vi style incremental search
bindkey '^R' history-incremental-search-backward
bindkey '^S' history-incremental-search-forward
bindkey '^P' history-search-backward
bindkey '^N' history-search-forward
While zsh supports most bash commands, it also supports a more intelligent collection of commands. For example, if you want to move inside a directory in bash you would type `cd foo`. In zsh you can just type `foo` if you add this line to your .zshrc:
To setup a nice prompt, I used [Steve Losh's excellent prompt][35] as a guide and then made a few minor modifications. Simply create a new theme file within `oh-my-zsh/themes/` and add a line to your zshrc file referencing the name of your theme (`ZSH_THEME=bunsen`). Here is my version of Steve's prompt:
function virtualenv_info {
[ $VIRTUAL_ENV ] && echo '('`basename $VIRTUAL_ENV`') '
}
function box_name {
[ -f ~/.box-name ] && cat ~/.box-name || hostname -s
}
PROMPT='
%{$fg[magenta]%}%n%{$reset_color%} at %{$fg[yellow]%}$(box_name)%{$reset_color%} in %{$
fg_bold[green]%}${PWD/#$HOME/~}%{$reset_color%}$(git_prompt_info)
$(virtualenv_info)%(?,,%{${fg_bold[blue]}%}[%?]%{$reset_color%} )$ '
ZSH_THEME_GIT_PROMPT_PREFIX=" on %{$fg[magenta]%}"
ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[green]%}!"
ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[green]%}?"
ZSH_THEME_GIT_PROMPT_CLEAN=""
local return_status="%{$fg[red]%}%(?..⤬)%{$reset_color%}"
RPROMPT='${return_status}%{$reset_color%}'
### vim
I'm going to focus specifically on aspects of integrating vim with the Text Triumvirate rather than vim itself. To get solarized integration with vim, install the [vim solarized plugin][36] and then append these lines to your vimrc:
syntax enable
let g:solarized_termtrans = 1
colorscheme solarized
togglebg#map("")
Color management in the terminal can be tricky. On my system, I had to explicitly add `let g:solarized_termtrans = 1` to get the proper color rendering in terminal vim. Solarized provides a built in background function to toggle light and dark themes using the `` function, so if you want this functionality add the last line. Inside vim you can also run `:set background=dark` or `:set background=light` to achieve the same functionality.
vim handles copy/paste somewhat differently than GUI-based text editors. Instead of a single copy/paste system, vim has numerous copy registers and a couple paste modes. I've added the following lines to my vimrc to make copy/paste with the system more intuitive.
" Yank text to the OS X clipboard
noremap y "*y
noremap yy "*Y
" Preserve indentation while pasting text from the OS X clipboard
noremap p :set paste:put *:set nopaste
The above mappings make using the OS X system clipboard much more accessible. The first two commands yank selected text or a line into the system clipboard, respectively. The last line maintains the formatting of text pasted into vim. In practice I don't find that I paste a great deal of text in and out of vim. If I need to share code I usually use the [vim gist plugin][37], which is faster than copy/paste.
### tmux
tmux is the glue that holds the Text Triumvirate together. I've only started using tmux within the last month, but I'm amazed at how indespensible it now is to my workflow. Here is the wikipedia description of tmux:
> tmux is a software application that can be used to multiplex several virtual consoles, allowing a user to access multiple separate terminal sessions inside a single terminal window or remote terminal session. It is useful for dealing with multiple programs from a command line interface, and for separating programs from the Unix shell that started the program.
Essentially, tmux allows you to create _sessions_, which you can attach and detach from whenever you like. tmux is invaluable because you can organize your work contextually.
Just like vim, the most difficult aspects of setting up and using tmux is color management and copy/paste functionality with the system clipboard. It's straight forward to generate the proper solarized colors by making sure tmux knows you are using 256 colors. Add this line to your tmux.conf file:
set -g default-terminal "screen-256color"
For copy/paste, tmux has a special copy mode. Copy mode tmux commands start with a prefix key. By default the tmux prefix key is `Control-b`. Most people, myself included, remap the prefix to `Control-a` because it's much easier to touch type and it is also the default binding of GNU screen. When you see me refer to `prefix` below, it means `Control-a`. So ` c` means: type `Control-a` and then `c`.
Copy/paste inside tmux is completely broken on OS X. Fortunately, Chris Johnsen created a nice patch called [reattach-to-user-namespace][38] that is easy to install via Homebrew. The people at [Thoughtbot][39] have a number of helpful blog posts explaining how to use tmux and how to get copy/paste functionality working (see [here][40] and [here][41]). Even with these instructions I didn't initially grasp how to use tmux with the OS X clipboard system, so here's what you need add to your tmux.conf file after reattach-to-user-namespace is installed:
set -g default-command "reattach-to-user-namespace -l zsh"
set -g mode-mouse on
setw -g mouse-select-window on
setw -g mouse-select-pane on
# Copy mode
setw -g mode-keys vi
bind ` copy-mode
unbind [
unbind p
bind p paste-buffer
bind -t vi-copy v begin-selection
bind -t vi-copy y copy-selection
bind -t vi-copy Escape cancel
bind y run "tmux save-buffer - | reattach-to-user-namespace pbcopy"
The first line configures tmux to use the wrapper program to start zsh for each new tmux window that is opened. The next three lines are my personal preferences for mouse handling inside tmux. You can keep or discard these lines depending on your preferences. The real meat and potatoes are the next ten lines that deal with copy mode.
tmux has it's own copy/paste buffers in addition to the vim copy/paste buffers, and OS X copy/paste. To work efficiently with tmux buffers, enter copy mode with ` ``. I've remapped the default copy bindings to use the analgous vi bindings. To place text into a tmux copy/paste buffer, enter copy mode and select the text to copy using `v` to make a selection and then `y` to yank the selection. At this point, the text is in a tmux copy/paste buffer. Running ` p` will paste the text. However, if you want the text in the OS X copy/paste buffer, run ` y`.
### Plug-ins
I would be remiss if I didn't mention some of the incredible open source projects that integrate especially well the Text Triumvirate. Rather than explaining each tool in-depth, here are links to some of my favorite projects with abridged descriptions:
* [Ack][42]—better than grep
* [Autojump][43]—directory navigation
* [Command-t][44]—vim plugin for fuzzy search; (link to setting up with tmux)
* [Formd][45]—my own markdown link formatting tool for prose
* [Pandoc][46]—markup format conversion
* [Poweline-vim][47]—customized vim statusbar
* [Pianobar][48]—terminal Pandora music player
* [pdfgrep][49]—grep for PDF files
* [shelr][50]—screen recording in the shell
* [vimux][51]—interact with tmux from vim
* [virtualenv][52]—Python virtual environment builder
* [wemux][53]—multi-user multiplexing
* [yadr][54]—an opinionated zsh, MacVim, and git configuration
### Update
Several people have contacted me asking how to setup tmux with the attractive status bar I displayed in the above screenshot. I learned how to do this from the [wemux project][53]. Assuming you have installed [vim-powerline][47] and are using patched fonts, you can simply append the following lines your your `.tmux.conf` file to get my status bar style. Thanks [Matt Furden][55]!
set -g status-left-length 52
set -g status-right-length 451
set -g status-fg white
set -g status-bg colour234
set -g window-status-activity-attr bold
set -g pane-border-fg colour245
set -g pane-active-border-fg colour39
set -g message-fg colour16
set -g message-bg colour221
set -g message-attr bold
set -g status-left '#[fg=colour235,bg=colour252,bold] ❐ #S
#[fg=colour252,bg=colour238,nobold]⮀#[fg=colour245,bg=colour238,bold] #(whoami)
#[fg=colour238,bg=colour234,nobold]⮀'
set -g window-status-format "#[fg=white,bg=colour234] #I #W "
set -g window-status-current-format
"#[fg=colour234,bg=colour39]⮀#[fg=colour25,bg=colour39,noreverse,bold] #I ⮁ #W
#[fg=colour39,bg=colour234,nobold]⮀"
[1]: http://en.wikipedia.org/wiki/Julius_Caesar
[2]: http://en.wikipedia.org/wiki/Marcus_Licinius_Crassus
[3]: http://en.wikipedia.org/wiki/Pompey
[4]: http://en.wikipedia.org/wiki/First_Triumvirate
[5]: http://en.wikipedia.org/wiki/Roman_Republic
[6]: http://www.zsh.org/
[7]: http://www.vim.org/
[8]: http://tmux.sourceforge.net/
[9]: http://www.drbunsen.org#opinions
[10]: http://www.drbunsen.org#aesthetics
[11]: http://www.drbunsen.org#setup
[12]: http://www.drbunsen.org#zsh
[13]: http://www.drbunsen.org#vim
[14]: http://www.drbunsen.org#tmux
[15]: http://www.drbunsen.org#plugins
[16]: http://www.randsinrepose.com/archives/2009/11/02/the_foamy_rules_for_rabid_tools.html
[17]: http://en.wikipedia.org/wiki/Pair_programming
[18]: http://git-scm.com/
[19]: http://www.urbandictionary.com/define.php?term=awesome+sauce
[20]: http://farm8.staticflickr.com/7096/7090273507_293daf55c0_b.jpg
[21]: http://en.wikipedia.org/wiki/Context-dependent_memory
[22]: http://ethanschoonover.com/solarized
[23]: http://levien.com/type/myfonts/inconsolata.html
[24]: http://farm8.staticflickr.com/7205/7080277925_db8735899d_b.jpg
[25]: http://www.drbunsen.org/remap-capslock.html
[26]: http://capsoff.org/history
[27]: http://www.iterm2.com/
[28]: http://www.iterm2.com/#/section/documentation
[29]: https://github.com/altercation/solarized/tree/master/iterm2-colors-solarized
[30]: http://manytricks.com/moom/
[31]: http://mxcl.github.com/homebrew/
[32]: http://progit.org/book/
[33]: http://gitimmersion.com/
[34]: https://github.com/robbyrussell/oh-my-zsh
[35]: http://stevelosh.com/blog/2010/02/my-extravagant-zsh-prompt/
[36]: https://github.com/altercation/vim-colors-solarized
[37]: https://github.com/mattn/gist-vim
[38]: https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard
[39]: http://thoughtbot.com/
[40]: http://robots.thoughtbot.com/post/2641409235/a-tmux-crash-course
[41]: http://robots.thoughtbot.com/post/2166174647/love-hate-tmux
[42]: http://betterthangrep.com/
[43]: https://github.com/joelthelion/autojump/wiki/
[44]: https://wincent.com/blog/tweaking-command-t-and-vim-for-use-in-the-terminal-and-tmux
[45]: http://www.drbunsen.org/formd-a-markdown-formatting-tool.html
[46]: http://johnmacfarlane.net/pandoc/
[47]: https://github.com/Lokaltog/vim-powerline
[48]: http://6xq.net/projects/pianobar/
[49]: http://pdfgrep.sourceforge.net/
[50]: https://github.com/antono/shelr
[51]: https://github.com/benmills/vimux
[52]: https://github.com/pypa/virtualenv
[53]: https://github.com/zolrath/wemux
[54]: http://skwp.github.com/dotfiles/
[55]: https://github.com/zolrath
|