loading...
Cover image for Ditch VSCode for neovim

Ditch VSCode for neovim

casonadams profile image Cason Adams Updated on ・7 min read

I found myself in the past always reaching for VSCode when I start working on a new project, or a code base I am not really familiar with. Simply because of the intellisense that is built into it! I am always frustrated with how slow it is, and how inflexible the terminal is with my work flow. So here is what I have done to ditch VSCode completely.

Image

Setup neovim

First lets setup neovim to use a very similar LSP engine. In this post we are going to use coc

Requirements

All of these should be installed with your OS package manager

  1. neovim
  2. git
  3. tmux
  4. alacritty

Tools

  1. vim-plug
  2. gitmux (save to PATH /usr/local/bin)

Font

  1. JetBrains Mono

init.vim

Lets create an init.vim file. For linux and OSX this file is should be saved here ~/.config/nvim/init.vim

Add this snippet to init.vim

"------------------------------------------------
" Plugins START
call plug#begin()
  Plug 'airblade/vim-gitgutter'
  Plug 'cespare/vim-toml'
  Plug 'editorconfig/editorconfig-vim'
  Plug 'itchyny/lightline.vim'
  Plug 'junegunn/vim-easy-align'
  Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
  Plug 'junegunn/fzf.vim'
  Plug 'mengelbrecht/lightline-bufferline'
  Plug 'lifepillar/vim-gruvbox8'
  Plug 'neoclide/coc.nvim', {'branch': 'release'}
  Plug 'tpope/vim-commentary'
call plug#end()
" Plugins END
"------------------------------------------------

"------------------------------------------------
" Settings START
let mapleader = "\<Space>"
filetype plugin on
set completeopt=menuone
set mouse=a
set nobackup
set nocompatible
set noswapfile
set nowritebackup
set number
set signcolumn=yes
set title
set wrap
setlocal wrap
" Settings END
"------------------------------------------------

"------------------------------------------------
" persist START
set undofile " Maintain undo history between sessions
set undodir=~/.vim/undodir

" Persist cursor
autocmd BufReadPost *
  \ if line("'\"") >= 1 && line("'\"") <= line("$") && &ft !~# 'commit'
  \ |   exe "normal! g`\""
  \ | endif
" persist END
"------------------------------------------------

"------------------------------------------------
" Theme START
syntax on
set termguicolors
colorscheme gruvbox8
set background=dark
set cursorline
set hidden
set cmdheight=1
set laststatus=2

let g:gruvbox_transp_bg = 1
let g:gruvbox_italicize_strings = 0

set list
set listchars=tab:»·,trail:·

" let buffers be clickable
let g:lightline#bufferline#clickable=1
let g:lightline#bufferline#shorten_path=1
let g:lightline#bufferline#min_buffer_count=1

let g:lightline = {
\  'colorscheme': 'jellybeans',
\  'active': {
\    'left': [ [], [], [ 'relativepath' ] ],
\    'right': [ [], [], [ 'lineinfo', 'percent' ] ]
\  },
\  'inactive': {
\    'left': [ [], [], [ 'relativepath' ] ],
\    'right': [ [], [], [ 'lineinfo', 'percent' ] ]
\  },
\  'subseparator': {
\    'left': '', 'right': ''
\  },
\  'tabline': {
\    'left': [ ['buffers'] ],
\    'right': [ [] ]
\  },
\  'tabline_separator': {
\    'left': "", 'right': ""
\  },
\  'tabline_subseparator': {
\    'left': "", 'right': ""
\  },
\  'component_expand': {
\    'buffers': 'lightline#bufferline#buffers'
\  },
\  'component_raw': {
\    'buffers': 1
\  },
\  'component_type': {
\    'buffers': 'tabsel'
\  }
\}

" Theme END
"------------------------------------------------

"------------------------------------------------
" Remaps START
" Align GitHub-flavored Markdown tables
au FileType markdown vmap <Leader><Bslash> :EasyAlign*<Bar><Enter>

" Toggle between buffers
nmap <Leader>bn :bn<CR>
nmap <Leader>bp :bp<CR>
nnoremap <C-p> :Rg<Cr>
nnoremap <C-e> :Files<Cr>
nmap <Leader>bl :Buffers<CR>
nmap <Leader>g :GFiles<CR>
nmap <Leader>e :Files<CR>
nmap <Leader>p :Rg<CR>
nmap <Leader>g? :GFiles?<CR>
nmap <Leader>h :History<CR>
" Remaps END
"------------------------------------------------

"------------------------------------------------
" Coc START
" Having longer updatetime (default is 4000 ms = 4 s) leads to noticeable
" delays and poor user experience.
set updatetime=300

" Don't pass messages to |ins-completion-menu|.
set shortmess+=c

" Use tab for trigger completion with characters ahead and navigate.
" NOTE: Use command ':verbose imap <tab>' to make sure tab is not mapped by
" other plugin before putting this into your config.
inoremap <silent><expr> <TAB>
      \ pumvisible() ? "\<C-n>" :
      \ <SID>check_back_space() ? "\<TAB>" :
      \ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"

function! s:check_back_space() abort
  let col = col('.') - 1
  return !col || getline('.')[col - 1]  =~# '\s'
endfunction

" Use <c-space> to trigger completion.
if has('nvim')
  inoremap <silent><expr> <c-space> coc#refresh()
else
  inoremap <silent><expr> <c-@> coc#refresh()
endif

" Use <cr> to confirm completion, `<C-g>u` means break undo chain at current
" position. Coc only does snippet and additional edit on confirm.
" <cr> could be remapped by other vim plugin, try `:verbose imap <CR>`.
if exists('*complete_info')
  inoremap <expr> <cr> complete_info()["selected"] != "-1" ? "\<C-y>" : "\<C-g>u\<CR>"
else
  inoremap <expr> <cr> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
endif

" Use `[g` and `]g` to navigate diagnostics
" Use `:CocDiagnostics` to get all diagnostics of current buffer in location list.
nmap <silent> [g <Plug>(coc-diagnostic-prev)
nmap <silent> ]g <Plug>(coc-diagnostic-next)

" GoTo code navigation.
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)

" Use K to show documentation in preview window.
nnoremap <silent> K :call <SID>show_documentation()<CR>

function! s:show_documentation()
  if (index(['vim','help'], &filetype) >= 0)
    execute 'h '.expand('<cword>')
  else
    call CocActionAsync('doHover')
  endif
endfunction

" Highlight the symbol and its references when holding the cursor.
autocmd CursorHold * silent call CocActionAsync('highlight')

" Symbol renaming.
nmap <leader>rn <Plug>(coc-rename)

" Formatting selected code.
xmap <leader>f  <Plug>(coc-format-selected)
nmap <leader>f  <Plug>(coc-format-selected)

augroup mygroup
  autocmd!
  " Setup formatexpr specified filetype(s).
  autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
  " Update signature help on jump placeholder.
  autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
augroup end

" Remap keys for applying codeAction to the current buffer.
nmap <leader>ga  <Plug>(coc-codeaction)
" Apply AutoFix to problem on the current line.
nmap <leader>qf  <Plug>(coc-fix-current)

" Add `:Format` command to format current buffer.
command! -nargs=0 Format :call CocAction('format')

" Add `:Fold` command to fold current buffer.
command! -nargs=? Fold :call     CocAction('fold', <f-args>)

" Add `:OR` command for organize imports of the current buffer.
command! -nargs=0 OR   :call     CocAction('runCommand', 'editor.action.organizeImport')

" Mappings for CoCList
" Show all diagnostics.
nnoremap <silent><nowait> <space>a  :<C-u>CocList diagnostics<cr>
" Show commands.
nnoremap <silent><nowait> <space>c  :<C-u>CocList commands<cr>
" Find symbol of current document.
nnoremap <silent><nowait> <space>o  :<C-u>CocList outline<cr>
" Search workspace symbols.
nnoremap <silent><nowait> <space>s  :<C-u>CocList -I symbols<cr>
" Do default action for next item.
nnoremap <silent><nowait> <space>j  :<C-u>CocNext<CR>
" Do default action for previous item.
nnoremap <silent><nowait> <space>k  :<C-u>CocPrev<CR>

I know there is a lot here but this gets everything we need to be like vscode.

tmux.conf

For linux and OSX create ~/.tmux.conf

# Scroll up with mouse
set-option -g mouse on
set -g set-clipboard on

# Scrollback buffer
set -g history-limit 1000

# tmux display things in 256 colors
set-option -g default-terminal "xterm-256color"
set-option -g terminal-overrides "xterm-256color"

# allow for navigating between words with option
set-window-option -g xterm-keys on

# command delay? We don't want that, make it short
set -g escape-time 10

# Allow the arrow key to be used immediately after changing windows
set-option -g repeat-time 0

# Set window notifications
set -g monitor-activity on
set -g visual-activity on

# Update files on focus (using for vim)
set -g focus-events on

# Status update interval
set -g status-interval 1

# Reduce time to wait for Escape key. You'll want this for neovim.
set-option escape-time 40

# Option to clear histroy
bind -n C-k clear-history
bind-key -n C-l send-keys 'C-l'
bind-key R switch-client -r

######### DISPLAY ##########
set -g renumber-windows on    # renumber windows when a window is closed

######### THEME  ##########
set -g status-bg colour237
set -g status-fg colour246
set-option -g pane-active-border-style fg=colour239
set-option -g pane-border-style fg=colour237
set -g mode-style fg=colour235,bg=colour66
set-option -g message-style bg=colour66,fg=colour235

set-option -g status-justify "left"
set-option -g status-left-style none
set-option -g status-left-length "80"
set-option -g status-right-style none
set-option -g status-right-length "80"

set-option -g status-right '#(gitmux -cfg ~/.gitmux.conf "#{pane_current_path}") %H:%M:%S '
set-window-option -g window-status-separator " "
set-window-option -g window-status-current-format "#[fg=colour66]#W"
set-window-option -g window-status-format "#W"

# Allow us to reload our Tmux configuration while
# using Tmux
bind r source-file ~/.tmux.conf \; display "Reloaded!"

if "test ! -d ~/.tmux/plugins/tpm" \
   "run 'git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm && ~/.tmux/plugins/tpm/bin/install_plugins'"

set -g @plugin 'casonadams/tmux-vi-navigation'
set -g @yank_selection 'clipboard'
set -g @yank_selection_mouse 'clipboard'

run -b '~/.tmux/plugins/tpm/tpm'

To install plugins while in tmux session ctrl+b I

alacritty.yml

Linux and OSX save this file to ~/.config/alacritty/alacritty.yml

env:
  TERM: xterm-256color

window:
  dimensions:
    columns: 0
    lines: 0
  padding:
    x: 0
    y: 0

  # Spread additional padding evenly around the terminal content.
  dynamic_padding: true
  decorations: full
  startup_mode: Windowed

scrolling:
  history: 10000
  multiplier: 3

# Font configuration (changes require restart)
font:
  # Normal (roman) font face
  normal:
    family: "JetBrains Mono"
    style: Regular
  size: 10.0
  offset:
    x: 0
    y: 0
  glyph_offset:
    x: 0
    y: 0

# If `true`, bold text is drawn using the bright color variants.
draw_bold_text_with_bright_colors: true

# Colors (Gruvbox dark)
colors:
  primary:
    hard contrast: background = '0x1d2021'
    background: "0x282828"
    soft contrast: background = '0x32302f'
    foreground: "0xebdbb2"

  # Normal colors
  normal:
    black: "0x282828"
    red: "0xcc241d"
    green: "0x98971a"
    yellow: "0xd79921"
    blue: "0x458588"
    magenta: "0xb16286"
    cyan: "0x689d6a"
    white: "0xa89984"

  # Bright colors
  bright:
    black: "0x928374"
    red: "0xfb4934"
    green: "0xb8bb26"
    yellow: "0xfabd2f"
    blue: "0x83a598"
    magenta: "0xd3869b"
    cyan: "0x8ec07c"
    white: "0xebdbb2"

mouse:
  hide_when_typing: false

selection:
  semantic_escape_chars: ',│`|:"'' ()[]{}<>'
  save_to_clipboard: false

cursor:
  style: Block
  unfocused_hollow: true

# Live config reload (changes require restart)
live_config_reload: true

gitmux.conf

Linux and OSX save to ~/.gitmux.conf

tmux:
  symbols:
    branch: ''
    hashprefix: ':'
    ahead: ↑·
    behind: ↓·
    staged: '● '
    conflict: '✖ '
    modified: '✚ '
    untracked: '… '
    stashed: '⚑ '
    clean: ✔
  styles:
    state: '#[fg=red]'
    branch: '#[fg=colour246]'
    remote: '#[fg=cyan]'
    staged: '#[fg=green]'
    conflict: '#[fg=red]'
    modified: '#[fg=red]'
    untracked: '#[fg=magenta]'
    stashed: '#[fg=cyan]'
    clean: '#[fg=green]'
  layout: [branch, '']
  options:
    branch_max_len: 0

Install

run this command in the terminal to install plugins nvim +'PlugInstall' +qa --headless

Using

Change Dir to project. Open a file to edit nvim file
coc-vim will prompt to install pugins for the lanugage of choice.

Some Navigation tips

cmd Description
gd Go to Definition
gy Type Definition
gi Implentation
gr Show References
rn Rename
Space qf Quick fix
Shift K Show Hover
Space bl Show Buffers
Space e Show Files
Space p Fuzzy find
ctrl+b \ Split pane horz 25%
ctrl+b h Jump to pane left
ctrl+b j Jump to pane down
ctrl+b k Jump to pane up
ctrl+b l Jump to pane right

Posted on by:

Discussion

pic
Editor guide
 

Yet another install NeoVim on your *nix machines and configs. What about Windows?

Tmux doesnt support Windows. And before someone suggests me to switch to Linux. I would say Been there, done that, regretted that.

 

You're not missing too much by not using tmux. Find yourself a terminal that supports tabs and split panes and you're done. I used cmder in the past, it was good and supports split panes.

There is also the new windows terminal, which is called windows terminal. That also looks good. Or maybe one of those electron based terminal like this one.

Another thing you can try is use neovim itself as a replacement for tmux. Using neovim-qt and this plugin.

 

nvimux looks pretty awesome thanks for the suggestion! Alacritty terminal is the only terminal that doesn’t have lag. Most of those electron based ones are super laggy! They are awesomely full featured, but with that there are trade offs.

I really love tmux because I can use it as a server and pair program:)

 

Never mind guys. I switched to Linux now. Everything is even-steven.

Thing is I don't find devs talking about Windows compatibility and with rumours of Windows NT kernel being replaced by Linux one, I though it would be wise to get on the train sooner. I won't complain though. Windows has given me so many games and things to not worry about. It has its pros and cons just like Linux has its.

Also, I have stopped playing games since the last 6 months. So, I didn't require Windows. I switched to Garuda Linux and everything is working good.

Anyways thanks for the suggestion.

 

I have neovim running on Windows. With the new terminal it works really well.

 

Have you tried WSL2 before? You then should be able to do pretty much everything in this post.

 

I just started using tmux. I used the tabs and panes my terminal emulator provided for years and it works perfectly fine.

 
 

I prefer to use the undofile and not deal with the swapfile. undofile is nice because I can close vi and reopen and still undo changes I made before.

 

he use undofile. i came neovim from vscode too and the swap file is so annoy. i already have git and undofile then i don't need it

 

you map to many key for function key in alacrtty . what is the purpose to do that

 

This is a pretty vanilla alacritty.yml file (or at least less then a year ago). Honestly I don't use any of them.

 

Asking the important questions

 

You didnt get into the outcome, was it worth all this configuration? Speed? Ease of use? Could you replicate the same features? Any disadvantages?

I guess for Windows, this is off limits, unless you use WSL.

 

Yeah I don’t do windows.

 

Looks good, I too have recently switched fully into using NeoVim.

 

Thank you! Do you have these configs in a dotfile in a repo somewhere?