Code Formatting in Neovim for Beginners

Alexander Avery

Fri | Oct 23, 2020

computer-science An ordered array of lamps running along a concrete stairway.

Easing the cluttered mind

When developing software, I like to remove choices from my workflow. This may sound limiting, but if you remove the right choices from your development process will be maximally streamlined.

Recently, I noticed that formatting my code style was taking up too much of my development time. In pertinence to whitespace, curly braces, ternary operations, import order, and identifier names I’ve always had a consistent style, but enforcing it was a chore. The less time I spend worrying about those tasks, the more “brain cycles” I can spend on writing features, tests, and bug fixes. If linting and formatting is not new to you, you can skip here to see how to accomplish it in neovim.

Formatters and Linters

The fastest method, in terms of setup, to save time on code style (maintainability aside), is to write anything the compiler will accept, and never refactor. But in thise article, I will show you my setup for the second fastest method: setting up linters and formatters to let my computer worry about it.

Most programming languages today have preset style guides, and default language toolchains usually provide programs that will format your code to these guides. Rust has rustfmt (or cargofmt for your entire project), Golang has gofmt, Dart has dartfmt. Even languages that don’t have formatters in the default toolchain have many 3rd party formatters and linters. My favorite examples are black and flake8 for Python, as well as eslint and prettier for Javascript/Typescript.

All of the above formatters are extremely powerful, while only some are highly configurable (which is perfect if you want to spend less time thinking about formatting!). If you configure formatters and linters to work together for a particular language, the formatters will be able to take care of most of the gripes that the linters present to you about your files.

Why you should use both

As far as I have experienced, formatters are solely used for making your code style uniform. Linters present many more kinds of errors to the developer in addition to style errors. Most linters, for example, consider a declared variable that is unused as an error, but a formatter can’t fix this because it can’t know what you intend to do with your variables.

Linters can run many more static analyses that discover qualitative aspects of your codebase on which you may want detailed information. Code Climate is a popular cloud linter that can assess the quality of a particular codebase, and there are many other awesome-linters, that you can run locally! For these reasons, you will most likely want to use both linters and formatters.

Linting and Formatting in Neovim

My personal choice for linting when it comes to Neovim is the plugin ALE. I tend to keep as few plugins as possible in my nvim configuration, and regardless, I highly recommend using this one. After installation (manual or plugin manager), you can set up a rather quick configuration for ALE with the linters and formatters you want to use. Here is a configuration for my desktop that sets up linters and fixers for the programming languages I work with:

let g:ale_fix_on_save = 1
let g:ale_linters = {'javascript': ['eslint'], 'python': ['flake8']}
let g:ale_fixers = {
\ 'javascript': ['prettier'],
\ 'python': ['black', 'isort'],
\ 'rust': ['rustfmt'],
\ 'go': ['gofmt']
\ }

I add these configurations on my laptop to save battery power by stopping the linters from running continuously in the background:

let g:ale_lint_on_text_changed = 'never'
let g:ale_lint_on_enter = 1

I’m not aware of any linters or formatters for gdscript, but thanks to GDNative and its excellent bindings, I am able to develop games for Godot with these amazing linters and formatters!

For the Beginners

Stepping into Vim and Neovim plugins was just as daunting to me as was learning Vim key bindings in the first place. If this is your first time adding plugins to your configuration, I can’t stress the importance of reading through all the documentation that ALE provides.

You can read through the github page, or run :help ALE while you’re in Vim (aren’t offline docs just the best?)!

ALE has tons of features, and you want to make sure that you configure it to it’s fullest before you set out adding many other plugins on top of it. Even if after reading through all the docs, you are sure that there are no defaults you want to change aside from the linters and fixers you are using, you will still learn a lot about how ALE works. This helped me immensely when I decided to add deoplete for autocompletion, because I knew what configuration I needed for ALE to work nicely with it.

Next: Saving Time With the Unix Philosophy
Previous: 4 Great Qualities of Codewars
>> Home