minimal extui fuzzy finder for neovim
1---@module 'artio.config'
2
3---@class artio.config
4---@field opts artio.config.opts
5---@field win artio.config.win
6---@field mappings table<string, 'up'|'down'|'accept'|'cancel'|'togglepreview'|string>
7
8---@class artio.config.opts
9---@field preselect boolean
10---@field bottom boolean
11---@field shrink boolean
12---@field promptprefix string
13---@field prompt_title boolean
14---@field pointer string
15---@field use_icons boolean
16
17---@class artio.config.win
18---@field height? integer|number
19---@field hidestatusline? boolean
20---@field preview_opts? fun(view: artio.View): vim.api.keyset.win_config
21
22local M = {}
23
24---@type artio.config
25---@eval return MiniDoc.afterlines_to_code(MiniDoc.current.eval_section)
26---@text # Default ~
27M.default = {
28 opts = {
29 preselect = true,
30 bottom = true,
31 shrink = true,
32 promptprefix = "",
33 prompt_title = true,
34 pointer = "",
35 use_icons = package.loaded["mini.icons"] and true or false,
36 },
37 win = {
38 height = 0.4,
39 hidestatusline = false, -- works best with laststatus=3
40 preview_opts = function(view)
41 return {
42 width = vim.o.columns,
43 height = view.win.height,
44 col = 0,
45 row = vim.o.lines - vim.o.cmdheight * 2 - 1 - (vim.o.winborder == "none" and 0 or 2),
46 }
47 end,
48 },
49 mappings = {
50 ["<down>"] = "down",
51 ["<up>"] = "up",
52 ["<cr>"] = "accept",
53 ["<esc>"] = "cancel",
54 ["<c-l>"] = "togglepreview",
55 },
56}
57
58---@type artio.config
59---@diagnostic disable-next-line: missing-fields
60M.config = {}
61
62---@private
63---@generic T: table|any[]
64---@param tdefault T
65---@param toverride T
66---@return T
67local function tmerge(tdefault, toverride)
68 if toverride == nil then
69 return tdefault
70 end
71
72 if vim.islist(tdefault) then
73 return toverride
74 end
75 if vim.tbl_isempty(tdefault) then
76 return toverride
77 end
78
79 return vim.iter(pairs(tdefault)):fold({}, function(tnew, k, v)
80 if toverride[k] == nil or type(v) ~= type(toverride[k]) then
81 tnew[k] = v
82 return tnew
83 end
84 if type(v) == "table" then
85 tnew[k] = tmerge(v, toverride[k])
86 return tnew
87 end
88
89 tnew[k] = toverride[k]
90 return tnew
91 end)
92end
93
94---@param tdefault artio.config
95---@param toverride artio.config
96---@return artio.config
97function M.merge(tdefault, toverride)
98 if vim.fn.has("nvim-0.11.0") == 1 then
99 toverride =
100 vim.tbl_deep_extend("keep", toverride, { editor = { float = { solid_border = vim.o.winborder == "solid" } } })
101 end
102 return tmerge(tdefault, toverride)
103end
104
105---@return artio.config
106function M.get()
107 return M.merge(M.default, M.config)
108end
109
110---@param cfg artio.config
111---@return artio.config
112function M.override(cfg)
113 return M.merge(M.default, cfg)
114end
115
116---@param cfg artio.config
117function M.set(cfg)
118 M.config = cfg
119end
120
121return M