This commit is contained in:
parent
791278e498
commit
e879302d00
|
@ -104,10 +104,8 @@ function M.refresh(opts)
|
|||
end
|
||||
|
||||
-- Proxy to last view's action.
|
||||
---@param action trouble.Action|string
|
||||
---@param action trouble.Action.spec
|
||||
function M._action(action)
|
||||
action = type(action) == "string" and Actions[action] or action
|
||||
---@cast action trouble.Action
|
||||
return function(opts)
|
||||
local view = M.open(opts)
|
||||
if view then
|
||||
|
|
|
@ -2,9 +2,10 @@ local Util = require("trouble.util")
|
|||
|
||||
---@alias trouble.Action.ctx {item?: trouble.Item, node?: trouble.Node, opts?: table}
|
||||
---@alias trouble.ActionFn fun(view:trouble.View, ctx:trouble.Action.ctx)
|
||||
---@alias trouble.Action trouble.ActionFn|{action:trouble.ActionFn, desc?:string}
|
||||
---@alias trouble.Action {action: trouble.ActionFn, desc?: string, mode?: string}
|
||||
---@alias trouble.Action.spec string|trouble.ActionFn|trouble.Action|{action: string}
|
||||
|
||||
---@class trouble.actions: {[string]: trouble.Action}
|
||||
---@class trouble.actions: {[string]: trouble.ActionFn}
|
||||
local M = {
|
||||
-- Refresh the trouble source
|
||||
refresh = function(self)
|
||||
|
@ -32,12 +33,25 @@ local M = {
|
|||
self:preview(ctx.item)
|
||||
end
|
||||
end,
|
||||
-- Open the preview
|
||||
delete = function(self)
|
||||
local enabled = self.opts.auto_refresh
|
||||
self:delete()
|
||||
if enabled and not self.opts.auto_refresh then
|
||||
Util.warn("Auto refresh **disabled**", { id = "toggle_refresh" })
|
||||
end
|
||||
end,
|
||||
-- Toggle the preview
|
||||
toggle_preview = function(self)
|
||||
toggle_preview = function(self, ctx)
|
||||
self.opts.auto_preview = not self.opts.auto_preview
|
||||
local enabled = self.opts.auto_preview and "enabled" or "disabled"
|
||||
local notify = (enabled == "enabled") and Util.info or Util.warn
|
||||
notify("Auto preview **" .. enabled .. "**", { id = "toggle_preview" })
|
||||
local Preview = require("trouble.view.preview")
|
||||
if self.opts.auto_preview then
|
||||
self:preview()
|
||||
if ctx.item then
|
||||
self:preview()
|
||||
end
|
||||
else
|
||||
Preview.close()
|
||||
end
|
||||
|
@ -45,6 +59,9 @@ local M = {
|
|||
-- Toggle the auto refresh
|
||||
toggle_refresh = function(self)
|
||||
self.opts.auto_refresh = not self.opts.auto_refresh
|
||||
local enabled = self.opts.auto_refresh and "enabled" or "disabled"
|
||||
local notify = (enabled == "enabled") and Util.info or Util.warn
|
||||
notify("Auto refresh **" .. enabled .. "**", { id = "toggle_refresh" })
|
||||
end,
|
||||
|
||||
filter = function(self, ctx)
|
||||
|
|
|
@ -50,7 +50,7 @@ local defaults = {
|
|||
},
|
||||
-- Key mappings can be set to the name of a builtin action,
|
||||
-- or you can define your own custom action.
|
||||
---@type table<string, string|trouble.Action>
|
||||
---@type table<string, trouble.Action.spec>
|
||||
keys = {
|
||||
["?"] = "help",
|
||||
r = "refresh",
|
||||
|
@ -70,6 +70,8 @@ local defaults = {
|
|||
-- k = "prev",
|
||||
["{"] = "prev",
|
||||
["[["] = "prev",
|
||||
dd = "delete",
|
||||
d = { action = "delete", mode = "v" },
|
||||
i = "inspect",
|
||||
p = "preview",
|
||||
P = "toggle_preview",
|
||||
|
|
|
@ -87,6 +87,22 @@ function M.section(spec)
|
|||
return ret
|
||||
end
|
||||
|
||||
---@param action trouble.Action.spec
|
||||
function M.action(action)
|
||||
if type(action) == "string" then
|
||||
action = { action = action, desc = action:gsub("_", " ") }
|
||||
end
|
||||
if type(action) == "function" then
|
||||
action = { action = action }
|
||||
end
|
||||
if type(action.action) == "string" then
|
||||
action.desc = action.desc or action.action:gsub("_", " ")
|
||||
action.action = require("trouble.config.actions")[action.action]
|
||||
end
|
||||
---@cast action trouble.Action
|
||||
return action
|
||||
end
|
||||
|
||||
---@param mode trouble.Mode
|
||||
---@return trouble.Section.opts[]
|
||||
function M.sections(mode)
|
||||
|
|
|
@ -25,6 +25,26 @@ function M.new(opts)
|
|||
return self
|
||||
end
|
||||
|
||||
function M:delete()
|
||||
local parent = self.parent
|
||||
if not parent then
|
||||
return
|
||||
end
|
||||
if parent.children then
|
||||
parent.children = vim.tbl_filter(function(c)
|
||||
return c ~= self
|
||||
end, parent.children)
|
||||
end
|
||||
if parent.index and self.id then
|
||||
parent.index[self.id] = nil
|
||||
end
|
||||
parent._count = nil
|
||||
parent._degree = nil
|
||||
if parent:count() == 0 then
|
||||
parent:delete()
|
||||
end
|
||||
end
|
||||
|
||||
-- Max depth of the tree
|
||||
function M:degree()
|
||||
if not self._degree then
|
||||
|
@ -60,6 +80,7 @@ function M:count()
|
|||
return self._count
|
||||
end
|
||||
|
||||
--- Gets all the items in the tree, recursively.
|
||||
---@param ret trouble.Item[]?
|
||||
function M:flatten(ret)
|
||||
ret = ret or {}
|
||||
|
|
|
@ -23,7 +23,10 @@ end
|
|||
|
||||
M.islist = vim.islist or vim.tbl_islist
|
||||
|
||||
---@alias NotifyOpts {level?: number, title?: string, once?: boolean}
|
||||
---@alias NotifyOpts {level?: number, title?: string, once?: boolean, id?:string}
|
||||
|
||||
---@type table<string, any>
|
||||
local notif_ids = {}
|
||||
|
||||
---@param msg string|string[]
|
||||
---@param opts? NotifyOpts
|
||||
|
@ -32,7 +35,8 @@ function M.notify(msg, opts)
|
|||
msg = type(msg) == "table" and table.concat(msg, "\n") or msg
|
||||
---@cast msg string
|
||||
msg = vim.trim(msg)
|
||||
return vim[opts.once and "notify_once" or "notify"](msg, opts.level, {
|
||||
local ret = vim[opts.once and "notify_once" or "notify"](msg, opts.level, {
|
||||
replace = opts.id and notif_ids[opts.id] or nil,
|
||||
title = opts.title or "Trouble",
|
||||
on_open = function(win)
|
||||
vim.wo.conceallevel = 3
|
||||
|
@ -41,6 +45,10 @@ function M.notify(msg, opts)
|
|||
vim.treesitter.start(vim.api.nvim_win_get_buf(win), "markdown")
|
||||
end,
|
||||
})
|
||||
if opts.id then
|
||||
notif_ids[opts.id] = ret
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
---@param msg string|string[]
|
||||
|
@ -49,6 +57,12 @@ function M.warn(msg, opts)
|
|||
M.notify(msg, vim.tbl_extend("keep", { level = vim.log.levels.WARN }, opts or {}))
|
||||
end
|
||||
|
||||
---@param msg string|string[]
|
||||
---@param opts? NotifyOpts
|
||||
function M.info(msg, opts)
|
||||
M.notify(msg, vim.tbl_extend("keep", { level = vim.log.levels.INFO }, opts or {}))
|
||||
end
|
||||
|
||||
---@param msg string|string[]
|
||||
---@param opts? NotifyOpts
|
||||
function M.error(msg, opts)
|
||||
|
|
|
@ -199,6 +199,19 @@ function M:on_mount()
|
|||
end, { remap = false, expr = true })
|
||||
end
|
||||
|
||||
---@param node? trouble.Node
|
||||
function M:delete(node)
|
||||
local selection = node and { node } or self:selection()
|
||||
if #selection == 0 then
|
||||
return
|
||||
end
|
||||
for _, n in ipairs(selection) do
|
||||
n:delete()
|
||||
end
|
||||
self.opts.auto_refresh = false
|
||||
self:render()
|
||||
end
|
||||
|
||||
---@param node? trouble.Node
|
||||
---@param opts? trouble.Render.fold_opts
|
||||
function M:fold(node, opts)
|
||||
|
@ -311,29 +324,37 @@ function M:at(cursor)
|
|||
return self.renderer:at(cursor[1])
|
||||
end
|
||||
|
||||
function M:selection()
|
||||
if not vim.fn.mode():lower():find("v") then
|
||||
local ret = self:at()
|
||||
return ret.node and { ret.node } or {}
|
||||
end
|
||||
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("<esc>", true, false, true), "x", false)
|
||||
|
||||
local from = vim.api.nvim_buf_get_mark(self.win.buf, "<")[1]
|
||||
local to = vim.api.nvim_buf_get_mark(self.win.buf, ">")[1]
|
||||
---@type trouble.Node[]
|
||||
local ret = {}
|
||||
for row = from, to do
|
||||
local node = self.renderer:at(row).node
|
||||
if not vim.tbl_contains(ret, node) then
|
||||
ret[#ret + 1] = node
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
---@param key string
|
||||
---@param action trouble.Action|string
|
||||
---@param action trouble.Action.spec
|
||||
function M:map(key, action)
|
||||
local desc ---@type string?
|
||||
if type(action) == "string" then
|
||||
desc = action:gsub("_", " ")
|
||||
action = require("trouble.config.actions")[action]
|
||||
end
|
||||
---@type trouble.ActionFn
|
||||
local fn
|
||||
if type(action) == "function" then
|
||||
fn = action
|
||||
else
|
||||
fn = action.action
|
||||
desc = action.desc or desc
|
||||
end
|
||||
action = Spec.action(action)
|
||||
local _self = Util.weak(self)
|
||||
self.win:map(key, function()
|
||||
local this = _self()
|
||||
if this then
|
||||
this:action(fn)
|
||||
this:action(action)
|
||||
end
|
||||
end, desc)
|
||||
end, { desc = action.desc, mode = action.mode })
|
||||
end
|
||||
|
||||
---@param opts? {idx?: number, up?:number, down?:number, jump?:boolean}
|
||||
|
@ -374,12 +395,13 @@ function M:move(opts)
|
|||
end
|
||||
end
|
||||
|
||||
---@param action trouble.Action
|
||||
---@param action trouble.Action.spec
|
||||
---@param opts? table
|
||||
function M:action(action, opts)
|
||||
action = Spec.action(action)
|
||||
self:wait(function()
|
||||
local at = self:at() or {}
|
||||
action(self, {
|
||||
action.action(self, {
|
||||
item = at.item,
|
||||
node = at.node,
|
||||
opts = type(opts) == "table" and opts or {},
|
||||
|
|
|
@ -363,19 +363,23 @@ end
|
|||
|
||||
---@param key string
|
||||
---@param fn fun(self: trouble.Window):any
|
||||
---@param opts? string|vim.keymap.set.Opts
|
||||
---@param opts? string|vim.keymap.set.Opts|{mode?:string}
|
||||
function M:map(key, fn, opts)
|
||||
opts = vim.tbl_deep_extend("force", {
|
||||
buffer = self.buf,
|
||||
nowait = true,
|
||||
mode = "n",
|
||||
}, type(opts) == "string" and { desc = opts } or opts or {})
|
||||
local mode = opts.mode
|
||||
opts.mode = nil
|
||||
---@cast opts vim.keymap.set.Opts
|
||||
if not self:valid() then
|
||||
error("Cannot create a keymap for an invalid window")
|
||||
end
|
||||
|
||||
self.keys[key] = opts.desc or key
|
||||
local weak_self = Util.weak(self)
|
||||
vim.keymap.set("n", key, function()
|
||||
vim.keymap.set(mode, key, function()
|
||||
if weak_self() then
|
||||
return fn(weak_self())
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue