The Ultimate Guide To Neovim and Tmux in 2021 for fullstack engineers
Tags: vim, bash, beginners
Published: 2021-07-26 14:38:54

## 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: 

[https://ohmyz.sh/](https://ohmyz.sh/)

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.

```jsx
sudo apt-get install neovim  
```

If you're on Mac use Homebrew.

```jsx
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:

```jsx
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.

```jsx
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.

 ```bash
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.

```bash
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.

```bash
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.

```bash
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.

```bash
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.

```jsx
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

```jsx
" 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
```bash
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'
```