Skip to content

Commit 1e1c912

Browse files
committed
refactor(pickers): improve snacks picker implementation and callback handling
feat: add table utility functions for debugging fix: update grep and find_files to properly handle callbacks refactor: streamline picker options and configuration style: improve code organization and consistency Breaking changes: - Modified behavior of grep and find_files to prioritize callbacks
1 parent d6490d5 commit 1e1c912

File tree

1 file changed

+130
-63
lines changed

1 file changed

+130
-63
lines changed

lua/obsidian/pickers/_snacks.lua

Lines changed: 130 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,45 @@ local Path = require "obsidian.path"
66
local abc = require "obsidian.abc"
77
local Picker = require "obsidian.pickers.picker"
88

9+
10+
function print_table(t, indent)
11+
indent = indent or 0
12+
local padding = string.rep(" ", indent)
13+
14+
for key, value in pairs(t) do
15+
if type(value) == "table" then
16+
print(padding .. tostring(key) .. " = {")
17+
print_table(value, indent + 1)
18+
print(padding .. "}")
19+
else
20+
print(padding .. tostring(key) .. " = " .. tostring(value))
21+
end
22+
end
23+
end
24+
25+
function table_to_string(t, indent)
26+
if type(t) ~= "table" then return tostring(t) end
27+
28+
indent = indent or 0
29+
local padding = string.rep(" ", indent)
30+
local parts = {}
31+
32+
for k, v in pairs(t) do
33+
local key = type(k) == "number" and "[" .. k .. "]" or k
34+
local value
35+
if type(v) == "table" then
36+
value = "{\n" .. table_to_string(v, indent + 1) .. padding .. "}"
37+
elseif type(v) == "string" then
38+
value = string.format("%q", v)
39+
else
40+
value = tostring(v)
41+
end
42+
parts[#parts + 1] = padding .. key .. " = " .. value
43+
end
44+
45+
return table.concat(parts, ",\n") .. "\n"
46+
end
47+
948
---@param entry string
1049
---@return string
1150
local function clean_path(entry)
@@ -17,6 +56,24 @@ local function clean_path(entry)
1756
return ""
1857
end
1958

59+
local function map_actions(action)
60+
if type(action) == "table" then
61+
opts = { win = { input = { keys = {} } }, actions = {} };
62+
for k, v in pairs(action) do
63+
local name = string.gsub(v.desc, " ", "_")
64+
opts.win.input.keys = {
65+
[k] = { name, mode = { "n", "i" }, desc = v.desc }
66+
}
67+
opts.actions[name] = function(picker, item)
68+
vim.notify("action item: " .. table_to_string(item))
69+
v.callback({args: item.text})
70+
end
71+
end
72+
return opts
73+
end
74+
return {}
75+
end
76+
2077
---@class obsidian.pickers.SnacksPicker : obsidian.Picker
2178
local SnacksPicker = abc.new_class({
2279
---@diagnostic disable-next-line: unused-local
@@ -26,93 +83,103 @@ local SnacksPicker = abc.new_class({
2683
}, Picker)
2784

2885
SnacksPicker.find_files = function(self, opts)
29-
opts = opts and opts or {}
86+
opts = opts or {}
3087

3188
---@type obsidian.Path
3289
local dir = opts.dir and Path:new(opts.dir) or self.client.dir
3390

34-
local result = snacks_picker.pick("files", {
35-
cwd = tostring(dir),
91+
local pick_opts = vim.tbl_extend("force", map or {}, {
92+
source = "files",
93+
title = opts.prompt_title,
94+
cwd = opts.dir.filename,
95+
confirm = function(picker, item, action)
96+
picker:close()
97+
if item then
98+
if opts.callback then
99+
opts.callback(item._path)
100+
else
101+
snacks_picker.actions.jump(picker, item, action)
102+
end
103+
end
104+
end,
36105
})
37-
38-
if result and opts.callback then
39-
local path = clean_path(result)
40-
opts.callback(tostring(dir / path))
41-
end
106+
snacks_picker.pick(pick_opts)
42107
end
43108

44-
SnacksPicker.grep = function(self, opts)
45-
opts = opts and opts or {}
109+
SnacksPicker.grep = function(self, opts, action)
110+
opts = opts or {}
46111

47112
---@type obsidian.Path
48113
local dir = opts.dir and Path:new(opts.dir) or self.client.dir
49114

50-
local result = snacks_picker.pick("grep", {
51-
cwd = tostring(dir),
115+
local pick_opts = vim.tbl_extend("force", map or {}, {
116+
source = "grep",
117+
title = opts.prompt_title,
118+
cwd = opts.dir.filename,
119+
confirm = function(picker, item, action)
120+
picker:close()
121+
if item then
122+
if opts.callback then
123+
opts.callback(item._path)
124+
else
125+
snacks_picker.actions.jump(picker, item, action)
126+
end
127+
end
128+
end,
52129
})
53-
54-
if result and opts.callback then
55-
local path = clean_path(result)
56-
opts.callback(tostring(dir / path))
57-
end
130+
snacks_picker.pick(pick_opts)
58131
end
59132

60133
SnacksPicker.pick = function(self, values, opts)
61-
62-
self.calling_bufnr = vim.api.nvim_get_current_buf()
63-
64-
local buf = opts.buf or vim.api.nvim_get_current_buf()
65-
66-
opts = opts and opts or {}
67-
68-
local entries = {}
69-
for _, value in ipairs(values) do
70-
if type(value) == "string" then
71-
table.insert(entries, {
72-
text = value,
73-
value = value,
74-
})
75-
elseif value.valid ~= false then
76-
local name = self:_make_display(value)
77-
table.insert(entries, {
134+
self.calling_bufnr = vim.api.nvim_get_current_buf()
135+
136+
opts = opts or {}
137+
138+
local buf = opts.buf or vim.api.nvim_get_current_buf()
139+
140+
-- local map = vim.tbl_deep_extend("force", {},
141+
-- map_actions(opts.selection_mappings),
142+
-- map_actions(opts.query_mappings))
143+
144+
local entries = {}
145+
for _, value in ipairs(values) do
146+
if type(value) == "string" then
147+
table.insert(entries, {
148+
text = value,
149+
value = value,
150+
})
151+
elseif value.valid ~= false then
152+
local name = self:_make_display(value)
153+
table.insert(entries, {
78154
text = name,
79155
buf = buf,
80156
filename = value.filename,
81157
value = value.value,
82158
pos = { value.lnum, value.col },
83-
})
159+
})
160+
end
84161
end
85-
end
86162

87-
snacks_picker({
88-
tilte = opts.prompt_title,
89-
items = entries,
90-
layout = {
163+
local pick_opts = vim.tbl_extend("force", map or {}, {
164+
tilte = opts.prompt_title,
165+
items = entries,
166+
layout = {
91167
preview = false
92-
},
93-
format = function(item, _)
94-
local ret = {}
95-
local a = snacks_picker.util.align
96-
ret[#ret + 1] = { a(item.text, 20) }
97-
return ret
98-
end,
99-
confirm = function(picker, item)
100-
picker:close()
101-
if item then
102-
if opts.callback then
103-
opts.callback(item.value)
104-
elseif item then
105-
vim.schedule(function()
106-
if item["buf"] then
107-
vim.api.nvim_set_current_buf(item["buf"])
168+
},
169+
format = "text",
170+
confirm = function(picker, item)
171+
picker:close()
172+
if item and opts.callback then
173+
if type(item) == "string" then
174+
opts.callback(item)
175+
else
176+
opts.callback(item.value)
108177
end
109-
vim.api.nvim_win_set_cursor(0, {item["pos"][1], 0})
110-
end)
111-
end
112-
end
113-
end,
114-
-- sort = require("snacks.picker.sort").idx(),
115-
})
178+
end
179+
end,
180+
})
181+
182+
local entry = snacks_picker.pick(pick_opts)
116183
end
117184

118185
return SnacksPicker

0 commit comments

Comments
 (0)