Skip to content

Commit

Permalink
feat: added severity filter keymap and improved filtering actions
Browse files Browse the repository at this point in the history
  • Loading branch information
folke committed May 31, 2024
1 parent a6f1af5 commit 7842dbb
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 11 deletions.
15 changes: 13 additions & 2 deletions lua/trouble/config/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,22 @@ local defaults = {
zi = "fold_toggle_enable",
gb = { -- example of a custom action that toggles the active view filter
action = function(view)
view.state.filter_buffer = not view.state.filter_buffer
view:filter(view.state.filter_buffer and { buf = 0 } or nil)
view:filter({ buf = 0 }, { toggle = true })
end,
desc = "Toggle Current Buffer Filter",
},
s = { -- example of a custom action that toggles the severity
action = function(view)
local f = view:get_filter("severity")
local severity = ((f and f.filter.severity or 0) + 1) % 5
view:filter({ severity = severity }, {
id = "severity",
template = "{hl:Title}Filter:{hl} {severity}",
del = severity == 0,
})
end,
desc = "Toggle Severity Filter",
},
},
---@type table<string, trouble.Mode>
modes = {
Expand Down
24 changes: 24 additions & 0 deletions lua/trouble/filter.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
local Util = require("trouble.util")

local M = {}

---@class trouble.ViewFilter.opts
---@field id? string
---@field template? string
---@field data? table<string, any>
---@field toggle? boolean
---@field del? boolean

---@class trouble.ViewFilter
---@field id string
---@field filter trouble.Filter
---@field template? string
---@field data? table<string, any>

---@param opts? {lines:boolean}
---@param range trouble.Range
---@param pos trouble.Pos
Expand Down Expand Up @@ -62,6 +77,15 @@ M.filters = {
---@param filter trouble.Filter
---@param ctx trouble.Filter.ctx
function M.is(item, filter, ctx)
if type(filter) == "table" and Util.islist(filter) then
for _, f in ipairs(filter) do
if not M.is(item, f, ctx) then
return false
end
end
return true
end

filter = type(filter) == "table" and filter or { filter }
for k, v in pairs(filter) do
---@type trouble.FilterFn?
Expand Down
9 changes: 9 additions & 0 deletions lua/trouble/format.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ local M = {}
---@param source string
---@param field string
function M.default_hl(source, field)
if not source then
return "Trouble" .. Util.camel(field)
end
local key = source .. field
local value = Cache.default_hl[key]
if value then
Expand Down Expand Up @@ -104,6 +107,12 @@ M.formatters = {
text = vim.fn.fnamemodify(ctx.item.dirname, ":p:~:."),
}
end,
filter = function(ctx)
return {
text = vim.inspect(ctx.item.filter):gsub("%s+", " "),
hl = "ts.lua",
}
end,
kind_icon = function(ctx)
if not ctx.item.kind then
return
Expand Down
9 changes: 8 additions & 1 deletion lua/trouble/sources/lsp.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ local Filter = require("trouble.filter")
local Item = require("trouble.item")
local Util = require("trouble.util")

local get_line_col = vim.lsp.util._str_byteindex_enc
---@param line string line to be indexed
---@param index integer UTF index
---@param encoding string utf-8|utf-16|utf-32| defaults to utf-16
---@return integer byte (utf-8) index of `encoding` index `index` in `line`
local function get_line_col(line, index, encoding)
local ok, ret = pcall(vim.lsp.util._str_byteindex_enc, line, index, encoding)
return ok and ret or #line
end

---@class trouble.Source.lsp: trouble.Source
---@diagnostic disable-next-line: missing-fields
Expand Down
76 changes: 68 additions & 8 deletions lua/trouble/view/init.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
local Format = require("trouble.format")
local Main = require("trouble.view.main")
local Preview = require("trouble.view.preview")
local Render = require("trouble.view.render")
Expand All @@ -17,6 +18,7 @@ local Window = require("trouble.view.window")
---@field moving uv_timer_t
---@field opening? boolean
---@field state table<string,any>
---@field _filters table<string, trouble.ViewFilter>
---@field _waiting (fun())[]
---@field private _main? trouble.Main
local M = {}
Expand All @@ -38,6 +40,7 @@ function M.new(opts)
self.state = {}
self.opts = opts or {}
self._waiting = {}
self._filters = {}
self.first_render = true
self.opts.win = self.opts.win or {}
self.opts.win.on_mount = function()
Expand Down Expand Up @@ -108,14 +111,6 @@ function M.get(filter)
return ret
end

---@param filter trouble.Filter
function M:filter(filter)
for _, section in ipairs(self.sections) do
section.filter = filter
end
self:refresh()
end

function M:on_mount()
vim.w[self.win.win].trouble = {
mode = self.opts.mode,
Expand Down Expand Up @@ -518,6 +513,62 @@ function M:update()
end
end

---@param filter trouble.Filter
---@param opts? trouble.ViewFilter.opts
function M:filter(filter, opts)
opts = opts or {}

---@type trouble.ViewFilter
local view_filter = vim.tbl_deep_extend("force", {
id = vim.inspect(filter),
filter = filter,
data = opts.data,
template = opts.template,
}, opts)

if opts.del or (opts.toggle and self._filters[view_filter.id]) then
self._filters[view_filter.id] = nil
else
self._filters[view_filter.id] = view_filter
end

local filters = vim.tbl_count(self._filters) > 0
and vim.tbl_map(function(f)
return f.filter
end, vim.tbl_values(self._filters))
or nil

for _, section in ipairs(self.sections) do
section.filter = filters
end
self:refresh()
end

function M:header()
local ret = {} ---@type trouble.Format[][]
for _, filter in pairs(self._filters) do
local data = vim.tbl_deep_extend("force", {
filter = filter.filter,
}, type(filter.filter) == "table" and filter.filter or {}, filter.data or {})
local template = filter.template or "{hl:Title}Filter:{hl} {filter}"
ret[#ret + 1] = self:format(template, data)
end
return ret
end

---@param id string
function M:get_filter(id)
return self._filters[id]
end

---@param template string
---@param data table<string,any>
function M:format(template, data)
data.source = "view"
assert(self.opts, "opts is nil")
return Format.format(template, { item = data, opts = self.opts })
end

-- render the results
function M:render()
if not self.win:valid() then
Expand All @@ -537,6 +588,15 @@ function M:render()
for _ = 1, vim.tbl_get(self.opts.win, "padding", "top") or 0 do
self.renderer:nl()
end

local header = self:header()
for _, h in ipairs(header) do
for _, ff in ipairs(h) do
self.renderer:append(ff.text, ff)
end
self.renderer:nl()
end

self.renderer:sections(self.sections)
self.renderer:trim()

Expand Down

0 comments on commit 7842dbb

Please sign in to comment.