Emulating powerline with just Vim and tmux

tmux_featured

In a recent post, I looked into powerline, a bash status line utility. Powerline looks pretty cool, and I really wanted to run it, but try as I might, I just couldn’t get it working with my set up. Specifically, it doesn’t work really well with tmux. If you spend as much time on the command line as I do, them tmux is indispensable for serious work. That’s another post, but what I really want to talk about is how I emulated some of Powerline’s features using just the native tmux configuration. In addition, there’s a great Vim plugin, airline, which is sort of a vim only powerline. Using the combination of tmux and vim-airline gives me a status line that I’m really happy with.

Tmux configured and vim-airline running, as I write this post in Vim

Tmux configured and vim-airline running, as I write this post in Vim

First, installing vim airline is pretty straight forward, especially if you’re using something like pathogen or vundle. Details can be found on github: https://github.com/bling/vim-airline.

Now, once you have tmux installed, you can open up the tmux config file. If you’re on Linux, it should be /home/<username>/.tmux.conf. Here’s what’s in mine:

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
# Change control key to Ctrl-a
# It's just easier to get to for me.
unbind C-b
set-option -g prefix C-a
 
# Index windows from 0
set-option -g base-index 0
 
# Lower delay
set -s escape-time 1
 
# Silence bell
set-option -g visual-bell on
 
# Shortcut to reload config
# Keeps me from having to exit and restart whenever I make a config change.
bind r source-file ~/.tmux.conf \; display "Reloaded!"
 
# Bind Ctrl-a Ctrl-a to last window
bind-key C-a last-window
 
# Up the history limit
set-option -g history-limit 10000
 
# Change window-splitting commands
unbind %
bind | split-window -h
bind - split-window -v
 
# Vim style Movement commands
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
 
bind -r C-h select-window -t :-
bind -r C-l select-window -t :+
 
# Pane resizing commands
bind H resize-pane -L 5
bind J resize-pane -D 5
bind K resize-pane -U 5
bind L resize-pane -R 5
 
# Turn on mouse support
set-option -g mode-mouse on
set-option -g mouse-resize-pane on
set-option -g mouse-select-pane on
set-option -g mouse-select-window on
 
# 256 colors, this gives me real trouble, and I'm still not sure
# it's right
set -g default-terminal "xterm-256color"
# alternative copy mode key
bind Escape copy-mode
 
# pass through xterm keys
set -g xterm-keys on
 
# monitor activity in windows
setw -g monitor-activity on
 
# Here's where we get into the status line:
# These basically set the defaults
set-option -g status-utf8 on
set-option -g status-justify left
set-option -g status-bg black
set-option -g status-fg white
# Set the length of the left region to 40 characters
set-option -g status-left-length 40
 
set-option -g pane-active-border-fg green
set-option -g pane-active-border-bg black
set-option -g pane-border-fg white
set-option -g pane-border-bg black
 
set-option -g message-fg white
set-option -g message-bg red
 
setw -g window-status-bg black
setw -g window-status-current-fg red
#setw -g window-status-alert-attr default
#setw -g window-status-alert-fg yellow
 
# Here's where we set the actual display of the various regions
set -g status-left '#[bg=colour100]#[fg=black]#H:#[fg=white]#S#[fg=colour100] #[bg=black]?#[default]'
set -g status-right-length 100
# set -g status-right '#[fg=green]][#[fg=white] #T #[fg=green]][#[fg=blue]%Y-%m-%d #[fg=black]? %H:%M#[default]'
set -g status-right '#[fg=colour100]?#[bg=colour100] #[fg=black]#(weather.sh) ? ? %Y-%m-%d #[fg=blue]?#[bg=blue]#[fg=black] %H:%M #[default]'

The status-left and status-right options can interpolate string formats like so:
Character pair Replaced with
#(shell-command) First line of the command’s output
#[attributes] Colour or attribute change
## A literal `#’

So it’s pretty simple to have dynamic content or even the output of shell commands and scripts in there. I have a little script that outputs the current weather in mine.

The real magic takes place in the last 3 lines:

1
set -g status-left '#[bg=colour100]#[fg=black]#H:#[fg=white]#S#[fg=colour100] #[bg=black]?#[default]'

That line sets the background and font colors, displays the hostname, and the tmux session name. Then sets everything back to the default for the next region.

1
set -g status-right '#[fg=colour100]?#[bg=colour100] #[fg=black]#(weather.sh) ? ? %Y-%m-%d #[fg=blue]?#[bg=blue]#[fg=black] %H:%M #[default]'

That line does the same sort of thing. Sets background and font colors, then displays the output of my weather report script, then a little UTF-8 clock symbol and the date, then a background change and the time. Pretty cool, huh?

Here’s the weather script. Note that you’ll need to find your location code on your own. You can search around at: https://weather.yahoo.com/ to find it.

1
2
3
4
5
#! /bin/bash
# weather.sh
curl --silent "http://weather.yahooapis.com/forecastrss?w=12769077&amp;u=f" | awk -F '- ' '
/&lt;title&gt;/ { sub("&lt;/title&gt;", "", $2) &amp;&amp; l=$2 }
/&lt;b&gt;Forecast/ { getline; gsub("&lt;.*", "", $2); printf("%s: %s\n", l, $2); exit }'

And that, my friends, is how I got my badass status line going with nothing other than stock tmux and vim-airline. Frankly, I’d still like to get Powerline going, since it (supposedly) works with all kinds of other utilities. I’ve just never been able to get it going.