mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-04 18:58:12 +00:00
feat(snacks): added snacks.picker
(#445)
## Description More info coming tomorrow. In short: - very fast. pretty much realtime filtering/sorting in huge repos (like 1.7 million files) - extensible - easy to customize the layout (and lots of presets) with `snacks.layout` - simple to create custom pickers - `vim.ui.select` - lots of builtin pickers - uses treesitter highlighting wherever it makes sense - fast lua fuzzy matcher which supports the [fzf syntax](https://junegunn.github.io/fzf/search-syntax/) and additionally supports field filters, like `file:lua$ 'function` There's no snacks picker command, just use lua. ```lua -- all pickers Snacks.picker() -- run files picker Snacks.picker.files(opts) Snacks.picker.pick("files", opts) Snacks.picker.pick({source = "files", ...}) ``` <!-- Describe the big picture of your changes to communicate to the maintainers why we should accept this pull request. --> ## Todo - [x] issue with preview loc not always correct when scrolling fast in list (probably due to `snacks.scroll`) - [x] `grep` (`live_grep`) is sometimes too fast in large repos and can impact ui rendering. Not very noticeable, but something I want to look at. - [x] docs - [x] treesitter highlights are broken. Messed something up somewhere ## Related Issue(s) <!-- If this PR fixes any issues, please link to the issue here. - Fixes #<issue_number> --> ## Screenshots <!-- Add screenshots of the changes if applicable. -->
This commit is contained in:
parent
1b7a57a0b1
commit
559d6c6bf2
67 changed files with 12013 additions and 126 deletions
74
lua/snacks/picker/source/qf.lua
Normal file
74
lua/snacks/picker/source/qf.lua
Normal file
|
@ -0,0 +1,74 @@
|
|||
local M = {}
|
||||
|
||||
---Represents an item in a Neovim quickfix/loclist.
|
||||
---@class qf.item
|
||||
---@field bufnr? number The buffer number where the item originates.
|
||||
---@field filename? string
|
||||
---@field lnum number The start line number for the item.
|
||||
---@field end_lnum? number The end line number for the item.
|
||||
---@field pattern string A pattern related to the item. It can be a search pattern or any relevant string.
|
||||
---@field col? number The column number where the item starts.
|
||||
---@field end_col? number The column number where the item ends.
|
||||
---@field module? string Module information (if any) associated with the item.
|
||||
---@field nr? number A unique number or ID for the item.
|
||||
---@field text? string A description or message related to the item.
|
||||
---@field type? string The type of the item. E.g., "W" might stand for "Warning".
|
||||
---@field valid number A flag indicating if the item is valid (1) or not (0).
|
||||
---@field user_data? any Any user data associated with the item.
|
||||
---@field vcol? number Visual column number. Indicates if the column number is a visual column number (when set to 1) or a byte index (when set to 0).
|
||||
|
||||
---@class snacks.picker
|
||||
---@field loclist fun(opts?: snacks.picker.Config): snacks.Picker
|
||||
---@field qflist fun(opts?: snacks.picker.Config): snacks.Picker
|
||||
|
||||
---@class snacks.picker.qf.Config
|
||||
---@field qf_win? number
|
||||
---@field filter? snacks.picker.filter.Config
|
||||
|
||||
local severities = {
|
||||
E = vim.diagnostic.severity.ERROR,
|
||||
W = vim.diagnostic.severity.WARN,
|
||||
I = vim.diagnostic.severity.INFO,
|
||||
H = vim.diagnostic.severity.HINT,
|
||||
N = vim.diagnostic.severity.HINT,
|
||||
}
|
||||
|
||||
---@param opts snacks.picker.qf.Config
|
||||
---@type snacks.picker.finder
|
||||
function M.qf(opts, filter)
|
||||
local win = opts.qf_win
|
||||
win = win == 0 and vim.api.nvim_get_current_win() or win
|
||||
|
||||
local list = win and vim.fn.getloclist(win, { all = true }) or vim.fn.getqflist({ all = true })
|
||||
---@cast list { items?: qf.item[] }?
|
||||
|
||||
local ret = {} ---@type snacks.picker.finder.Item[]
|
||||
|
||||
for _, item in pairs(list and list.items or {}) do
|
||||
local row = item.lnum == 0 and 1 or item.lnum
|
||||
local col = (item.col == 0 and 1 or item.col) - 1
|
||||
local end_row = item.end_lnum == 0 and row or item.end_lnum
|
||||
local end_col = item.end_col == 0 and col or (item.end_col - 1)
|
||||
|
||||
if item.valid == 1 then
|
||||
local file = item.filename or item.bufnr and vim.api.nvim_buf_get_name(item.bufnr) or nil
|
||||
local text = item.text or ""
|
||||
ret[#ret + 1] = {
|
||||
pos = { row, col },
|
||||
end_pos = item.end_lnum ~= 0 and { end_row, end_col } or nil,
|
||||
text = file .. " " .. text,
|
||||
line = item.text,
|
||||
file = file,
|
||||
severity = severities[item.type] or 0,
|
||||
buf = item.bufnr,
|
||||
item = item,
|
||||
}
|
||||
elseif #ret > 0 and ret[#ret].item.text and item.text then
|
||||
ret[#ret].item.text = ret[#ret].item.text .. "\n" .. item.text
|
||||
ret[#ret].item.line = ret[#ret].item.line .. "\n" .. item.text
|
||||
end
|
||||
end
|
||||
return filter:filter(ret)
|
||||
end
|
||||
|
||||
return M
|
Loading…
Add table
Add a link
Reference in a new issue