Table of Contents
Problem
I recently wanted to show git branch and status information of the project I am wokring on in tmux statusbar.
We can use one of the many open source projects to achieve this (see the Conclusion for honorable mentions), but I prefer a minimalist approach for simplicity and portability.
Naturally, I know I can invoke any shell command from my .tmux.conf
using the #(<shell command>)
syntax.
For example, set -g status-right '#(echo "hello world")'
will print hello world
in the right corner of your tmux statusbar, which is located at bottom
by default.
But, doing something like set -g status-right '#(git branch)'
didn't work. This is because the command is running in a different shell context, like running sh -c "git branch"
. The current directory is simply not passed to the sub-shell command.
Furthermore, git branch
only prints the branch name. We need a custom bash function to print symbols indicating if there are modified files, staged files, stashes, and/or untracked files.
Solution
Similar to how you can print any information in a .bash_prompt
via custom bash functions, so too can we implement a function that is invoked as a git sub-command via aliases.
Bash Function
The function we will use for this is borrowed from jessfraz/dotfiles.
If we simply join all the lines and escape the double-quotes, it looks like this:
prompt_git() { local s=''; local branchName=''; if [ \"$(git rev-parse --is-inside-work-tree &>/dev/null; echo \"${?}\")\" == '0' ]; then if [ \"$(git rev-parse --is-inside-git-dir 2> /dev/null)\" == 'false' ]; then if [[ -O \"$(git rev-parse --show-toplevel)/.git/index\" ]]; then git update-index --really-refresh -q &> /dev/null; fi; if ! git diff --quiet --ignore-submodules --cached; then s+='+'; fi; if ! git diff-files --quiet --ignore-submodules --; then s+='!'; fi; if [ -n \"$(git ls-files --others --exclude-standard)\" ]; then s+='?'; fi; if git rev-parse --verify refs/stash &> /dev/null; then s+='$'; fi; fi; branchName=\"$(git symbolic-ref --quiet --short HEAD 2> /dev/null || git rev-parse --short HEAD 2> /dev/null || echo '(unknown)')\"; echo \"(${1}${branchName} ${s})\"; else return; fi; }
Git Alias
Now, you can put this one-liner into a git alias in your .gitconfig
or ~/.config/git/config
, like this:
[alias]
prompt = !"prompt_git() { ... }; prompt_git"
Tip: alternatively, you can copy/paste the bash_prompt function into a shell script file prefixed with git-
, like git-prompt
, placed somewhere in your $PATH
. This allows you to call it as if it were a standard git subcommand as well, like git prompt
.
Note that we invoke/execute the function after defining it.
To test this, simply run:
$ git prompt
It should return the branch name and indicators based on your status, like:
(branch +!$?)
Tmux
Now, we can easily call a git command to show this information, but we also need to pass a -C
flag with a path to the repo in question. Fortunately, tmux gives us the path of the current pane in a special variable called #{pane_current_path}
.
So, our status bar configuration in tmux may look like:
set -g status-right '#(git -C #{pane_current_path} prompt)'
Bonus Tip
Did you know tmux has 2 different "status bars"?
I like to put any global information, or information that does not change between panes, in my status-right
. This includes date, time, cpu, and memory.
Any pane-specific information, I prefer to put it in my pane-border-format
. This includes current working directory and git status information.
Example:
set -g status-right-length 200
# show [prefix] when activated/pressed + mem/cpu load + date/timestamp
set -g status-right "#{?client_prefix,#[reverse][prefix]#[noreverse],} #(tmux-mem-cpu-load --interval 1) [%A %Y-%m-%d %l:%M %p]"
set -g pane-border-status top
set -g pane-border-format ' #{pane_current_path} #(git -C #{pane_current_path} prompt) '
Conclusion
If you are a minimalist like me, I hope this helps you configure and customize your tmux to best suit your needs, workflow, and productivity.
If you were hoping to discover tools or utilities to conveniently configure tmux, then I would like to leave you with some honorable mentions:
-
gitmux
: a binary that you can simply download, configure, and execute in your.tmux.conf
. No runtime dependencies needed. -
powerline
: a fully-featured statusline utility for vim, tmux, and more. Requires python. -
tmux-git
: a tmux plugin.
For more inspiration, feel free to browse my dotfiles.
Thank you for reading.
Happing hacking!
Top comments (0)