0
0
Просмотр исходного кода

feat(neovim): add `maj-peg` diagnostic plugin

Joe 9 месяцев назад
Родитель
Сommit
2a30bb974a

+ 33 - 0
.config/nvim/custom/maj-peg/lua/maj-peg/health.lua

@@ -0,0 +1,33 @@
+local maj_peg = require("maj-peg")
+
+return {
+    check = function()
+        vim.health.start("Maj-Peg")
+        if maj_peg.status().setup == false then
+            vim.health.warn("Not loaded")
+            return
+        end
+        if maj_peg.status().has_mypy then
+            vim.health.ok("`mypy` found")
+        else
+            vim.health.warn("`mypy` was not found")
+            if vim.tbl_count(vim.fn.systemlist("echo $VIRTUAL_ENV")) == 0 then
+                vim.health.warn(
+                    "Missing `mypy` likely due to unset $VIRTUAL_ENV in subshell")
+            else
+                vim.health.ok("Check that `mypy` is installed in $VIRTUAL_ENV: " ..
+                    vim.fn.system("echo $VIRTUAL_ENV"))
+            end
+        end
+        if maj_peg.status().has_mypy_baseline then
+            vim.health.ok("`mypy-baseline` found")
+        else
+            vim.health.warn("`mypy-baseline` was not found")
+        end
+        if maj_peg.status().setup then
+            vim.health.ok("Set up")
+        else
+            vim.health.warn("Not set up")
+        end
+    end
+}

+ 104 - 0
.config/nvim/custom/maj-peg/lua/maj-peg/init.lua

@@ -0,0 +1,104 @@
+local Job = require("plenary.job")
+local Path = require("plenary.path")
+local namespace_name = "maj-peg"
+local status = {
+    setup = false,
+    enabled = true,
+    has_mypy = false,
+    has_mypy_baseline = false
+}
+
+local setup = function(mypy_flags, mypybaseline_flags)
+    local namespace = vim.api.nvim_create_namespace(namespace_name)
+    local group = vim.api.nvim_create_augroup(namespace_name, { clear = true })
+    status.has_mypy = vim.fn.system({ "which", "mypy" }) ~= ""
+    status.has_mypy_baseline = vim.fn.system({ "which", "mypy-baseline" }) ~= ""
+    if mypy_flags == nil then
+        mypy_flags = { "--follow-imports", "silent" }
+    end
+    if mypybaseline_flags == nil then
+        mypybaseline_flags = { "filter" }
+    end
+    vim.api.nvim_create_autocmd({ "FileType" },
+        {
+            pattern = "python",
+            group = group,
+            callback = function(outer_args)
+                vim.api.nvim_create_autocmd({ "BufWritePost", "FileType" }, {
+                    buffer = outer_args.buf,
+                    group = group,
+                    callback = function(args)
+                        vim.diagnostic.reset(namespace, args.buf)
+                        if status.enabled == false then return end
+                        local command = "mypy " ..
+                            table.concat(mypy_flags, " ") .. " " ..
+                            vim.api.nvim_buf_get_name(args.buf)
+                        if status.has_mypy_baseline then
+                            command = command ..
+                                " | mypy-baseline " ..
+                                table.concat(mypybaseline_flags, " ")
+                        end
+                        local path = Path:new(vim.api.nvim_buf_get_name(args.buf))
+                            :make_relative()
+                        local diagnostics = {}
+                        Job:new({
+                            command = "zsh",
+                            args = { "-c", command },
+                            on_stdout = function(_, line)
+                                if line == nil or line:sub(1, path:len()) ~= path then
+                                    return
+                                end
+
+                                line = line:sub(path:len() + 1)
+                                local lnum = line:match(':%d+:')
+                                line = line:gsub(':%d: ', '', 1)
+                                if lnum == nil then return end
+                                lnum = lnum:gsub(':', '')
+                                lnum = tonumber(lnum) - 1
+
+                                local severity = vim.diagnostic.severity.INFO
+                                local severity_text = line:match('%a+: ')
+                                if severity_text == nil or severity_text == "hint: " then
+                                    severity = vim.diagnostic.severity.HINT
+                                elseif severity_text == "error: " then
+                                    severity = vim.diagnostic.severity.ERROR
+                                elseif severity_text == "warn: " then
+                                    severity = vim.diagnostic.severity.WARN
+                                elseif severity_text == "info: " then
+                                    severity = vim.diagnostic.severity.INFO
+                                end
+                                line = line:gsub('.+: ', '', 1)
+
+                                table.insert(
+                                    diagnostics,
+                                    {
+                                        lnum = tonumber(lnum),
+                                        col = 0,
+                                        source = namespace_name,
+                                        severity = severity,
+                                        message = line
+                                    })
+                            end,
+                            on_exit = function()
+                                vim.schedule(function()
+                                    vim.diagnostic.set(namespace,
+                                        args.buf, diagnostics)
+                                end)
+                            end,
+                        }):start()
+                    end
+                })
+            end
+        })
+    status.setup = true
+end
+
+return {
+    setup = setup,
+    toggle = function()
+        status.enabled = not status.enabled;
+    end,
+    status = function()
+        return status
+    end
+}

+ 28 - 0
.config/nvim/lua/plugins/diagnostic.lua

@@ -0,0 +1,28 @@
+return {
+    {
+        dir = vim.fn.stdpath("config") .. "/custom/maj-peg",
+        dependencies = { "nvim-lua/plenary.nvim" },
+        name = "maj-peg",
+        lazy = false,
+        enabled = true,
+        config = function()
+            local mp = require("maj-peg")
+            mp.setup()
+            require("command-palette").add({
+                {
+                    "maj-peg", "Diagnostic integration for `mypy`", {
+                    {
+                        "Toggle maj-peg",
+                        function()
+                            if mp.status().enabled then
+                                return "Disable `mypy` integration"
+                            else
+                                return "Enable `mypy` integration"
+                            end
+                        end,
+                        mp.toggle } }
+                }
+            })
+        end
+    }
+}