Last Updated: 27 September 2019.

In this article, I’d like to share my setup and some of the Vim plugins that will transform your Vim into a perfect IDE for JavaScript and React (step back, VS Code!).

Obviously, you don't have to use everything. Feel free to copy things that work for your setup and your style of work.

Here's How My Vim Looks Like

Essentials

Here some important ones (they are all of a general-purpose).

Plug plugin manager used in this article

NERDTree to navigate the file tree

FZF let's you fuzzy search through the files in project (and much more, really)

jiangmiao/auto-pairs inserts quotes and parenthesis in pairs as you type

tpope/vim-commentary press gcc to comment out a line or gc to comment a selection in visual mode

You can read more about the essential plugins here.

Syntax highlighting

Vim is doing pretty well with syntax JavaScript highlighting out of the box. But it's not ideal.

Many of the old syntax plugins for JavaScript have troubles with some modern features like arrow functions or async/await.

Here are some plugins that will help to fix it.

YAJS (“Yet Another JavaScript Syntax”)

vim-jsx plugin for proper JSX support

Also, this color scheme called OceanicNext is real nice. It is a little bit like Sublime. You can see it on the first screenshot for this article.

Formatting

In Vim, there is a special gq ( :help format ) command that formats the code. By default, it's not very useful, but we can set up it to use an external program to format the code.

I use prettier for almost everything.

Don't forget to install it first (or make sure you have the latest version),

npm install -g prettier

Then put this into Vim's settings:

" FORMATTERS au FileType javascript setlocal formatprg=prettier au FileType javascript.jsx setlocal formatprg=prettier au FileType typescript setlocal formatprg=prettier\ --parser\ typescript au FileType html setlocal formatprg=js-beautify\ --type\ html au FileType scss setlocal formatprg=prettier\ --parser\ css au FileType css setlocal formatprg=prettier\ --parser\ css

gq is quite handy as it can be combined with the text objects:

gqgq format current line

format current line gqip format paragraph

format paragraph gggqG format the whole file

The last one is something I use quite often, so I have a mapping for it:

nnoremap <F5> mzgggqG`z

Linting

A linter is a binary that can analyze your code and tell you something about possible errors or formatting issues. Vim can use the linters and show the warnings with help of a plugin (there are multiple variants really).

Since the release of Vim 8 many people swapped the old Syntastic plugin with the new ALE plugin which is fast, easily customizable and asynchronous. The last thing means that your editor won’t freeze anymore as the linting happening. It also supports so many different languages, linters, and fixers that you won’t need to think about it anymore.

By default, it will just try to use as many linters as it is able to find in the system. I'd like to be a bit stricter about that. Here’s how I have it customized to associate specific linters with the file types:

let g:ale_linters = { \ 'python': ['flake8', 'pylint'], \ 'javascript': ['eslint'], \ 'vue': ['eslint'] \}

Many of the linters (like eslint) can also fix your code, which is very handy.

let g:ale_fixers = { \ 'javascript': ['eslint'], \ 'typescript': ['prettier', 'tslint'], \ 'vue': ['eslint'], \ 'scss': ['prettier'], \ 'html': ['prettier'], \ 'reason': ['refmt'] \} let g:ale_fix_on_save = 1

The last option will make ALE auto-fix your file every time you save it. And this is really neat.

Another useful feature is navigating to the next / previous error with ]r / [r .

nnoremap ]r :ALENextWrap<CR> " move to the next ALE warning / error nnoremap [r :ALEPreviousWrap<CR> " move to the previous ALE warning / error

Autocompletion

For the autocomplete in Vim there are multiple options. I use Deoplete, mostly because it just works with my current setup (I usually use Neovim).

Deoplete is an engine, so it doesn't provide any autocomplete itself, it merely aggregates all possible autocompletion-s into a friendly interface.

Language Server

I'm a big fan of Language Server Protocol which is a relatively new thing that got popularized by Microsoft with TypeScript. Basically, it's a separate server process that runs in the background and analyzes your codebase. Then any editor (including Vim) can act as a client to get some important information and even send commands.

By integrating with a Language Server, your editor can support features like autocompletion, going to the definition, and so on. There are multiple language servers for different languages, and of cause there's a good one for JavaScript.

You can install it with npm:

npm install -g javascript-typescript-langserver

ALE described in the previous section has some capabilities to work as a Language Client but I was unable to set up it properly for pure JavaScript. So instead I use a separate plugin.

Plug 'autozimu/LanguageClient-neovim', { \ 'branch': 'next', \ 'do': 'bash install.sh', \ }

The Language Client can start the server in background for you, but we need to specify which server (binary) we want to use for a specific file type.

let g:LanguageClient_serverCommands = { \ 'javascript': ['javascript-typescript-stdio'] \ 'ruby': ['~/.rbenv/shims/solargraph', 'stdio'], \ }

Alright, now that we all set up you can restart Vim and you should be able to run all those nice commands. I'd suggest the following mappings:

nnoremap <leader>l :call LanguageClient_contextMenu()<CR> nnoremap K :call LanguageClient#textDocument_hover()<CR> nnoremap gd :call LanguageClient#textDocument_definition()<CR> nnoremap <leader>r :call LanguageClient#textDocument_rename()<CR>

Now, <leader>l opens a menu showing all possible things you can do with language server.

The other ones are my mostly used commands:

K shows the available documentation when possible

shows the available documentation when possible gd jumps to where the symbol under the cursor has been first defined

jumps to where the symbol under the cursor has been first defined <leader>r rename the symbol under cursor

Laguage servers are really neat and they can do more interesting things. For references and for a table of supported languages refer to the official website.

What's next?