mfussenegger / nvim-lint

An asynchronous linter plugin for Neovim complementary to the built-in Language Server Protocol support.
GNU General Public License v3.0
1.88k stars 198 forks source link

Question: Weird behavior with stdin=true #501

Open cultab opened 8 months ago

cultab commented 8 months ago

I wanted gitlint to lint without saving the file, so I checked that it supported reading from stdin, and enabled it in the config (plus disabled appending the filename etc.).

It didn't work, I got no diagnostics, so to debug it I replaced gitlint's cmd with a script that simply logs it's stdin to ~/LOG. It was always empty, nothing was appended. It was being run successful as nvim-lint could read it's output (just a simple echo "something") and could read it's exit code (if I added exit 1 to the script it reported that the linter failed to run).

I also tried writing arbitrary messages to it's stdin here:

if linter.stdin then
  stdin:write("some arbitrary debug message here\n") -- <----
  local lines = vim.api.nvim_buf_get_lines(0, 0, -1, true)
  for _, line in ipairs(lines) do
    stdin:write(line .. '\n')
  end
  stdin:write('', function()
    stdin:shutdown(function()
      stdin:close()
    end)
  end)
else
  stdin:close()
end

but still could not see anything.

(also for a sanity check I tried another linter that supports stdin, jq and it worked fine)

I'm kinda stumped on what's going wrong here :|, any ideas?

mfussenegger commented 8 months ago

Just tried it and https://github.com/mfussenegger/nvim-lint/pull/502 works fine for me?

cultab commented 8 months ago

still won't work, will try to make a minimally reproducible example

mfussenegger commented 8 months ago

There's two things that I noticed:

cultab commented 8 months ago

ok I'm beginning to think I'm misunderstanding something crucial.

Why use --msg-filename with stdin = true, isn't it irrelevant since gitlint will read from stdin? Also why use function() <return filename> end instead of append_fname = true, just because or am I missing something?

The file must exist on disk, otherwise there will be an error: Error: Invalid value for '--msg-filename': . Could remove that option, but then --staged has to be removed too.

COMMIT_EDITMSG should always exist in .git when running git commit right?

sidenote: haven't gotten a working MRE yet ;-;

cultab commented 8 months ago

repro.lua:

local root = vim.fn.fnamemodify("~/.repro", ":p")

-- set stdpaths to use .repro
for _, name in ipairs({ "config", "data", "state", "cache" }) do
    vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end

-- bootstrap lazy
local lazypath = root .. "/plugins/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
    vim.fn.system({
        "git",
        "clone",
        "--filter=blob:none",
        "--single-branch",
        "https://github.com/folke/lazy.nvim.git",
        lazypath,
    })
end
vim.opt.runtimepath:prepend(lazypath)

-- install plugins
local plugins = {
    -- do not remove the colorscheme!
    "folke/tokyonight.nvim",
    -- add any other pugins here
    {
        "mfussenegger/nvim-lint",
        version = "*",
        config = function()
            require('lint').linters_by_ft = {
                json = { 'jq' },
                gitcommit = { 'gitlint' },
            }

            vim.api.nvim_create_autocmd({ "BufEnter", "TextChanged", "InsertLeave", "BufWritePost" }, {
                callback = function()
                    vim.notify("Tried to lint: " .. math.random())
                    require("lint").try_lint()
                end,
            })
        end
    }
}
require("lazy").setup(plugins, {
    root = root .. "/plugins",
})

-- add anything else here
vim.opt.termguicolors = true
-- do not remove the colorscheme!
vim.cmd([[colorscheme tokyonight]])

to test set your git $EDITOR to nvim -u repro.lua, and try to run git commit (for a sanity check you can also open up a json file to see that jq works)

nvs commented 8 months ago

I too am noticing that gitlint is not working via nvim-lint's stdin.

When using the following config:

return {
    cmd = 'gitlint',
    stdin = true,
    args = { '--debug' },
    stream = 'stderr',
    ignore_exitcode = true,
    parser = require('lint.parser').from_pattern('(.*)', { 'message' }),
}

I see the following within the returned message:

DEBUG: gitlint.cli No --msg-filename flag, no or empty data passed to stdin. Using the local repo.

Looking at https://github.com/jorisroovers/gitlint/blob/4d9119760056492eabc201bfad5de2f9e660b85f/gitlint-core/gitlint/cli.py#L174 leads me to believe that nvim-lint is not communicating with gitlint through stdin. The details for gitlint's stdin usage is listed in that same file in the function above.

For comparison, efm does seem to work with gitlint via stdin (as configured here: https://github.com/creativenull/efmls-configs-nvim/blob/main/lua/efmls-configs/linters/gitlint.lua).

cultab commented 8 months ago

Interesting.. seems like a good time to mention that tee log was receiving on stdin while a script that did cat /dev/stdin did not. Maybe there's some fuckery with uv.spawn?