I've seen a lot of tweets recently that basically state that vim
is not suitable for frontend development. So I decided to do a small overview of my setup(I'm mostly a frontend developer although I do some backend and devops stuff as well).
My setup
You can find all configuration and instructions on how to install it in my github repo:
Vim Settings
An article describing key features of this config.
Prerequisites
In order to get all features you might want to install following packages:
Installation
On unix and windows(with bash which can be installed with git):
curl -L https://raw.github.com/gko/vimio/main/install.sh | bash
macOS
In macOS terminal.app don't forget to check the «Use option as meta key»:
And «Esc+» option in iterm2:
Shortcuts
Some of shortcuts(Leader key is comma):
- Ctrl + s saves current file
-
Leader + s in both
select
andnormal
mode initiates search and replace - Alt + Up/Down moves line or selection above or below current line(see upside-down for more info)
- Alt + Left/Right moves character or selection to left or to the right
- Leader + n toggles NERDTree
- Leader + m shows current file in NERDTree
- when in select mode ', ", ( wraps selection accordingly
- y…
File structure
The main file is init.vim
that is symlinked to .vimrc
during the installation. All the configuration scripts are stored in after/plugin/*.vim
. This way I can just add another script to that folder(with a name of a plugin for instance) and it will be automatically loaded during vim startup. It also helps me to keep things modular.
Spoiler
I should point out right away that perfect editor doesn't exist or at least it's different for everyone.
Why vim
I think there are many great editors and IDEs out there but there is one thing among others that stands out if you're using vim: you don't switch environment. So if you're in terminal and you've cloned a project, once you open it you're still in terminal. Even if you quit vim you're still in the same environment. For me, that's the most important thing about using vim(beside many other things, obviously).
With that out of the way let's take a look at some key features of my config.
Opening a project
In my mind any project is strongly linked with a repository(except monorepos of course), so when I open any file in a repository I want my editor to go to the root of the project(i.e. where the .git folder is located). There is a plugin for that:
airblade / vim-rooter
Changes Vim working directory to project root.
It goes through parent folders until it finds a repo, or your custom file or folder pattern that you can configure.
mhinz / vim-startify
🔗 The fancy start screen for Vim.
will help me quickly go back to recent projects.
Opening a file
Locally
I use fzf
and ctrlp
extensions.
The second one has also a ctrlb shortcut to switch between buffers.
In future I would like to use only fzf
Also with this plugin:
I can open a certain line, for instance:
vim ~/.vimrc:123
will open line 123 of .vimrc
file.
Opening file in the browser
Sometimes when you have a file opened you want to quickly jump to a Web version(for instance to leave a comment). For this I use the following plugin:
ruanyl / vim-gh-line
vim plugin that open the link of current line on github
The main shortcuts are:
- Leadergh — open file in the browser(current revision)
- Leadergb — open blame view for current file
- Leadergo — open repository in the browser
Please note, that if you use it in visual mode, it will automatically highlight selected line(s).
Sharing code via Carbon
Carbon is a code sharing website, that adds swag to it. To share selection(if you're in visual mode) or the whole file I use following vim extension:
kristijanhusak / vim-carbon-now-sh
Open selected text in https://carbon.now.sh
Here's my Carbon
config:
let g:carbon_now_sh_options = {
\ 'ln': 'true',
\ 'bg': 'rgba(74,144,226,1)',
\ 't': 'night-owl',
\ 'wt': 'none',
\ 'ds': 'true',
\ 'dsyoff': '20px',
\ 'dsblur': '68px',
\ 'wc': 'true',
\ 'wa': 'true',
\ 'pv': '56px',
\ 'ph': '56px',
\ 'fm': 'Fira Code',
\ 'fs': '14.5px',
\ 'lh': '141%',
\ 'si': 'false',
\ 'es': '2x',
\ 'wm': 'false'
\}
Miscellaneous
To configure vim
to change indentation rules per project I use:
editorconfig / editorconfig-vim
EditorConfig plugin for Vim
To search text within all files and replace it I use ripgrep that is supported natively in fzf
extension(Rg
command):
Taking notes with vim
I recently wrote a post about how to configure vim to quickly take notes:
I can add following plugin to that article:
MattesGroeger / vim-bookmarks
Vim bookmark plugin
It allows you to bookmark anything anywhere(even in NERDTree).
Color themes
By default I use:
cormacrelf / vim-colors-github
A Vim colorscheme based on Github's syntax highlighting as of 2018.
But I also installed the base16(this is a fork, due to some problems with the original repo) themes and configured vim so that it looks into ~/.vimrc_background
file and takes current base16
theme from there:
" set colorscheme
" if you have base16 installed take that colorscheme
try
if filereadable(expand("~/.vimrc_background"))
let base16colorspace=256
source ~/.vimrc_background
let g:airline_theme='base16'
else
colorscheme github
" https://github.com/cormacrelf/vim-colors-github/pull/5
hi! link SignColumn LineNr
let g:airline_theme = "github"
endif
catch /^Vim\%((\a\+)\)\=:E185/
colorscheme default
endtry
This way vim stays consistent with terminal theme.
Autocompletion
For autocompletion I use coc.nvim.
It's based on the same language server as vscode
.
Javascript
By default you won't have an autocompletion in javascript. To enforce typescript to enable autocompletion within javascript you have to add:
// @ts-check
At the top of the file. In my setup I have
a templates folder that contains predefined templates for new files(config can be found in templates.vim). So once I create new js file it already contains that comment.
Jumping between files
Coc
already provides different shortcuts to jump to function definition and what not:
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)
However vim
provides a magic shortcut gf
that allows you to jump to a file under cursor. The magic is that you can alter it's behavior per file type. For instance, in javascript we want to use the following algorithm to resolve the file:
- Check file locally
- If it doesn't exist check file in node_modules
- If it exists and it is a folder check the
package.json
formain
field. If it is present open it. - If the main field is not there check for
index.js
You can find the implementation in the after/ftplugin/javascript.vim file.
Linters
For linting I use Ale
(config — ale.vim):
dense-analysis / ale
Check syntax in Vim asynchronously and fix files, with Language Server Protocol (LSP) support
and prettier to autoformat:
prettier / vim-prettier
A Vim plugin for Prettier
Conclusion
Here I highlighted key features of my configuration. I encourage you to go check the full list of extensions that I use in the init.vim file and the configuration scripts in the after/plugin/ folder. I listed all the file types and commands for every extension explicitly so that there is nothing that fires up randomly.
Top comments (5)
I'm not sure of this vim-fetch thing.
is doing what
already does.
Looking at the repo, the author says it's to support log formats that would otherwise have to go through a "rather convoluted detour through an error file and the Quickfix window." but that's exactly how most people use it, as far as I know. That's what the quickfix window is for, so you can easily jump between errors. You don't usually paste in a line from an error log to the command arguments themselves.
Yes, but I wanted to support
.vimrc:123
format because it is often used in errors ofeslint
,jest
and other js tooling, so I can just jump to error line straight away after opening file in question without changing format.We use alot of the same tools. Thanks for sharing!
Why using ALE when COC.nvim also has a linter and errors highlighted?
BTW, thanks for the super informative article.
Thank you 🙏
I think it was due to that it supports only
eslint
and I was trying to make a generic config for multiple languages (ALE
supports a lot of linters).