samoshkin / dotvim

Personal vim configuration: vimrc file and friends
58 stars 4 forks source link

dotvim

Personal Vim configuration designed in a modular way.

A warn note. I tested it on my local machine only so far. Most likely it depends on my own environment (terminal, OS, installed apps) in some unforeseen ways. With that said, I cannot guarantee the smooth experience on your machine. Be prepared to fix issues on your own.

Tested under:

Table of Contents

Features

Screenshots

Installation

git clone https://github.com/samoshkin/dotvim ~/.vim
cd ~/.vim
./install.sh

Required external dependencies. Make sure they are installed and are available on PATH:

Mappings

Most native Vim mappings work as you expect. This config follows and builds upon the ideology and spirit of the Vim, rather than fighting against it.

leader and localleader are mapped as:

nnoremap <Space> <Nop>
let mapleader=" " "<Space>
let maplocalleader=","

Toggle various settings/feature ON and OFF with a uniform mapping that starts with <leader>t, for example:

nmap <leader>ts     :ToggleSyntax<CR>
nmap <leader>th     :set hlsearch!<CR>
nmap <leader>tl     <Plug>(qf_loc_toggle_stay)
nmap <leader>tq     <Plug>(qf_qf_toggle_stay)
nmap <leader>tt     :GutentagsToggle<CR>
nmap <leader>t{}    :DelimitMateSwitch<CR>
nmap <leader>tp     :set paste!<CR>
nmap <leader>td     :GitGutterBufferToggle<CR>
nmap <leader>tw     :setl wrap!<CR>
nmap <leader>tz     :setlocal foldenable!<CR>
nmap <leader>te     :call CocAction("diagnosticToggle")<CR>

<C-C> is mapped to <Esc>. Use it to exit from any non-Normal mode, plus it works to exit insert completion menu, coc.nvim lists, various fzf popups. IMO, <C-c> is easier to type that <ESC> or other alternatives like jk. Most likely you already get used to it after working in a shell.

inoremap <C-C> <ESC>
noremap <C-C> <ESC>
vnoremap <C-C> <ESC>

By default terminal Vim does not distinguish <S-CR> and <C-CR> from regular <CR>. However, you can tell the terminal to send specific escape sequence (\e[13;2u, \e[13;5u) and instruct Vim to recognize them.

" See https://stackoverflow.com/questions/16359878/how-to-map-shift-enter
" See https://vim.fandom.com/wiki/Mapping_fast_keycodes_in_terminal_Vim
execute "set <F20>=\e[13;2u"
execute "set <F21>=\e[13;5u"

The solution is not portable, but these keys are quite useful, especially in the Insert mode:

" Shift-Enter(remapped as <F20>) to start editing new line below without splitting the current one
" Ctrl-Enter(remapped as <F21>) to start editing new line above
inoremap <F20> <C-o>o
inoremap <F21> <C-o>O

When Vim is running inside tmux, <S-arrow> and <C-arrow> keys are not delegated by tmux downwards to the Vim. To enable it, you need to change your tmux.conf:

set -wg xterm-keys on

Even despite that, Vim's still not able to automatically recognize <S-arrow> and <C-arrow> keys when tmux reports itself as a screen-256color. This is due to the lack of data in a terminfo database for that terminal type. To fix it manually tell Vim about right escape sequences:

if &term =~ '^screen'
  " tmux will send xterm-style keys when its xterm-keys option is on
  execute "set <xUp>=\e[1;*A"
  execute "set <xDown>=\e[1;*B"
  execute "set <xRight>=\e[1;*C"
  execute "set <xLeft>=\e[1;*D"
endif

Text objects

There're a bunch of custom text objects installed. The "Zen" of vim is that you're speaking a language. Grammar consists of basic vocabulary: verbs, modifiers, nouns. The text objects extend the vocabulary of available {nouns}.

iW aW, WORD
iw aw, word
is as, sentence
ip ap, paragraph

i' a', single quotes
i" a", double quotes
i` a`, back ticks
iq/aq, between any quote

i( a(, parenthesis
i[ a[, brackets
i{ a{, bracnes
i> a>, angle brackets
ib/ab, between any paretheses and braces

if/af, function (when supported by the language server)
ic/ac, class (when supported by the language server)
ia/aa, function arguments

ie/ae, entire file
il/al, current line
ii/ai, block of lines with same indentation
iy/ay, syntax highlights
iu/au, URIs
iv/av, variable segement of lower_case or camelCase
iz/az, block of folded lines
ih/ah, vim-gitgutter diff hunks
im/am, to select matchit % pairs
ib/ab, text between parentheses and braces ( [ { <

gc,    commented text

IDE-like experience using language servers

Language server integration brings highly important features that are usually found only in IDEs. To enumerate most prominent ones:

coc.nvim is the Vim plugin that represent the client-side of the LSP protocol, whereas language server itself should be installed separately. Each language server usually takes care of a particular file type or a language. To mention some of them: tsserver, vim-lsp, vscode-json-languageservice, bash-language-service

coc-extensions file is just a normal package.json file that declares installed language servers. Extensions should be installed in a special folder, and install.sh script takes care of it:

mkdir -p "~/.config/coc/extensions"
ln -sf "~/.vim/coc-extensions.json" "~/.config/coc/extensions/package.json"
pushd ~/.config/coc/extensions
yarn install
popd

coc-settings.json is the main configuration file for coc.nvim itself plus any language server you installed before. To open it from inside the Vim, use :CocConfig command.

Code linting is done through the coc-diagnostic language server. It's a special one because it's not limited to support single file type, but allows you to plug any linter program and lint any file. Checkout [coc-settings.json]() for the configuration:

"diagnostic-languageserver.filetypes": {
  "vim": "vint",
  "email": "languagetool",
  "markdown": [ "write-good", "markdownlint" ],
  "sh": "shellcheck",
  "javascript": ["eslint"],
  "javascriptreact": ["eslint"],
  "scss": ["stylelint"],
  "sass": ["stylelint"],
  "less": ["stylelint"],
  "css": ["stylelint"]
}

Note, that dense-analysis/ale is not used in this config.

Modular configuration

Unlike most .vim configuration on the internet, this one does not keep hundreds of settings kept in a single giant vimrc file. On the contrary, settings and functions are broken down into the individual files, with a respect to Vim guidelines.

Here is the .vim directory outline:

├── after
│  ├── colors
│  │  └── gruvbox.vim
│  ├── ftplugin
│  │  ├── git.vim
│  │  ├── gitcommit.vim
│  │  ├── markdown.vim
│  │  ├── scss.vim
│  ├── plugin
│  │  └── colorscheme.vim
│  └── syntax
│     ├── gitcommit.vim
│     ├── json.vim
│     └── nerdtree.vim
├── autoload
│  ├── _
│  │  ├── buffer.vim
│  │  ├── diff.vim
│  │  ├── fugitive.vim
│  │  ├── mixedwhitespace.vim
│  │  ├── qfloc.vim
│  │  ├── search.vim
│  │  ├── session.vim
│  │  ├── util.vim
│  │  └── window.vim
│  └── plug.vim
├── coc-extensions.json
├── coc-settings.json
├── deprecated
│  ├── plug_ale.vim
│  └── plug_findfiles.vim
├── filetype.vim
├── install.sh
├── nerdtree_plugin
│  ├── copy_path_to_clipboard.vim
│  └── gitignore_filter.vim
├── plugin
│  ├── buffer.vim
│  ├── colors.vim
│  ├── command.vim
│  ├── diagnostic.vim
│  ├── diff.vim
│  ├── motion.vim
|  |   ...........
│  ├── plug_cleverf.vim
│  ├── plug_coc.vim
│  ├── plug_commentary.vim
│  ├── plug_delimitmate.vim
│  ├── plug_editorconfig.vim
│  ├── plug_exchange.vim
├── UltiSnips
└── vimrc

Plugins

vim-plug is used as a plugin manager. All plugin dependencies are pinned to a specific commit for repeatable and stable installations.

Plug 'junegunn/fzf', { 'do': { -> fzf#install() }, 'commit': '8c533e3' }
Plug 'junegunn/fzf.vim', { 'commit': '811b860' }
Plug 'pbogut/fzf-mru.vim', { 'commit': 'c0a6bda' }

For the full list of plugins, checkout main vimrc file or use :PlugStatus command.