In my first job we used Emacs as our main text editor. However, I have no idea how to use it properly so I just used it more like Notepad++ than Emacs. In our team there is one person who refused to use Emacs, instead he was using vi (without the m!). To be honest, it looked painful watching him edit code with no syntax highlighting, no line numbers, and no plugins whatsoever. We tried constantly to convince him to use Emacs but he always refused and stuck to using vi. I thought the guy was crazy.
Fast forward 12 years in my career. I was attending a Ruby conference with my peers and one of the speakers (Brad Urani) demonstrated zshell, vim, and tmux and how he does development in his machine. It looked cool! Some of my peers also uses vim and tmux so its not a new concept to me, however I always decided to use gedit all these years. This time, they probably thought I was crazy.
After the conference I finally decided to jump to the other side. I will no longer use any text editor or IDE for programming and will force myself to use vim exclusively. I also decided to use tmux instead of relying on the guake terminal for more awesomeness.
After two months, am I very pleased with the results: I now have my development environment set up using zshell, vim, and tmux and all the tools that I used to have before have been configured to work on vim. As I feel like I am years (maybe decades) late to the party, here is a simple guide I wrote to help people like me who want to dive head-first into vim and tmux.
ZShell
This step is not really required to use Vim and Tmux, but it is recommended due to several improvements and plugins that you can use to improve your development environment.
In this guide, I will be using Ubuntu (or other Debian based systems) so I can be lazy and just install it using the package manager:
sudo apt-get install zsh
You can also check the version of the zshell installed to make sure its compatible with the plugins you want to use later on:
zsh --version
Once zshell has been installed, we will want to make it our default shell (instead of let’s say bash). This will make your system use zshell when you invoke the terminal or the command line.
chsh -s $(which zsh)
When you load zshell for the first time, it needs to be configured first and it will prompt you on how to do the initial configuration:
This is the Z Shell configuration function for new users,
zsh-newuser-install.
You are seeing this message because you have no zsh startup files
(the files .zshenv, .zprofile, .zshrc, .zlogin in the directory
~). This function can help you with a few settings that should
make your use of the shell easier.
You can:
(q) Quit and do nothing. The function will be run again next time.
(0) Exit, creating the file ~/.zshrc containing just a comment.
That will prevent this function being run again.
(1) Continue to the main menu.
(2) Populate your ~/.zshrc with the configuration recommended
by the system administrator and exit (you will need to edit
the file by hand, if so desired).
--- Type one of the keys in parentheses --- 2
To make things simpler, we can use option (2) to auto-generate the zshell configuration file .zshrc. You can edit it later if needed.
Aliases
Aliases are command shortcuts that you can use to speed up your work by allowing you to type less characters to perform common tasks. An example of an alias is this:
alias work="cd ~/Desktop/WORK"
When this alias is loaded, whenever you type work in your terminal, it will automatically go to your work folder instead of manually typing the entire command. This particular example is very simplistic, but you can create more complex aliases to suit your workflow.
In order to create aliases, we can use a common file like .aliases to store all of our aliases. This is useful so we can just load this file into a shell’s configuration file, meaning we can have the same aliases set up whenever we use bash or zshell or any other shell.
First, create a hidden file called .aliases in your home folder:
touch ~/.aliases
Edit this file as needed, adding an alias line for every alias we want to set up. Next we will load this into zshell by editing the .zshrc file that was generated in the previous step and adding this line:
source $HOME/.aliases
This will then instruct zshell to load your aliases file whenever your shell starts.
Tmux
Tmux is a terminal multiplexer, which is a tool used for managing multiple separate terminal sessions inside a single session. Tmux provides an elegant way of managing multiple terminals such has text editing, SSH sessions, starting local servers, etc. Personally I find it very useful as I can switch context inside terminals very quickly using keyboard shortcuts, but it is much more powerful than that.
Before we can install tmux from source, we need to install the following dependencies:
sudo apt-get install libevent-dev
sudo apt-get install libncurses5-dev libncursesw5-dev
Then we download the tmux source code:
wget https://github.com/tmux/tmux/releases/download/2.6/tmux-2.6.tar.gz
We unpack the compressed file and go to the decompressed folder:
tar xvzf tmux-2.6.tar.gz
cd tmux-2.6
Then we build the installation and install it in our system:
./configure && make
sudo make install
We then invoke tmux using the following command:
tmux
Tmux Configuration
Just like in zshell, we can customize how tmux behaves using a file in our home directory called .tmux.conf. Here I will show you some common useful configuration to get you started quickly. These can be found in my own tmux configuration here https://github.com/marvs/dotfiles/blob/master/.tmux.conf.
The default command prefix is Ctrl+b. Now if you try it in your keyboard, its quite hard to do as you may need to use two hands to do this. This is a problem since this command is going to be used as a starting sequence for several other commands. It is therefore useful to bind this into an easier sequence (which can be done in a single hand), such as Ctrl+a.
# sets prefix to Ctrl-a
set -g prefix C-a
unbind C-b
We also need to instruct tmux to load our favorite shell instead of the default system shell. In this case we will set it to zshell.
# sets shell do the default user shell
set -g default-shell /bin/zsh
Tmux can have issues displaying colors in the terminal, so we instruct it to use 256 colors. This is essential for syntax highlighting such as when using vim.
# 256 colors
set -g default-terminal "screen-256color"
If you are using tmux for the first time, you will notice that you can no longer use the mouse to interact with the terminal. This may be useful as it forces you to rely on keyboard shortcuts and commands to do the things that you want. In the hands of an expert, this results in lightning-fast terminal interactions as compared to using the mouse.
However, as I am lazy I prefer to have a mouse fallback in case I get stuck in what to do next in my terminal. To do this, we can enable mouse integration (and scrolling) in tmux.
# Enable mouse integration
set -g mouse on
# Sane scrolling- I don't know how this works
set -g terminal-overrides 'xterm*:smcup@:rmcup@'
One thing I immediately noticed is I can no longer copy and paste using the clipboard when the terminal is inside tmux. The solution for this is to hold the SHIFT key before selecting the text you want to copy. Then you will have your copy/paste mechanism working as it was when you are not using tmux.
Tmux scripts
One feature of tmux that I appreciated is that you can now create your tmux sessions and windows/panels programmatically using a shell script. An example of this script (that I personally use) can be found here:
https://github.com/marvs/dotfiles/blob/master/dev-tmux
Basically, what this script does is it will create 2 windows, one called CODING and one called SSH. The CODING window has only one pane as it will be mainly used for text editing. The SSH window is divided into three panes, where you can run your local servers or access remote servers.
Once tmux is set up, invoking your custom development terminal session becomes as simple as running the script:
./dev-tmux
Useful Commands
Here are some of the tmux commands/keybinds that I commonly use in my work:
- Ctrl+a n – move to the next window (e.g from CODING to SSH)
- Ctrl+a p – move to the previous window (e.g. from SSH to CODING)
- Ctrl+a arrow keys – move to the top, bottom, left, or right panes
- Ctrl+a (hold) arrow keys – resize the pane in a particular direction
Vim
Vim stands for Vi IMproved. As the name implies, vim is an improved version of the basic vi editor, enabling new ways to interact with the text, advanced plugin support, and more.
To install vim, we can use again our favorite package manager:
sudo apt-get install vim
Configuration
As you may have guessed by now, vim is configured using a file called .vimrc, which also resides in your home folder. Here are some examples of useful configuration you can use:
To enable syntax highlighting:
syntax on
filetype plugin indent on
To make backspaces, tabs, and indents work like your favorite IDE:
set backspace=indent,eol,start " more powerful backspacing
set tabstop=2 " Set the default tabstop
set softtabstop=2
set shiftwidth=2 " Set the default shift width for indents
set expandtab " Make tabs into spaces (set by tabstop)
set smarttab " Smarter tab levels
Make the vim tab name the current filename (useful to get context when you have multiple tabs open):
let &titlestring = @%
set title
As a safety mechanism, vim creates swapfiles (temporary hidden files) when you edit a file. However, this can be problematic if you are using a version control system such as git as these files will be shown as newly added files. For this, you can move the swapfiles generated by vim into a directory outside your working directory:
set swapfile
set dir=~/tmp
To highlight the selections in your view when you search for it:
set hlsearch
To show line numbers:
set number
Plugins
One of the best features of vim is its extensibility and customization using plugins. There are several plugin managers out there that can handle installing and configuring plugins within vim, but in this article we will use vim-plug.
https://github.com/junegunn/vim-plug
To install vim-plug, just download the plug.vim file into your vim installation:
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
You can now specify the plugins in your .vimrc file, like the following:
call plug#begin('~/.vim/plugged')
Plug 'scrooloose/nerdtree'
Plug 'scrooloose/nerdcommenter'
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
Plug 'junegunn/fzf.vim'
Plug 'tpope/vim-endwise'
call plug#end()
And then when you invoke vim, install the plugins you specified in your .vimrc file
:PlugInstall
Once you have the plugins installed, you can also configure the keyboard shortcuts to use those plugins. As an example, you can put these additional configuration in your .vimrc file:
map <C-n> :NERDTreeToggle<CR>
nnoremap <C-f> :FZF<cr>
nnoremap <C-t> :tabe<cr>
With this configuration, I can open a file tree view using CTRL+n, do a fuzzy search using CTRL+f, and open a new tab using CRTL+t.
Make sure you only add configuration that makes sense to you! Copying other people’s configuration may or may not be helpful depending on how you want to use vim.
Final Thoughts
I have been using this setup for months now, using vim as my main editor when working with code (instead of gedit). The first week(s) are difficult as this is the time that my hands are still getting used to the keyboard shortcuts used by tmux and vim. However, once you get the hang of it, I find them enjoyable to use.
One advantage that I gained is that I no longer use my mouse or my trackpad when coding, meaning my hands no longer need to travel away from the keyboard when working.
Another advantage of this setup is that it has a tiny resource footprint compared to more popular IDEs like Atom, Sublime, or VSCode. This advantage was highlighted when I tried to use one of my netbooks to do some light coding. This netbook has limited CPU and memory, and loading an editor or an IDE in this machine results in poor performance. Setting up tmux+vim in this machine breathed new life to the machine, as everything is just running inside a terminal!
I recommend that you give this setup a try as well and see if it makes sense in your workflow. As with most things, do them not because they are popular or “cool”, but because it makes sense in your work.