Add "nix flake fmt" builtin formatter
This implements a builtin formatter that (essentially) invokes nix fmt on the given buffer. I called it "nix flake fmt", even though the underlying command is nix fmt, because I didn't want people to confuse it with none-ls's pre-existing nixfmt builtin formatter. Naming is hard.
This was pretty tricky to build. Issues I ran into:
-
nix fmtis slow enough that it's unbearable to run every time you save a buffer. The slowness is the time spent evaluating all the relevant nix code each time, so I opted to cache the result.- I wanted to cache this per project rather than per buffer, so I added a new
by_bufrootcache helper (inspired by the existingby_bufnrcache helper). That's the first commit in this PR, and could be merged up independently, but it might be silly to do so without any builtins using it. - The underlying
nix eval,nix build, etc implementation makes me cry :sob:. I'm hoping a Nix expert swoops in and shows me a better way. Or, perhaps we can use this as motivation to add a feature to thenixcli to make this easier. I have a few ideas about things that could make this simpler.
- I wanted to cache this per project rather than per buffer, so I added a new
- The current implementation assumes that the
nix fmtentrypoint takes a--walk=filesystemparameter. That's a bogus assumption. I've left a comment in the code explaining how I think we should fix this (it'll require a change totreefmtitself). I'd like to address this before we merge this PR up, so I've marked this as a draft.
I actually just learned that neovim seems to have a tempdir with automatic cleanup already builtin. So all you have to do is doing this once and save it in temporary variable:
tmp_dir = vim.fn.tempname()
And pass this as an argument for the gcroot. When vim terminates this directory is removed again.
This logic seems much easier than having to check store paths with nix-store and is also more sound.
I've rebased this on top of https://github.com/nvimtools/none-ls.nvim/pull/197 now that it's merged. Also, treefmt v2.1.0 (with https://github.com/numtide/treefmt/commit/659aa0fdc20d2deaeaf76d325449ce86d2869036) has been released for a while, so I feel comfortable removing the --walk=filesystem option.
If someone with a different setup could test this I'd be glad to merge, since I have zero Nix experience.
cc @Lassulus for testing ^
This seems to work for me.
Should this be in none-ls vs none-ls-extras? Are there any guidelines as to which sources go to which? I find it interesting that "eslint", for example, is in extras, and "nix fmt" would be in main.
eslint is in extras since a better alternative is available (eslint-lsp).
eslint is in extras since a better alternative is available (eslint-lsp).
of course. ty!
Thanks for the merge, @mochaaP!