summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJieru Mei <[email protected]>2021-12-02 04:31:45 -0500
committerGitHub <[email protected]>2021-12-02 10:31:45 +0100
commitf3cd608d174e6dc2b8cdbdcbad6c7b7eedb6668a (patch)
treee7f8c700577672cc275f286f03648d1993bf62e8
parenta3243b29ef27cb102bbb896358a2f7cde899b579 (diff)
feat: null-ls code_actions interface (#2008)
-rw-r--r--lua/lvim/core/info.lua23
-rw-r--r--lua/lvim/lsp/null-ls/code_actions.lua81
2 files changed, 104 insertions, 0 deletions
diff --git a/lua/lvim/core/info.lua b/lua/lvim/core/info.lua
index 8d33fe5e..df7b7061 100644
--- a/lua/lvim/core/info.lua
+++ b/lua/lvim/core/info.lua
@@ -35,6 +35,23 @@ local function make_formatters_info(ft)
return section
end
+local function make_code_actions_info(ft)
+ local null_actions = require "lvim.lsp.null-ls.code_actions"
+ local registered_actions = null_actions.list_registered_providers(ft)
+ local supported_actions = null_actions.list_available(ft)
+ local section = {
+ "Code actions info",
+ fmt(
+ "* Active: %s%s",
+ table.concat(registered_actions, "  , "),
+ vim.tbl_count(registered_actions) > 0 and "  " or ""
+ ),
+ fmt("* Supported: %s", str_list(supported_actions)),
+ }
+
+ return section
+end
+
local function make_linters_info(ft)
local null_linters = require "lvim.lsp.null-ls.linters"
local supported_linters = null_linters.list_available(ft)
@@ -121,6 +138,8 @@ function M.toggle_popup(ft)
local linters_info = make_linters_info(ft)
+ local code_actions_info = make_code_actions_info(ft)
+
local content_provider = function(popup)
local content = {}
@@ -137,6 +156,8 @@ function M.toggle_popup(ft)
formatters_info,
{ "" },
linters_info,
+ { "" },
+ code_actions_info,
} do
vim.list_extend(content, section)
end
@@ -151,6 +172,7 @@ function M.toggle_popup(ft)
vim.cmd [[let m=matchadd("LvimInfoHeader", "Language Server Protocol (LSP) info")]]
vim.cmd [[let m=matchadd("LvimInfoHeader", "Formatters info")]]
vim.cmd [[let m=matchadd("LvimInfoHeader", "Linters info")]]
+ vim.cmd [[let m=matchadd("LvimInfoHeader", "Code actions info")]]
vim.cmd('let m=matchadd("LvimInfoIdentifier", " ' .. ft .. '$")')
vim.cmd 'let m=matchadd("string", "true")'
vim.cmd 'let m=matchadd("string", "active")'
@@ -160,6 +182,7 @@ function M.toggle_popup(ft)
-- tbl_set_highlight(registered_providers, "LvimInfoIdentifier")
tbl_set_highlight(require("lvim.lsp.null-ls.formatters").list_available(ft), "LvimInfoIdentifier")
tbl_set_highlight(require("lvim.lsp.null-ls.linters").list_available(ft), "LvimInfoIdentifier")
+ tbl_set_highlight(require("lvim.lsp.null-ls.code_actions").list_available(ft), "LvimInfoIdentifier")
end
local Popup = require("lvim.interface.popup"):new {
diff --git a/lua/lvim/lsp/null-ls/code_actions.lua b/lua/lvim/lsp/null-ls/code_actions.lua
new file mode 100644
index 00000000..ff59fabf
--- /dev/null
+++ b/lua/lvim/lsp/null-ls/code_actions.lua
@@ -0,0 +1,81 @@
+local M = {}
+
+local null_ls = require "null-ls"
+local services = require "lvim.lsp.null-ls.services"
+local Log = require "lvim.core.log"
+
+local METHOD = null_ls.methods.CODE_ACTION
+
+local is_registered = function(name)
+ local query = {
+ name = name,
+ method = METHOD,
+ }
+ return require("null-ls.sources").is_registered(query)
+end
+
+function M.list_registered_providers(filetype)
+ local registered_providers = services.list_registered_providers_names(filetype)
+ return registered_providers[METHOD] or {}
+end
+
+function M.list_available(filetype)
+ local availables = require("null-ls.sources").get_available(filetype, METHOD)
+ local actors = vim.tbl_map(function(src)
+ return src.name
+ end, availables)
+ table.sort(actors)
+ return actors
+end
+
+function M.list_configured(actions_configs)
+ local actors, errors = {}, {}
+
+ for _, config in ipairs(actions_configs) do
+ vim.validate {
+ ["config.name"] = { config.name, "string" },
+ }
+
+ local name = config.name:gsub("-", "_")
+ local actor = null_ls.builtins.code_actions[name]
+
+ if not actor then
+ Log:error("Not a valid code_actions: " .. config.name)
+ errors[name] = {} -- Add data here when necessary
+ elseif is_registered(config.name) then
+ Log:trace "Skipping registering the source more than once"
+ else
+ local command
+ if actor._opts.command then
+ command = services.find_command(actor._opts.command)
+ end
+ if not command and actor._opts.command ~= nil then
+ Log:warn("Not found: " .. actor._opts.command)
+ errors[name] = {} -- Add data here when necessary
+ else
+ Log:debug("Using code_actions: " .. (command or config.name))
+ table.insert(
+ actors,
+ actor.with {
+ command = command, -- could be nil
+ extra_args = config.args,
+ filetypes = config.filetypes,
+ }
+ )
+ end
+ end
+ end
+
+ return { supported = actors, unsupported = errors }
+end
+
+function M.setup(actions_configs)
+ if vim.tbl_isempty(actions_configs) then
+ return
+ end
+
+ local actions = M.list_configured(actions_configs)
+ null_ls.register { sources = actions.supported }
+end
+
+return M