Skip to content

Commit 4038c14

Browse files
committed
feat(picker): add autodetection of picker modules
1 parent c15b38a commit 4038c14

File tree

3 files changed

+67
-20
lines changed

3 files changed

+67
-20
lines changed

lua/tiny-code-action/config.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ M.picker_config = {
4949

5050
M.default_config = {
5151
backend = "vim",
52-
picker = "telescope",
52+
picker = nil,
5353
backend_opts = {
5454
delta = {
5555
header_lines_to_remove = 4,

lua/tiny-code-action/init.lua

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ function M.code_action(opts)
7676
if type(M.config.picker) == "table" then
7777
picker_name = M.config.picker[1]
7878
else
79-
picker_name = M.config.picker or "telescope"
79+
picker_name = M.config.picker or picker_util.autodetect_picker()
8080
end
8181

8282
local picker_module = picker_util.get_picker_module(picker_name)
@@ -114,6 +114,11 @@ end
114114
function M.setup(opts)
115115
M.config = vim.tbl_deep_extend("force", {}, M.config, opts or {})
116116

117+
-- If no picker is configured, use autodetection
118+
if not M.config.picker then
119+
M.config.picker = picker_util.autodetect_picker()
120+
end
121+
117122
local picker_name = type(M.config.picker) == "table" and M.config.picker[1] or M.config.picker
118123
local default_picker_opts = M.picker_config[picker_name] or {}
119124

lua/tiny-code-action/picker.lua

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,84 @@
11
local config = require("tiny-code-action.config")
22
local M = {}
33

4+
--- Checks if a specific picker is available on the system
5+
--- @param picker_name string: Name of the picker to check
6+
--- @return boolean: True if picker is available
7+
local function is_picker_available(picker_name)
8+
if picker_name == "telescope" then
9+
return pcall(require, "telescope")
10+
elseif picker_name == "fzf-lua" then
11+
return pcall(require, "fzf-lua")
12+
elseif picker_name == "snacks" then
13+
return pcall(require, "snacks")
14+
elseif picker_name == "select" then
15+
return vim.ui and vim.ui.select ~= nil
16+
elseif picker_name == "buffer" then
17+
return true
18+
end
19+
return false
20+
end
21+
22+
--- Autodetects the best available picker on the system
23+
--- @return string: Name of the detected picker
24+
function M.autodetect_picker()
25+
local picker_priority = {
26+
"telescope",
27+
"fzf-lua",
28+
"snacks",
29+
"select",
30+
"buffer",
31+
}
32+
33+
for _, picker_name in ipairs(picker_priority) do
34+
if is_picker_available(picker_name) then
35+
return picker_name
36+
end
37+
end
38+
39+
return "buffer"
40+
end
41+
442
-- Get a picker module by name, with fallbacks
543
--- Retrieves a picker module by name, with fallbacks to defaults if unavailable.
644
--- @param picker_name string: Name of the picker module
745
--- @returntable|nil: Picker module or nil if not found
846
function M.get_picker_module(picker_name)
947
if not config.VALID_PICKERS[picker_name] then
1048
vim.notify(
11-
"Invalid picker: " .. picker_name .. ". Using default 'telescope'.",
49+
"Invalid picker: " .. picker_name .. ". Using autodetected picker.",
1250
vim.log.levels.WARN
1351
)
14-
return M.get_picker_module("telescope")
52+
return M.get_picker_module(M.autodetect_picker())
1553
end
54+
1655
local has_picker, picker_module = pcall(require, "tiny-code-action.pickers." .. picker_name)
1756
if has_picker then
1857
return picker_module
1958
end
20-
if picker_name == "telescope" then
59+
60+
local fallback_chain = {
61+
telescope = "fzf-lua",
62+
["fzf-lua"] = "snacks",
63+
snacks = "select",
64+
select = "buffer",
65+
buffer = nil,
66+
}
67+
68+
local fallback = fallback_chain[picker_name]
69+
if fallback and is_picker_available(fallback) then
2170
vim.notify(
22-
"Telescope picker is not available. Falling back to vim.ui.select.",
71+
picker_name:gsub("^%l", string.upper)
72+
.. " picker is not available. Falling back to "
73+
.. fallback
74+
.. ".",
2375
vim.log.levels.WARN
2476
)
25-
return M.get_picker_module("select")
26-
elseif picker_name == "snacks" then
27-
vim.notify("Snacks picker is not available. Falling back to telescope.", vim.log.levels.WARN)
28-
return M.get_picker_module("telescope")
29-
elseif picker_name == "select" then
30-
vim.notify("Select picker is not available. Falling back to buffer.", vim.log.levels.WARN)
31-
return M.get_picker_module("buffer")
32-
elseif picker_name == "fzf-lua" then
33-
vim.notify("Fzflua picker is not available. No picker could be loaded.", vim.log.levels.ERROR)
34-
return M.get_picker_module("select")
35-
elseif picker_name == "buffer" then
36-
vim.notify("Buffer picker is not available. No picker could be loaded.", vim.log.levels.ERROR)
37-
return nil
77+
return M.get_picker_module(fallback)
78+
elseif fallback then
79+
return M.get_picker_module(fallback)
3880
else
39-
vim.notify("Could not load any picker module. This should not happen.", vim.log.levels.ERROR)
81+
vim.notify("No picker could be loaded.", vim.log.levels.ERROR)
4082
return nil
4183
end
4284
end

0 commit comments

Comments
 (0)