فهرست منبع

feat: null-ls code_actions interface (#2008)

Jieru Mei 3 سال پیش
والد
کامیت
f3cd608d17
2فایلهای تغییر یافته به همراه104 افزوده شده و 0 حذف شده
  1. 23 0
      lua/lvim/core/info.lua
  2. 81 0
      lua/lvim/lsp/null-ls/code_actions.lua

+ 23 - 0
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 {

+ 81 - 0
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