Cláudio Ribeiro

@claudio.santos.ribeiro

Using Neovim for Javascript Development

Courtesy of Fotis Fotopoulos on Unsplash

For many of us, Neovim has become an absolute necessity. Over the last couple of years, I’ve used Neovim to program, to write and even as a window manager. The last couple of weeks I felt the need to edit a lot of Javascript files, and with, the need to configure Neovim to deal with Javascript.

This article details all the plugins and configurations I’ve used to configure Neovim for Javascript editing, completing and linting.

First of all, we’ll need to have the Neovim package installed from Python. We’ll also need a recent version of Node and some basic knowledge of Neovim.

I’ve been using Vim-Plug as my plugin manager for some time now, and I’ll be using it here, but you can use any of the other ones (like Vundle or Pathogen).

First thing I did was to navigate to my Neovim configuration file. Unlike pre-Vim 8 versions, we’re not looking for the .vimrc file. In Neovim we’re looking for the ~/.config/nvim/init.vim file.

To install new plugins using Vundle we need the following block in our configuration file:


call plug#begin()
call plug#end()

Everything in between these two lines is referred plugins that need to be installed.

Auto-Completion

The first thing I wanted to install was some sort of code analyzer that would help me with auto-completion. I decided to go with Tern for Vim.

call plug#begin()
Plug ‘ternjs/tern_for_vim’, { ‘do’: ‘npm install && npm install -g tern’ }
call plug#end()

For those of you unfamiliar with TernJs, it’s a stand-alone, editor-independent JavaScript analyzer that can be used to improve the JavaScript integration of existing editors.

Also, as we can see, I’m also installing both the plugin dependencies as well as a global tern package. This is just to keep the plugin in sync with the global ternjs package installed on my computer.

Anytime we want to actually install the plugins we add to the list, it’s a matter of running :PlugInstall inside Neovim and he’ll do all the work for us.

Now, with tern already installed, we have to actually configure it so he can know what and where to check. So, in I created a .tern-config file in my home directory with the following content:


{
“plugins”:
{
“node”: {}
}
}

I did a global configuration file, but this can also be done locally by adding the file to the root of your project. After running :PlugInstall we’re now ready to start using tern. For that, we use Omni-completion commands <C-x><C-o> to trigger the completion candidates.

This is great, but it’s just scratching the surface. Neovim brought us asynchronous execution. So why should we need to use Omnicompletion commands whenever we want auto-completion. Neovim should do that for us.

That’s where Deoplete comes into action.

Deoplete is a very cool plugin that provides an extensible and asynchronous completion framework for neovim/Vim8.


call plug#begin()
Plug ‘Shougo/deoplete.nvim’, { ‘do’: function(‘DoRemote’) }
Plug ‘ternjs/tern_for_vim’, { ‘do’: ‘npm install && npm install -g tern’ }
Plug ‘carlitux/deoplete-ternjs’
call plug#end()
let g:deoplete#enable_at_startup = 1
let g:deoplete#enable_ignore_case = 1
let g:deoplete#enable_smart_case = 1
let g:deoplete#enable_camel_case = 1
let g:deoplete#enable_refresh_always = 1
let g:deoplete#max_abbr_width = 0
let g:deoplete#max_menu_width = 0
let g:deoplete#omni#input_patterns = get(g:,’deoplete#omni#input_patterns’,{})
let g:tern_request_timeout = 1
let g:tern_request_timeout = 6000
let g:tern#command = [“tern”]
let g:tern#arguments = [“ — persistent”]

Deoplete allows others to hook into it and provide completions for candidates on screen. It comes preconfigured with file path completion, ctags completion and for strings that appear in each of your vim buffers. deoplete-ternjs is another package that plugs into deoplete that provides completions using the ternjs server.

We also added a lot of configurations for both Deoplete and tern. These help us shape our plugins behavior.

After running :PlugInstall once more, we should have fully working asynchronous completion. Try typing something Javascript related and auto-completion should be triggered automatically.

Linting

Linting was the next thing I wanted working. Since I’m not a Javascript genius, linting was really up there on my needs. It allowed me to be a little bit more relaxed with my code as I know that any mistake would be quickly uncovered.

I decided to use Neomake since it’s used and proved. I added the following:

Plug ‘neomake/neomake’, { ‘on’: ‘Neomake’ }

to my plugin list and

let g:neomake_javascript_enabled_makers = [‘eslint’]

to the configurations. We are using eslint but we can add or remove linters from that list as we need.

File jumping

Lastly, I also wanted some sort of “Jump to declaration” kind of functionality. In Vim we normally use Ctags for that effect. But vim-gutentags takes care of the much-needed management of tags files in Vim. It will (re)generate tag files as you work while staying completely out of your way. This will spare us the effort of generating and re-generating tags files manually.

So, I added to the plugin list:

Plug ‘ludovicchabant/vim-gutentags’

After running :PlugInstall once again and opening a project, we should be able to To jump to definitions using ctags. Just hover over a defined variable or import statement and type <C-]>.

Conclusion

This was my basic setup for Javascript programming. There are a lot more plugins and configurations that can be used to turn this into an even better experience.

What plugins and configurations are you using for Javascript development with Neovim?

Want to learn more about Vim? Want to learn how to use it as an IDE? Check out my new book An IDE Called Vim. It has everything from basic Vim usage to file finding, auto-completion, file manager and more.

More by Cláudio Ribeiro

Topics of interest

More Related Stories