The Ultimate Guide To Neovim and Tmux in 2021 for fullstack engineers

Introduction

Getting into Vim can be a pretty daunting task. I know it was for me. I didn't start truly learning how to use it well into the 3rd year of my career as a full-stack engineer. Over the course of the past year I've began the Vim journey and I must say I couldn't be happier. Everything with Vim is faster, more agile, and all around an awesome experience. I'm going to show you how to set up NeoVim to meet all your needs as a modern fullstack developer.

My Initial Setup (Zsh & Tmux)

I code on both a macbook and a Linux desktop. On the linux desktop, I use Terminator as my main terminal, while on Mac I use Iterm2. On both machines I use Zsh with oh-my-zsh. I'm not going to really talk about setting up oh-my-zsh today, but its worth checking out here:

I also use Tmux for swapping between windows on Mac. If you are unfamiliar with Tmux, its an abbreviation for Terminal Multiplexer, & it is a great way to have multiple tabs and panes open and swap
between them.

brew install tmux
tmux -V

Installation

First things first, we have to install neovim. If you're on linux you can use whatever package manager you usually use.

sudo apt-get install neovim

If you're on Mac use Homebrew.

brew install neovim

Next, we need to install vim-plug, which we'll be using to install plugins that we need.

You can find the plugin at [github.com/junegunn/vim-plug(github.com/junegunn/vim-plug)

You can copy this command from here or from their Github repo:

sh -c 'curl -fLo "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/autoload/plug.vim --create-dirs \
       https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'

Neovim Configuration

Our next step is to configure Neovim for our needs. Let's create our config file first.

mkdir ~/.config/nvim
touch ~/.config/nvim/init.vim

Let's open up our init.vim file we just made, and add a section for our plugins.

call plug#begin("~/.vim/plugged")
"Our plugins will go in the middle
call plug#end()

Now that we have that, lets set up the plugins we need to install. This is my current plugin configuration for fullstack web development.

call plug#begin("~/.vim/plugged")
Plug 'junegunn/fzf', {'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
Plug 'pangloss/vim-javascript'
Plug 'peitalin/vim-jsx-typescript'
Plug 'leafgarland/typescript-vim'
Plug 'dracula/vim'
Plug 'scrooloose/nerdtree'
Plug 'ryanoasis/vim-devicons'
Plug 'neoclide/coc.nvim', {'branch':'release'}
let g:coc_global_extensions = ['coc-tsserver',
\'coc-python',
\ 'coc-pydocstring',
\ 'coc-json',
\ 'coc-html-css-support',
\ 'coc-css',
\ 'coc-sql',
\ 'coc-yaml']
" Plug 'sheerun/vim-polyglot',
Plug 'preservim/nerdcommenter'
Plug 'jparise/vim-graphql'
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
" post install (yarn install | npm install) then load plugin only for editing supported files
Plug 'prettier/vim-prettier', {
\ 'do': 'yarn install',
\ 'for': ['javascript', 'typescript', 'css', 'less', 'scss', 'json', 'graphql', 'markdown', 'vue', 'yaml', 'html'] }
call plug#end()

In Neovim all you need to do to install all these plugins is run

:PlugInstall

We're also going to add a few lines to the top of our init.vim.

set scrolloff=8
set number
set relativenumber
set tabstop=4
set shiftwidth=4
set expandtab
set smartindent
set encoding=utf8
let g:airline_powerline_fonts = 1

Theming

Now let's enable our colorscheme. I use Dracula at the moment, but I tend to swap back and forth between Dracula and Gruvbox Dark.

Add these lines below our plugin declarations.

if (has("termguicolors"))
set termguicolors
endif
syntax enable
colorscheme dracula

Keymapping

Next we're going to set up some nice keymappings. I like setting mapleader to space, but I know some people aren't too fond of this. It's all personal preference honestly, if you find you're not using it, don't hesitate to switch to something else.

One mapping that I love to use is jk. I use jk to automatically escape, save, and then return when I'm in insert mode. I've found it to be a very useful little shortcut. The other shortcuts are for searching files and such.

  1. The pv map opens up a new tab to the side.
  2. The pf map opens up a finder that we can use for quickly searching.
  3. The Ctrl-P map is for searching for files within a Git repository. This is useful for finding files inside your software project.
let mapleader = " "
nnoremap <leader>pv :Vex<CR>
nnoremap <leader>pf :Files<CR>
inoremap jk <esc>:w<CR>
nnoremap <C-p> :GFiles<CR>

Nerdtree Configuration

To add IDE-like file navigation to Neovim, I use a plugin called NerdTree. I've mapped the toggle for Nerdtree to Ctrl-A, which I've found works pretty well for me.

let g:NERDTreeShowHidden = 1
let g:NERDTreeMinimalUI = 0
let g:NERDTreeIgnore = ['node_modules']
let NERDTreeStatusLine='NERDTree'
" Automaticaly close nvim if NERDTree is only thing left open
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
" Toggle
nnoremap <silent> <C-a> :NERDTreeToggle<CR>

Final Configurations

I have a couple more small configurations at the end of my init.vim.

  1. Opening an inline terminal with Ctrl-n
  2. Setting prettier to auto format and to prefer to use the prettier config file in the project, instead of the default
  3. A setting to open new panes to the right and below
" open new split panes to right and below
set splitright
set splitbelow
" turn terminal to normal mode with escape
tnoremap <Esc> <C-\><C-n>
" start terminal in insert mode
au BufEnter * if &buftype == 'terminal' | :startinsert | endif
" open terminal on ctrl+n
function! OpenTerminal()
split term://zsh
resize 10
endfunction
nnoremap <c-n> :call OpenTerminal()<CR>
let g:prettier#autoformat_config_present = 1
let g:prettier#config#config_precedence = 'prefer-file'

Conclusion

I hope you find this guide useful! This is my current Neovim setup and I've been very happy with the result. If you're not interested in following along. I'm including the full init.vim file below.

Don't forget to follow me on Twitter: @codespectremike

Init.Vim

set scrolloff=8
set number
set relativenumber
set tabstop=4
set shiftwidth=4
set expandtab
set smartindent
set encoding=utf8
let g:airline_powerline_fonts = 1

call plug#begin("~/.vim/plugged")
Plug 'junegunn/fzf', {'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
Plug 'pangloss/vim-javascript'
Plug 'peitalin/vim-jsx-typescript'
Plug 'leafgarland/typescript-vim'
Plug 'dracula/vim'
Plug 'scrooloose/nerdtree'
Plug 'ryanoasis/vim-devicons'
Plug 'neoclide/coc.nvim', {'branch':'release'}
let g:coc_global_extensions = ['coc-tsserver',
\'coc-python',
\ 'coc-pydocstring',
\ 'coc-json',
\ 'coc-html-css-support',
\ 'coc-css',
\ 'coc-sql',
\ 'coc-yaml']
" Plug 'sheerun/vim-polyglot',
Plug 'preservim/nerdcommenter'
Plug 'jparise/vim-graphql'
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
" post install (yarn install | npm install) then load plugin only for editing supported files
Plug 'prettier/vim-prettier', {
\ 'do': 'yarn install',
\ 'for': ['javascript', 'typescript', 'css', 'less', 'scss', 'json', 'graphql', 'markdown', 'vue', 'yaml', 'html'] }
call plug#end()

if (has("termguicolors"))
set termguicolors
endif
syntax enable
colorscheme dracula

let mapleader = " "
nnoremap <leader>pv :Vex<CR>
nnoremap <leader>pf :Files<CR>
inoremap jk <esc>:w<CR>
nnoremap <C-p> :GFiles<CR>

let g:NERDTreeShowHidden = 1
let g:NERDTreeMinimalUI = 0
let g:NERDTreeIgnore = ['node_modules']
let NERDTreeStatusLine='NERDTree'
" Automaticaly close nvim if NERDTree is only thing left open
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
" Toggle
nnoremap <silent> <C-a> :NERDTreeToggle<CR>

" open new split panes to right and below
set splitright
set splitbelow
" turn terminal to normal mode with escape
tnoremap <Esc> <C-\><C-n>
" start terminal in insert mode
au BufEnter * if &buftype == 'terminal' | :startinsert | endif
" open terminal on ctrl+n
function! OpenTerminal()
split term://zsh
resize 10
endfunction
nnoremap <c-n> :call OpenTerminal()<CR>
let g:prettier#autoformat_config_present = 1
let g:prettier#config#config_precedence = 'prefer-file'

28