nvim-lint
nvim-lint copied to clipboard
Linting of injected langauges
I've been thinking for a while on how to implement "linting of injected languages" using the existing code-base as-is, and (in theory anyway) it's not too difficult, I would just like to bring it up for a discussing before actually trying to implement it
conform.nvim has the same feature, but for formatting, and we can just re-use the core logic here (getting the injected languages via treesitter). I see it sort of like this:
- Get the injected languages, and for each:
- Create a new hidden-scratch buffer, set
ft
toinjected.language
- Set said scratch-buffer's content to
injected.content
(without additional new lines, see below) - Call
nvim_buf_call(scatch_bufnr, M.lint())
on the scratch-buffer - Get all the diagnostics for
scratch_bufnr
(if LSP's are setup for the target language, these will also be picked up - feature?) - Update the diagnostic' line_num to include the offset from the main buffer for each diagnostic (see below)
-
vim.diagnostics.set()
the diagnostics in the main buffer - Sync/delete hidden buffers - I need to test what is fastest here
I know of otter.nvim which does something similar, but for a limited set of languages, and only includes LSP features (which I'm not interested in). Otter.nvim creates a hidden buffer, but using newlines as offset, which I personally do not like, because some linters requires the first line to be a shebang (see shellcheck as an example), which is impossible to satisfy using the newline-approach
Instead, I'd suggest making a new buffer without newlines, but instead bump the lnum of the diagnostic itself afterwards, so it matches in the main buffer (i.e. if the injected block starts a line 5 in the main buffer, bump the lnum of the diagnostic by 4 (offset - 1). This makes the shellcheck example possible to "fix"
Since nvim-lint's cmd
-field can only return a path to an external command (or a function that returns said command), above requires a new field, which can take a pure-lua function
conform.nvim
has command
-field which is equivalent to nvim-lint's cmd
field, but they also have a format
-field, which accepts said pure-lua function (they also have a condition
-field, which I think could also be useful here)
(having a linter
field (pure-lua) would also allow new linter tools, for-example these two from null-ls, and this one I wrote, just before switching to nvim-lint/conform.nvim)
This bit is what is holding me back from writing the injected-linter; I'm not too comfortable adding logic to the core-logic :-)
Relates a bit to https://github.com/mfussenegger/nvim-lint/issues/235
I'd first like to see if there's more interest in this, before considering it.
It does appear there's a desire for this feature to be implemented. It currently has the highest number of votes.
This would be awesome for languages like Nix where I often end up injecting Lua or shell scripts with unchecked '' ''; blocks.