My Neovim Setup

Dids Irwyn T. Reyes
8 min readMar 12, 2023

--

neovim

I’m writing this blog for me 😄 and for those who wants to try Neovim, i always forget my Nvim setup when changing to different Operating System and Linux Distribution.

This configuration works well in web development Elixir and Phoenix Framework, Typescript, Javascript, ReactJS.

Automated Testing: Playwright Framework

This is for current Linux Distro: Mint, Flavor: Cinnamon

Tested with Linux Distro: Ubuntu 22.04.2 LTS
Tested with macOS: Ventura 13.4, Catalina 10.15, Sierra 10.12

Header is available here: https://github.com/nvimdev/dashboard-nvim/wiki/Header-Preview

First step is to open terminal Ctrl + Alt + T on linux

Current linux distro does not have Git pre-installed

Run command first

sudo apt update
sudo apt install git

Enter command:

sudo add-apt-repository ppa:neovim-ppa/stable
sudo apt-get update
sudo apt-get install neovim

This gets the latest version of nvim. running sudo apt install neovim will do it but other plugins wont work because the version that will be installed is lower than 0.7.0

After installing neovim

Create a directory


mkdir ~/.config/nvim/init.vim

Copy and Paste

call plug#begin('~/.local/share/nvim/site/plugged')

Plug 'neoclide/coc.nvim', {'branch': 'release'}
let g:coc_global_extensions = [
\ 'coc-tsserver'
\ ]

Plug 'scrooloose/nerdtree'
Plug 'mhinz/vim-startify'

let g:ascii = [
\'',
\' ⣴⣶⣤⡤⠦⣤⣀⣤⠆ ⣈⣭⣭⣿⣶⣿⣦⣼⣆ ',
\' ⠉⠻⢿⣿⠿⣿⣿⣶⣦⠤⠄⡠⢾⣿⣿⡿⠋⠉⠉⠻⣿⣿⡛⣦ ',
\' ⠈⢿⣿⣟⠦ ⣾⣿⣿⣷⠄⠄⠄⠄⠻⠿⢿⣿⣧⣄ ',
\' ⣸⣿⣿⢧ ⢻⠻⣿⣿⣷⣄⣀⠄⠢⣀⡀⠈⠙⠿⠄ ',
\' ⢠⣿⣿⣿⠈ ⠡⠌⣻⣿⣿⣿⣿⣿⣿⣿⣛⣳⣤⣀⣀ ',
\' ⢠⣧⣶⣥⡤⢄ ⣸⣿⣿⠘⠄ ⢀⣴⣿⣿⡿⠛⣿⣿⣧⠈⢿⠿⠟⠛⠻⠿⠄ ',
\' ⣰⣿⣿⠛⠻⣿⣿⡦⢹⣿⣷ ⢊⣿⣿⡏ ⢸⣿⣿⡇ ⢀⣠⣄⣾⠄ ',
\' ⣠⣿⠿⠛⠄⢀⣿⣿⣷⠘⢿⣿⣦⡀ ⢸⢿⣿⣿⣄ ⣸⣿⣿⡇⣪⣿⡿⠿⣿⣷⡄ ',
\' ⠙⠃ ⣼⣿⡟ ⠈⠻⣿⣿⣦⣌⡇⠻⣿⣿⣷⣿⣿⣿ ⣿⣿⡇⠄⠛⠻⢷⣄ ',
\' ⢻⣿⣿⣄ ⠈⠻⣿⣿⣿⣷⣿⣿⣿⣿⣿⡟ ⠫⢿⣿⡆ ',
\' ⠻⣿⣿⣿⣿⣶⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⡟⢀⣀⣤⣾⡿⠃ ',
\' ⢰⣶ ⣶ ⢶⣆⢀⣶⠂⣶⡶⠶⣦⡄⢰⣶⠶⢶⣦ ⣴⣶ ',
\' ⢸⣿⠶⠶⣿ ⠈⢻⣿⠁ ⣿⡇ ⢸⣿⢸⣿⢶⣾⠏ ⣸⣟⣹⣧ ',
\' ⠸⠿ ⠿ ⠸⠿ ⠿⠷⠶⠿⠃⠸⠿⠄⠙⠷⠤⠿⠉⠉⠿⠆ ',
\'',
\]

let g:startify_custom_header = 'startify#pad(startify#fortune#boxed() + g:ascii)'

" let g:ascii = [
" \'',
" \' ⢰⣧⣼⣯⠄⣸⣠⣶⣶⣦⣾⠄⠄⠄⠄⡀⠄⢀⣿⣿⠄⠄⠄⢸⡇⠄⠄ ',
" \' ⣾⣿⠿⠿⠶⠿⢿⣿⣿⣿⣿⣦⣤⣄⢀⡅⢠⣾⣛⡉⠄⠄⠄⠸⢀⣿⠄ ',
" \' ⢀⡋⣡⣴⣶⣶⡀⠄⠄⠙⢿⣿⣿⣿⣿⣿⣴⣿⣿⣿⢃⣤⣄⣀⣥⣿⣿⠄ ',
" \' ⢸⣇⠻⣿⣿⣿⣧⣀⢀⣠⡌⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠿⣿⣿⣿⠄ ',
" \' ⢀⢸⣿⣷⣤⣤⣤⣬⣙⣛⢿⣿⣿⣿⣿⣿⣿⡿⣿⣿⡍⠄⠄⢀⣤⣄⠉⠋⣰ ',
" \' ⣼⣖⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⣿⣿⣿⣿⣿⢇⣿⣿⡷⠶⠶⢿⣿⣿⠇⢀⣤ ',
" \' ⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣽⣿⣿⣿⡇⣿⣿⣿⣿⣿⣿⣷⣶⣥⣴⣿⡗ ',
" \' ⢀⠈⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟ ',
" \' ⢸⣿⣦⣌⣛⣻⣿⣿⣧⠙⠛⠛⡭⠅⠒⠦⠭⣭⡻⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃ ',
" \' ⠘⣿⣿⣿⣿⣿⣿⣿⣿⡆⠄⠄⠄⠄⠄⠄⠄⠄⠹⠈⢋⣽⣿⣿⣿⣿⣵⣾⠃ ',
" \' ⠘⣿⣿⣿⣿⣿⣿⣿⣿⠄⣴⣿⣶⣄⠄⣴⣶⠄⢀⣾⣿⣿⣿⣿⣿⣿⠃ ',
" \' ⠈⠻⣿⣿⣿⣿⣿⣿⡄⢻⣿⣿⣿⠄⣿⣿⡀⣾⣿⣿⣿⣿⣛⠛⠁ ',
" \' ⠈⠛⢿⣿⣿⣿⠁⠞⢿⣿⣿⡄⢿⣿⡇⣸⣿⣿⠿⠛⠁ ',
" \' ⠉⠻⣿⣿⣾⣦⡙⠻⣷⣾⣿⠃⠿⠋⠁ ⢀⣠⣴ ',
" \' ⣿⣿⣿⣶⣶⣮⣥⣒⠲⢮⣝⡿⣿⣿⡆⣿⡿⠃⠄⠄⠄⠄⠄⠄⠄⣠⣴⣿⣿⣿ ',
" \'',
" \]

Plug 'vwxyutarooo/nerdtree-devicons-syntax'
Plug 'ryanoasis/vim-devicons'

Plug 'elixir-editors/vim-elixir'
Plug 'tpope/vim-commentary'
Plug 'janko-m/vim-test'
Plug 'mhinz/vim-mix-format'

" Use for git commands. Ex: Git blame
Plug 'tpope/vim-fugitive'
" Surrond tags
Plug 'tpope/vim-surround'

" Tailwind
Plug 'yaegassy/coc-tailwindcss3', {'do': 'yarn install --frozen-lockfile'}

Plug 'nvim-lua/plenary.nvim'
Plug 'nvim-telescope/telescope.nvim', { 'tag': '0.1.0' }
Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'}


Plug 'Yggdroot/indentLine'

" Formatting
Plug 'prettier/vim-prettier', {
\ 'do': 'yarn install --frozen-lockfile --production',
\ 'branch': 'release/0.x'
\ }
Plug 'Townk/vim-autoclose'

Plug 'sbdchd/neoformat' " formatter
Plug 'dyng/ctrlsf.vim' " ctrlsf plugin to search for code matches

Plug 'sonph/onehalf', { 'rtp': 'vim' }

let g:ctrlp_user_command = ['.git', 'cd %s && git ls-files -co --exclude-standard'] "Hide files in .gitignore
let g:ctrlp_show_hidden = 1 "Show dotfiles
nmap <C-F>f <Plug>CtrlSFPrompt
nmap <C-F>n <Plug>CtrlSFCwordPath
nmap <C-F>p <Plug>CtrlSFPwordPath

"molokai theme plugin
Plug 'tomasr/molokai'
let g:molokai_original = 1
let g:rehash256 = 1

let g:NERDTreeMinimalMenu=1

let g:NERDTreeDisableFileExtensionHighlight = 1
let g:NERDTreeDisableExactMatchHighlight = 1
let g:NERDTreeDisablePatternMatchHighlight = 1

let g:NERDTreeFileExtensionHighlightFullName = 1
let g:NERDTreeExactMatchHighlightFullName = 1
let g:NERDTreePatternMatchHighlightFullName = 1

let g:NERDTreeHighlightFolders = 1 " enables folder icon highlighting using exact match
let g:NERDTreeHighlightFoldersFullName = 1 " highlights the folder name

let s:colors = {
\ 'brown' : "905532",
\ 'aqua' : "3AFFDB",
\ 'blue' : "689FB6",
\ 'darkBlue' : "44788E",
\ 'purple' : "834F79",
\ 'lightPurple' : "834F79",
\ 'red' : "AE403F",
\ 'beige' : "F5C06F",
\ 'yellow' : "F09F17",
\ 'orange' : "D4843E",
\ 'darkOrange' : "F16529",
\ 'pink' : "CB6F6F",
\ 'salmon' : "EE6E73",
\ 'green' : "8FAA54",
\ 'lightGreen' : "31B53E",
\ 'white' : "FFFFFF"
\ }


Plug 'tpope/vim-markdown'
Plug 'vim-scripts/closetag.vim'
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
Plug 'c-brenn/phoenix.vim'
Plug 'slashmili/alchemist.vim'
Plug 'cakebaker/scss-syntax.vim'
Plug 'hail2u/vim-css3-syntax'

" Use release branch (recommend)
Plug 'mechatroner/rainbow_csv'
if has('nvim')
Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }
else
Plug 'Shougo/deoplete.nvim'
Plug 'roxma/nvim-yarp'
Plug 'roxma/vim-hug-neovim-rpc'
endif
let g:deoplete#enable_at_startup = 1

" For Typescript
Plug 'pangloss/vim-javascript'
Plug 'leafgarland/typescript-vim'
Plug 'peitalin/vim-jsx-typescript'
Plug 'styled-components/vim-styled-components', { 'branch': 'main' }
Plug 'jparise/vim-graphql'

call plug#end()

syntax on
filetype plugin indent on

"Load files in elixir
au BufRead,BufNewFile *.ex,*.exs set filetype=elixir
au BufRead,BufNewFile *.eex,*.heex,*.leex,*.sface,*.lexs set filetype=eelixir
au BufRead,BufNewFile mix.lock set filetype=elixir

" Color
colorscheme onehalfdark

" Code Completion
inoremap <silent><expr><tab> pumvisible() ? "\<c-n>" : "\<tab>"
inoremap <silent><expr><s-tab> pumvisible() ? "\<c-p>" : "\<s-tab>"
" Dashboard

autocmd FileType dashboard set showtabline=0 | autocmd WinLeave <buffer> set showtabline=2

" For 'Yggdroot/indentLine' and 'lukas-reineke/indent-blankline.nvim' "
let g:indentLine_fileTypeExclude = ['dashboard', 'startify', 'nerdtree']
" For 'ntpeters/vim-better-whitespace' "
let g:better_whitespace_filetypes_blacklist = ['dashboard', 'startify', 'nerdtree']


" Telescope
" Find files using Telescope command-line sugar.
nnoremap <leader>ff <cmd>Telescope find_files<cr>
nnoremap <leader>fg <cmd>Telescope live_grep<cr>
nnoremap <leader>fb <cmd>Telescope buffers<cr>
nnoremap <leader>fh <cmd>Telescope help_tags<cr>

" Using Lua functions
nnoremap <leader>ff <cmd>lua require('telescope.builtin').find_files()<cr>
nnoremap <leader>fg <cmd>lua require('telescope.builtin').live_grep()<cr>
nnoremap <leader>fb <cmd>lua require('telescope.builtin').buffers()<cr>
nnoremap <leader>fh <cmd>lua require('telescope.builtin').help_tags()<cr>

" Airline
let g:airline_powerline_fonts = 1

if exists('+termguicolors')
let &t_8f = "\<Esc>[38;2;%lu;%lu;%lum"
let &t_8b = "\<Esc>[48;2;%lu;%lu;%lum"
set termguicolors
endif
" General
set clipboard=unnamedplus
set nopaste
set tabstop=2
set ts=2
set shiftwidth=2
set expandtab
set number " Display the line numbers
set showcmd
set showmode
set backspace=indent,eol,start
set mouse=ia " Enable your track pad interaction
set incsearch " Highlight matches as you type
set hlsearch " Highlight matches

" for TS
" autocmd BufEnter *.{js,jsx,ts,tsx} :syntax sync fromstart
" autocmd BufLeave *.{js,jsx,ts,tsx} :syntax sync clear

"for icons
set encoding=UTF-8
" let g:molokai_original = 1 " Modified Color Scheme - Using Molokai
xnoremap p pgvy " Paste multiple times

" Clear cache
:nnoremap <CR> :nohlsearch<cr>

" Make it easy to navigate on insert mode
imap <C-k> <Up>
imap <C-j> <Down>
imap <C-h> <Left>
imap <C-l> <Right>

" Folding
set foldmethod=indent
set foldnestmax=10
set nofoldenable
set foldlevel=0

" Undo files
set undofile
if !has('nvim')
set undodir=~/.vim/undo
endif

augroup vimrc
autocmd!
autocmd BufWritePre /tmp/* setlocal noundofile
augroup END

"Mix Formatter
let g:mix_format_on_save = 1

" Leader commands
let mapleader=" "

nnoremap <leader>f :<C-u>FZF<CR>
nnoremap <leader>n :NERDTreeToggle<cr>
nnoremap <leader>mv :vsplit <cr>
nnoremap <leader>ms :split <cr>
nnoremap <leader>z <C-Z>
" nnoremap <leader>g <C-O>

" Grepper
let g:grepper = {}
let g:grepper.tools = ['grep', 'git', 'rg']

" Search for the current word
nnoremap <Leader>* :Grepper -cword -noprompt<CR>

" Search for the current selection
nmap gs <plug>(GrepperOperator)
xmap gs <plug>(GrepperOperator)

" Neovim Terminal
if has('nvim')
tnoremap <Esc> <C-\><C-n>
tnoremap <C-v><Esc> <Esc>
endif

if has('nvim') && executable('nvr')
let $VISUAL="nvr -cc split --remote-wait +'set bufhidden=wipe'"
endif

" Key commands
imap jj <Esc>
map ss :w<cr>
map qq :q <cr>
nmap <tab> <c-w>w

" Linting
let g:ale_linters = {
\ 'javascript': ['eslint']
\}

" Mappings in the style of unimpaired-next
nmap <silent> [W <Plug>(ale_first)
nmap <silent> [w <Plug>(ale_previous)
nmap <silent> ]w <Plug>(ale_next)
nmap <silent> ]W <Plug>(ale_last)
nnoremap <Leader>l :ALELint<CR>

let g:ale_sign_error = '>>'
let g:ale_sign_warning = '.'
let g:ale_lint_on_enter = 0 " Less distracting when opening a new file
let g:ale_completion_enabled = 1
let g:ale_sign_column_always = 0

let g:ale_lint_on_text_changed = 'always' " default
let g:ale_lint_on_save = 1
let g:ale_lint_on_filetype_changed = 1

let g:airline#extensions#ale#enabled = 1
let g:airline#extensions#branch#displayed_head_limit = 7
let g:airline#extensions#branch#format = 2

" Prettier Config
let g:prettier#autoformat = 1
let g:prettier#autoformat_require_pragma = 0

" New tests from vim-test
" Run only the example under the cursor
nmap <silent> <leader>tn :TestNearest<cr>
" Run last visit
nmap <silent> <leader>tl :TestLast<cr>
" Run visit
nmap <silent> <leader>tg :TestVisit<cr>
" Run this file
nmap <silent> <leader>tt :TestFile<cr>
" Run all test files
nmap <silent> <leader>ta :TestSuite<cr>

"""""""""""""""""""""
" vim-test extensions
"""""""""""""""""""""
function! ElixirUmbrellaTransform(cmd) abort
if match(a:cmd, 'apps/') != -1
return substitute(a:cmd, 'mix test apps/\([^/]*/\)', 'cd apps/\1 \&\& mix test ', '')
else
return a:cmd
end
endfunction

let g:test#preserve_screen = 0
let g:test#custom_transformations = {'elixir_umbrella': function('ElixirUmbrellaTransform')}
let g:test#transformation = 'elixir_umbrella'

" Run Dialyzer in Project
function! RunPhoenixDialyxir()
:w
:silent !echo;echo;echo;echo;echo
exec ":!time mix dialyzer"
endfunction

" Run Coverall in Project
function! RunPhoenixCoverall()
:w
:silent !echo;echo;echo;echo;echo
exec ":!time mix coveralls"
endfunction

" Run Credo in Project
function! RunPhoenixCredo(filename)
" Write the file and run tests for the given filename
:w
:silent !echo;echo;echo;echo;echo
exec ":!time mix credo --strict " . a:filename
endfunction

" Run Credo in File
function! RunPhoenixCredoFile(...)
if a:0
let command_suffix = a:1
else
let command_suffix = ""
endif

call RunPhoenixCredo(@% . command_suffix)
endfunction

" Run Credo in Line
function! RunNearestCredoLine()
let spec_line_number = line('.')
call RunPhoenixCredoFile(":" . spec_line_number)
endfunction

" Run only the example under the cursor
map <leader>yl :call RunNearestCredoLine()<cr>
" Run this file
map <leader>yy :call RunPhoenixCredoFile()<cr>
" Run all test files
map <leader>ya :call RunPhoenixCredo('')<cr>
" Run dialyxir
map <leader>yd :call RunPhoenixDialyxir()<cr>
" Run coveralls
map <leader>yc :call RunPhoenixCoverall()<cr>

function! SetTestFile()
" Set the spec file that tests will be run for.
let t:grb_test_file=@%
endfunction

" Destroy all Softwares
augroup vimrcEX
autocmd!
autocmd FileType text setlocal textwidth=78
"Jump to last cursor position
autocmd BufReadPost *
\ if line("'\"") > 0 && line("'\"") <= line ("$") |
\ exe "normal g'\"" |
\ endif
augroup END

"Indent at begining of line, else do completion
function! InsertTabWrapper()
let col = col('.') - 1
if !col || getline('.')[col - 1] !~ '\k'
return "\<tab>"
else
return "\<c-p>"
endif
endfunction
" inoremap <tab> <c-r>=InsertTabWrapper()<cr>
" inoremap <s-tab> <c-n>

"Rename file
function! RenameFile()
let old_name = expand('%')
let new_name = input('New file name: ', expand('%'))
if new_name != '' && new_name != old_name
exec ':saveas ' . new_name
exec ':silent !rm ' . old_name
redraw!
endif
endfunction
map <leader>j :call RenameFile()<cr>

" Record Sesjion
map <leader>r :Obsession<cr>
map <leader>rt :Obsession!<cr>

" Source vimrc
map <leader>so :so ~/.vimrc<cr>

"Easy navigate vim panes
nnoremap <C-J> <C-W><C-J>
nnoremap <C-K> <C-W><C-K>
nnoremap <C-L> <C-W><C-L>
nnoremap <C-H> <C-W><C-H>

" Terminal
map <leader>ts :split \| terminal <cr>
map <leader>tv :vsplit \| terminal <cr>
map <leader>tp :split \| terminal mix phx.server <cr>
map <leader>tg :split \| terminal mix deps.get <cr>
map <leader>tm :split \| terminal mix ecto.migrate <cr>

" Navigate tabs
map <leader>gn :tabnext<cr>
map <leader>gp :tabprevious<cr>

" For Typescript Configuration
autocmd BufEnter *.{js,jsx,ts,tsx} :syntax sync fromstart
autocmd BufLeave *.{js,jsx,ts,tsx} :syntax sync clear
nnoremap <silent> K :call CocAction('doHover')<CR>

The Plug won’t run without vim-plug

Run command
curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

This will install vim-plug Manager

Reference: https://fanwangecon.github.io/Tex4Econ/nontex/install/linux/fn_vim.html 1.2 Install Vim-Plug Plug-ins manager for Neovim

After curl finishes the download, go inside init.vim

First update source:

source ~/.config/nvim/init.vim

Then run


nvim ~/.config/nvim/init.vim

This will open nvim and show the code pasted earlier.

Inside nvim type :Plug and press tab key, this will display all available commands in vim-plug, if it didn’t work it means there’s something wrong with installation.

Now tab all the way to :PlugInstall or just type directly :PlugInstall then hit enter.

After installation if you toggle nerd tree icons are not showing correctly, it needs to install a Nerd Font


mkdir -p ~/.local/share/fonts
cd ~/.local/share/fonts && curl -fLo “Droid Sans Mono for Powerline Nerd Font Complete.otf” https://github.com/ryanoasis/nerd-fonts/raw/HEAD/patched-fonts/DroidSansMono/complete/Droid%20Sans%20Mono%20Nerd%20Font%20Complete.otf

Or download Hack Nerd Font here https://github.com/ryanoasis/nerd-fonts#option-1-download-and-install-manually

After downloading extract the zip file and copy its contents

Create a directory first for the fonts

mkdir -p ~/.local/share/fonts
cp -a ttf ~/.local/share/fonts

Go to your terminal preferences and change the Terminal Font to (downloaded font) e.g., Nerd Font

After installation try running :UpdateRemotePlugins for deoplete

Telescope will work in Finding files, but the Livegrep won’t so ripgrep binary should be installed https://github.com/BurntSushi/ripgrep

sudo apt-get install ripgrep

Keyboard Shortcuts:

Nerd Tree: space n

Telescope — Find Files: \ ff

Telescope — Live Grep: \ fg

Minimize/Hide Nvim: space z

Maximize/Show Nvim: fg

Save: ss

Quit: qq

Test Nearest: space tn

Test All: space ta

Test File: space tt

--

--