1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-24 05:40:05 +08:00
SpaceVim/bundle/trouble.nvim/lua/trouble/init.lua
2023-07-01 20:30:44 +08:00

303 lines
6.9 KiB
Lua
Vendored

local View = require("trouble.view")
local config = require("trouble.config")
local colors = require("trouble.colors")
local util = require("trouble.util")
colors.setup()
local Trouble = {}
local view
function Trouble.is_open()
return view and view:is_valid() or false
end
function Trouble.setup(options)
if vim.fn.has("nvim-0.7.2") == 0 then
util.error("Trouble needs Neovim >= 0.7.2")
return
end
config.setup(options)
util.fix_mode(config.options)
colors.setup()
end
function Trouble.close()
if Trouble.is_open() then
view:close()
end
end
local function get_opts(...)
local args = { ... }
if vim.tbl_islist(args) and #args == 1 and type(args[1]) == "table" then
args = args[1]
end
local opts = {}
for key, value in pairs(args) do
if type(key) == "number" then
local k, v = value:match("^(.*)=(.*)$")
if k then
opts[k] = v
elseif opts.mode then
util.error("unknown option " .. value)
else
opts.mode = value
end
else
opts[key] = value
end
end
opts = opts or {}
util.fix_mode(opts)
config.options.cmd_options = opts
return opts
end
function Trouble.open(...)
local opts = get_opts(...)
if opts.mode and (opts.mode ~= config.options.mode) then
config.options.mode = opts.mode
end
if opts.severity and (opts.severity ~=config.options.severity) then
config.options.severity = opts.severity
end
opts.focus = true
opts.on_open = true
if Trouble.is_open() then
Trouble.refresh(opts)
elseif not opts.auto and vim.tbl_contains(config.options.auto_jump, opts.mode) then
require("trouble.providers").get(vim.api.nvim_get_current_win(), vim.api.nvim_get_current_buf(), function(results)
if #results == 1 then
util.jump_to_item(opts.win, opts.precmd, results[1])
elseif #results > 0 then
view = View.create(opts)
end
end, config.options)
else
view = View.create(opts)
end
end
function Trouble.toggle(...)
local opts = get_opts(...)
if opts.mode and (opts.mode ~= config.options.mode) then
config.options.mode = opts.mode
Trouble.open(...)
return
end
if Trouble.is_open() then
Trouble.close()
else
Trouble.open(...)
end
end
function Trouble.help()
local lines = { "# Key Bindings" }
local height = 1
for command, key in pairs(config.options.action_keys) do
if type(key) == "table" then
key = table.concat(key, " | ")
end
table.insert(lines, " * **" .. key .. "** " .. command:gsub("_", " "))
height = height + 1
end
-- help
vim.lsp.util.open_floating_preview(lines, "markdown", {
border = "single",
height = 20,
offset_y = -2,
offset_x = 2,
})
end
local updater = util.debounce(100, function()
-- buff might have been closed during the debounce
if not Trouble.is_open() then
util.debug("refresh: not open anymore")
return
end
util.debug("refresh: auto")
view:update({ auto = true })
end)
function Trouble.refresh(opts)
opts = opts or {}
-- dont do an update if this is an automated refresh from a different provider
if opts.auto then
if opts.provider == "diagnostics" and config.options.mode == "document_diagnostics" then
opts.provider = "document_diagnostics"
elseif opts.provider == "diagnostics" and config.options.mode == "workspace_diagnostics" then
opts.provider = "workspace_diagnostics"
elseif opts.provider == "qf" and config.options.mode == "quickfix" then
opts.provider = "quickfix"
elseif opts.provider == "qf" and config.options.mode == "loclist" then
opts.provider = "loclist"
end
if opts.provider ~= config.options.mode then
return
end
end
if Trouble.is_open() then
if opts.auto then
updater()
else
util.debug("refresh")
view:update(opts)
end
elseif opts.auto and config.options.auto_open and opts.provider == config.options.mode then
require("trouble.providers").get(vim.api.nvim_get_current_win(), vim.api.nvim_get_current_buf(), function(results)
if #results > 0 then
Trouble.open(opts)
end
end, config.options)
end
end
function Trouble.action(action)
if action == "toggle_mode" then
if config.options.mode == "document_diagnostics" then
config.options.mode = "workspace_diagnostics"
elseif config.options.mode == "workspace_diagnostics" then
config.options.mode = "document_diagnostics"
end
action = "refresh"
end
if action == 'switch_severity' then
if config.options.severity == nil then
config.options.severity = vim.diagnostic.severity.ERROR
elseif config.options.severity < 4 then
config.options.severity = config.options.severity + 1
else
config.options.severity = nil
end
action = "refresh"
end
if view and action == "on_win_enter" then
view:on_win_enter()
end
if not Trouble.is_open() then
return Trouble
end
if action == "hover" then
view:hover()
end
if action == "jump" then
view:jump()
elseif action == "open_split" then
view:jump({ precmd = "split" })
elseif action == "open_vsplit" then
view:jump({ precmd = "vsplit" })
elseif action == "open_tab" then
view:jump({ precmd = "tabe" })
end
if action == "jump_close" then
view:jump()
Trouble.close()
end
if action == "open_folds" then
Trouble.refresh({ open_folds = true })
end
if action == "close_folds" then
Trouble.refresh({ close_folds = true })
end
if action == "toggle_fold" then
view:toggle_fold()
end
if action == "on_enter" then
view:on_enter()
end
if action == "on_leave" then
view:on_leave()
end
if action == "cancel" then
view:switch_to_parent()
end
if action == "next" then
view:next_item()
return Trouble
end
if action == "previous" then
view:previous_item()
return Trouble
end
if action == "first" then
view:first_item()
return Trouble
end
if action == "last" then
view:last_item()
return Trouble
end
if action == "toggle_preview" then
config.options.auto_preview = not config.options.auto_preview
if not config.options.auto_preview then
view:close_preview()
else
action = "preview"
end
end
if action == "auto_preview" and config.options.auto_preview then
action = "preview"
end
if action == "preview" then
view:preview()
end
if Trouble[action] then
Trouble[action]()
end
return Trouble
end
function Trouble.next(opts)
util.fix_mode(opts)
if view then
view:next_item(opts)
end
end
function Trouble.previous(opts)
util.fix_mode(opts)
if view then
view:previous_item(opts)
end
end
function Trouble.first(opts)
util.fix_mode(opts)
if view then
view:first_item(opts)
end
end
function Trouble.last(opts)
util.fix_mode(opts)
if view then
view:last_item(opts)
end
end
function Trouble.get_items()
if view ~= nil then
return view.items
else
return {}
end
end
return Trouble