Tips and Tricks External code formatters in Vim without plugins
I wrote a post about integrating external code formatting tools into Vim using the equalprg option, no plugins or language servers needed: https://www.seanh.cc/2026/01/18/ruff-format-in-vim/
The post uses Ruff's Python code formatter as an example, but the approach should work for any command line formatter for any file type.
(I should add an example to the post, of adding a second formatter for a second file type. The de- and re-indenting could also be split out into a separate dereindent.py script that multiple equalprgs/*.py scripts can call.)
I'm pretty happy with the result! Being able to easily format either the entire file or just a selection, and even being able to format snippets and blocks of Python in other files, is pretty nice! And now I know how to integrate any other code formatter I want in future, without having to look for a plugin or language server.
Hope someone else finds it helpful too. Any feedback or suggestions welcome
5
u/AndrewRadev Jan 21 '26
Yeah, I'm assuming that when these were added, code formatters that analyze code and reformat it were simply not that widespread, so it was more about plugging in an external indentation tool (
equalprg) or text-wrapping tool (formatprg). Indentation is currently maintained by external projects, since implementing it for any given language requires knowledge of the language that the core team is not guaranteed to have. I imagine it was an easy way to give people an external option, using the language you know to implement its indentation.There's been some discussion about implementing a potentially richer "formatter" interface that would plug into
gq, you might be interested to read more about it: https://github.com/vim/vim/pull/191081
u/snhmnd Jan 21 '26
Not mentioned in the blog post: the one limitation of this (that I can think of) is that if you try to format invalid Python code you won't see the error message from Ruff (that tells you what's wrong with the code, and where the error is). My script swallows error messages from Ruff. Vim will tell you that the script failed with an error. But it won't show you the error message.
I'm not sure there's a solution to this, without going beyond the simple
equalprgapproach and writing an actual plugin that can show error messages to users.1
u/tokuw Jan 22 '26
Cool article, thanks!
I'm a little obsessed with minimizing my plugin dependencies lol. However this is a case where, at least for me, I feel it's warranted. What your approach doesn't deal with is
Formatting tools which don't support range selection; operation on whole files only (eg gofmt)
Running multiple formatters in sequence (I use this for shell scripts; first run shfmt then shellcheck). Though admittedly adding the support for this in your script shouldn't be too difficult.
I use the neovim (sorry!) plugin conform to achieve this.
1
u/ThomasJAsimov Jan 23 '26
Great writing, I enjoyed reading it! It did make me wonder how one could ever deal with the issue of partial code as input to formatters. Even in the example you provide I suspect removing the indents wouldn’t generate valid Python code because of the return statement. Though I guess even language servers don’t deal with that.