wonderfulfrog.com/src/content/posts/my-vim-setup-04-2021.md
2024-02-10 23:31:20 -08:00

351 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: My vim setup
draft: false
date: 2021-04-18T20:24:10.177Z
excerpt: Everybody does it differently.
categories: ["vim", "development"]
---
{% image "https://cdn.wonderfulfrog.com/vimsetup.png", "A screenshot of my `vim` setup in action.", "" %}
I thought it would be fun to talk about my `vim` configuration. Everyone does it differently, and I wanted to toss my hat into the ring.
I dont claim to have the best setup, but it works great for JavaScript (React, node) and TypeScript development.
I keep my `.vimrc` and other related files up to date on [GitHub](https://github.com/devinwl/dotfiles).
This has been a helpful exercise in evaluating what my configuration options do, and which ones I can get rid of. After a while these things tend to accumulate a lot of cruft.
I pledge to keep this page up to date as I add (or remove) changes to it.
## nvim
I use [Neovim](https://neovim.io) (`nvim`) instead of `vim` because it has support for fancier plugins, and it handles asynchronous actions better than `vim`, in my experience.
Plus it has “neo” in the name, and thats plain cool.
## Basics
This section captures what I would consider to be the basics of vim: clipboard behaviour, backspace behaviour, spellchecking, all that jazz.
```
set nocompatible
```
This tells vim to use `vim` settings rather than `vi`. To be honest I dont full understand what this does, but see it enough in other `.vimrc` I decided to include it.
```
set number
set relativenumber
```
This enables line numbers. Youre gonna need those if youre developin. `relativenumber` shows relative line numbers from the currently highlighted line.
```
set title
```
Sets the terminal windows title to be the file currently being edited (I think).
```
set scrolloff=2
```
This changes the scroll offset, or in other words when `vim` decides to start scrolling. In my case, once I am on the 2nd to last line of my screen and I want to scroll down (or up), it will scroll the screen upwards and move to the next line.
```
set backspace=indent,eol,start
```
This makes the BACKSPACE key behave in a sane way while using `vim`. I dont know why this behaviour isnt default — probably some holdover from the “old days”.
```
set nowrap
```
No linewrapping allowed. I switch around this setting from time to time.
```
set noerrorbells
set belloff=all
```
I dont see how playing a sound when there is an error is helpful — like when I try to scroll past the end or beginning of the file. Turn that off.
```
set hlsearch
```
This will highlight all search matches on any open buffers, like when using `/` to search for text.
```
set incsearch
```
As I start typing when using `/`, it will highlight things as they are matched (before pressing ENTER).
```
set signcolumn=yes
```
This enables the sign column in `vim`, which can be used by plugins to highlight lines with errors, warnings, and so on.
```
set hidden
```
`vim` by default will throw away buffers when you switch away from them. This stops that behaviour. A reasonable expectation with any modern text editor.
```
set nobackup
set nowritebackup
```
`vim` likes to create backup files (adding `~` to the extension) and I dont like them. I use version control software and Im content with that.
```
set cmdheight=2
```
This gives me more breathing room in the command window.
```
set shortmess+=c
```
Shortens messages from `vim`.
```
set path=$PWD/**
```
When running searches in `vim`, set the project directory to where I currently am.
```
set showmode
```
Shows which mode `vim` is currently in on the command window. Im forgetful.
```
set ignorecase
set smartcase
```
Makes search patterns case-insensitive. Except when the search pattern contains uppercase characters (`smartcase`).
```
set clipboard=unnamed
```
Removes `vim`s separate clipboard, and “shares” it between `vim` and the outside world (your computer).
```
set cursorline
```
Highlights the line the cursor is currently on. Makes it easier for me to find the cursor.
## Tabs and spaces
```
set tabstop=2
set shiftwidth=2
set softtabstop=2
set expandtab
set shiftround
set smarttab
set smartindent
set autoindent
set copyindent
```
I dont care if we use tabs or spaces anymore, Ill use what the project at hand wants.
Tab uses spaces, and each tab is 2 spaces.
If Im at a certain indentation level, then these options ensure I maintain it and it always a multiple of `shiftwidth`.
## Spellchecking
```
autocmd FileType gitcommit setlocal spell
autocmd FileType markdown,md,mdx setlocal spell
```
When I am writing a `git` commit, or inside a Markdown file I want to add spellchecking.
## Forcing myself to learn hjkl
```
noremap <Up> <NOP>
noremap <Down> <NOP>
noremap <Left> <NOP>
noremap <Right> <NOP>
inoremap <Down> <NOP>
inoremap <Left> <NOP>
inoremap <Right> <NOP>
inoremap <Up> <NOP>
```
`hjkl` is essential way to move around in `vim`. You dont have to move your hands from home row. Its hard to learn at first, but if you disable the arrow keys, you start to learn pretty quick.
## netrw
```
let g:netrw_banner = 0
```
This hides the giant help banner when using `netrw` (`:E`). I use `netrw` to move around sometimes, when CTRL + P doesnt cut it.
## Split movement
```
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>
```
I use splits a lot and this makes it easier to move around between them.
## Plugins
```
call plug#begin('~/.vim/plugged')
```
I use [vim-plug](https://github.com/junegunn/vim-plug) to manage all my plugins.
### auto-pairs
Adds pairs of quotes, brackets, etc. If I type `”`, itll add a closing quote. Works with `()` and `{}`.
```
let g:AutoPairsMultilineClose = 0
```
This disables the default behaviour of trying to close any pair even if it was on another line. When writing code blocks `{}`, it would jump to the next closing `}` if I was inside another code block. It might make sense to someone, but for me it just annoyed me. Thankfully it can be switched off!
### vim-surround
Took me a while to get, but once I did I cant imagine life without it. Wrap words/quotes/code blocks/whatever in more quotes or characters. A mnemonic from my coworker:
```
(y)olo (s)urround (i)n (w)ord/(“)quote/etc
```
### vim-commentary
I use `gc` all the time. Comment entire blocks or lines super quick. Easy to remember.
### vim-polyglot
Syntax highlighting for various languages. I use JavaScript (and adjacent stuff like JSON) 99% of the time, but nice to have for shell scripts, Ruby, and so on.
### fzf
One day I might learn how to use `vimgrep`, but for now I have `fzf`. Requires extra binaries. I thought I needed NERDTree to move around, but `fzf` has got my back.
```
nnoremap <silent> <c-p> :GFiles --cached --others --exclude-standard<cr>
```
This makes CTRL + P filter files that are part of the projects `.gitignore` by default.
### vim-fugitive
Ive got this installed but dont use it much. It adds `git` support right in `vim`, but I almost always have a second tab open in my terminal explicitly for `git` operations.
### vim-rhubarb
Like the above, it offers a neat feature, but I keep forgetting to use it. It will create a link directly to the line youre on in `vim`.
### coc.nvim
I bet this one will garner controversy. Getting intelligent autocomplete in `vim` was never something it was intended to do, but `coc` in combination with `nvim` gets us there. For it to function “just so” requires extra configuration, which Ill highlight below.
```
let g:coc_global_extensions = [
\ 'coc-tsserver',
\ 'coc-json',
\ ]
```
This runs these `coc` plugins all the time. Since Im always mucking about in JavaScript, this isnt a big deal. Its smart enough to know when Im *not* in JavaScript and to not complain, which works for me.
```
if isdirectory('./node_modules') && isdirectory('./node_modules/prettier')
let g:coc_global_extensions += ['coc-prettier']
endif
if isdirectory('./node_modules') && isdirectory('./node_modules/eslint')
let g:coc_global_extensions += ['coc-eslint']
endif
```
This tells `coc` to load up `eslint` and `prettier` extensions if Im using them in my project. Super handy to automatically load up `prettier` only when I need it.
```
nnoremap <silent> K :call CocAction('doHover')<CR>
```
Rarely do I need to trigger `coc` on its own, but this is for the odd time. Nice for when looking up variable types (using TypeScript), or method arguments.
```
command! -nargs=0 Prettier :CocCommand prettier.formatFile
```
Shortcut to run `prettier` using `:Prettier`. I dont use this often since I have it configured to run on save.
### coc-settings.json
```
"suggest.noselect": false,
```
This option pre-selects the first option in the autocomplete list.
```
"eslint.autoFixOnSave": true,
"eslint.filetypes": ["javascript", "javascriptreact", "typescript", "typescriptreact"],
```
This runs `eslint` on save, and ensures that the files in `filetypes` run `eslint`.
```
“coc.preferences.formatOnSaveFiletypes": ["markdown", "mdx", "javascript", "javascriptreact", "typescript", "typescriptreact"],
```
This runs `prettier` for me on these filetypes when saving. Somehow this doesnt interfere with `eslint`, which is magic to me.
```
"coc.preferences.jumpCommand": "vsplit"
```
When using commands like `gd` (goto definition), it will open in a new `:vsplit` by default.
## Theme
I saved the best for last.
I currently use the [Rigel](https://rigel.netlify.app) theme.
```
set statusline=%f%=%m%r%h%w%y[%04l,%04v]
```
This sets up my status line to show me what I need to know:
* The file Im editing
* A marker if the file has been modified but not saved
* What language mode Im in
* What line Im on
* What column Im on
```
highlight Comment cterm=italic gui=italic
```
My font of choice is [Operator Mono](https://www.typography.com/fonts/operator/overview), and it has beautiful cursive italics that I want to see. Anything comments in the file (or certain keywords) are converted into *italics*.