The Crazy Ball of Wax that is NeoVim Plugins from Github Co-pilot to Lint
Well, I've been using vim for a long time and it has taken forever to get something that is stable and really fast. I know most folks should probably move to VSCodium (the non tracker version of VSCode), but if you are really married to two things:
- Incredible speed and there is nothing like a character-oriented keystroke editor
- The vi finger tip memory of a zillion keystrokes like
bnfor buffer next or
gtto move to the next tab
Using NeoVim with Github Copilot and ALE
Neovim. This is a rewrite of vim which is itself a rewrite of vi. Wow, 45 years of computing history in one piece of software. The main reason to use this vs vim 8.0 is that GitHub Copilot only supports this thing and it is faster at background threading than vim. The big things are that Neovim has LSP built-in for instance, so when using thing this, I actually changed the infrastructure see below.
- Github Copilot. This is the main reason that I switched to Neovim, it is really remarkable how good this completion is and if you can get into the beta, then this is the first choice. It works for any document, so it will complete markdown, .vimrc files, python and just about everything else. The idea that in the end there will be a few BigTech companies with supermodels because they have all the data seems more real all the time when you use this. This thing was developed by OpenAI using the source in GitHub. It works super well and you can access it with
- ALE. OK, with Github Copilot doing all the command completion, the only thing I really need now is linting and fixer support. This basically means installing programs inside of your shell environment and then ALE calls them. So if you want Shellcheck, then do a
brew install shellcheckand then ALE should automatically detect it. Note that since ALE runs in parallel by default it runs all the lints for a particular file type it can find. If you don't want this, then you have to edit the ale_linter list in .vimrc to just get the ones that you want. If you want to see what it tries to do then a quick
:ALEInfowill tell you what it can load and fixers it can handle. The idea of a fixer is that if you want to pretty format your code, then it will run automatically. For instance
shfmtis quite good for shell scripts. If you want to see the errors, they appear on the left and then a quick
:llgets you to the first error (l is the line error buffer), then
:lnegoes to the next and
:lpgets you to the previous. This also supports cool features like function rename but I haven't been able to get working.
- Location List. One of the main things to understand about things like ALE and other lint checkers is that it uses a facility called the location list. There is a location list per buffer (that is open file) and you get a whole bunch of commands in addition to the ones above. So if you want to see the list, if you do a Ctrl-W S (for window split), then you will see that list and you can move back and forth. A quickfix list is the global version of this. If you are using the global list then the equivalent
- Coc. Note that I don't use CoC since Copilot is so much better but it is a good second choice, what it does is to use node and then links to Language Server Protocol (lsp) that are available so you get autocomplete that comes with VSCode. I've tried CoC for command completions, which uses the VSCode stuff, but it was definitely way slower and that's the main purpose of Github Copilot. Syntastic is nice, but ALE works really well for Neovim.
If you don't have Copilot, use Vim and Syntastic
The whole point of vim is being super-fast, it's really the fastest editor available. So if you don't have Copilot, then I would probably just use the tried and true vim (currently 8.0). This does mean your tooling is a little different
- Syntastic. Right now I use Syntastic because it is in process and good with vim, but for Neovim. Syntastic is a little complicated in that it needs other plugins to actually provide the linting and command completion. Unlike ALE, this throws up the entire line buffer and with a
^-W ^-Wyou can switch to it and when you go each, it scrolls the other window so it basically runs a ^W-s or split automatically. You can also use the same
:llcommands as ALE though
- Mu-complete. This is a completion manager that plugs into Syntastic and manages all the completions. It basically tries a chain of completions. I also didn't end up using You Complete Me, but I can't remember why. But you have to know things like jedi-vim provides python completions for instance, so it's really a meta layer
- I don't use ALE or CoC because async support in vim is just well not that fast, it just feels slower when running async processes. the way to go.
And yes I did spend an entire day untangle my .vimrc to do this. The main thing was just having a single .vimrc with
has(nvim) conditions so I just swap between these two toolings and the rest is common. It does make .vimrc first time runs a little slow, but you hardly notice on modern machines.