tangled
alpha
login
or
join now
robinwobin.dev
/
artio.nvim
3
fork
atom
minimal extui fuzzy finder for neovim
3
fork
atom
overview
issues
pulls
pipelines
feat: add marks
robinwobin.dev
3 months ago
30d45b45
3c77a191
+82
-8
5 changed files
expand all
collapse all
unified
split
lua
artio
builtins.lua
config.lua
picker.lua
utils.lua
view.lua
+7
-8
lua/artio/builtins.lua
···
10
local config = lzrq("artio.config")
11
local utils = lzrq("artio.utils")
12
13
-
local function extend(t1, t2)
14
-
return vim.tbl_deep_extend("force", t1, t2)
15
end
16
17
local builtins = {}
···
39
preview_item = function(item)
40
return vim.fn.bufadd(item)
41
end,
42
-
actions = {
43
-
setqflist = utils.make_setqflist(function(item)
0
44
return { filename = item.v }
45
end),
46
-
},
47
-
mappings = {
48
-
["<c-q>"] = "setqflist",
49
-
},
50
}, props)
51
)
52
end
···
10
local config = lzrq("artio.config")
11
local utils = lzrq("artio.utils")
12
13
+
local function extend(t1, ...)
14
+
return vim.tbl_deep_extend("force", t1, ...)
15
end
16
17
local builtins = {}
···
39
preview_item = function(item)
40
return vim.fn.bufadd(item)
41
end,
42
+
actions = extend(
43
+
{},
44
+
utils.make_setqflistactions(function(item)
45
return { filename = item.v }
46
end),
47
+
props.actions or {}
48
+
),
0
0
49
}, props)
50
)
51
end
+5
lua/artio/config.lua
···
12
---@field promptprefix string
13
---@field prompt_title boolean
14
---@field pointer string
0
15
---@field use_icons boolean
16
17
---@class artio.config.win
···
32
promptprefix = "",
33
prompt_title = true,
34
pointer = "",
0
35
use_icons = package.loaded["mini.icons"] and true or false,
36
},
37
win = {
···
51
["<up>"] = "up",
52
["<cr>"] = "accept",
53
["<esc>"] = "cancel",
0
54
["<c-l>"] = "togglepreview",
0
0
55
},
56
}
57
···
12
---@field promptprefix string
13
---@field prompt_title boolean
14
---@field pointer string
15
+
---@field marker string
16
---@field use_icons boolean
17
18
---@class artio.config.win
···
33
promptprefix = "",
34
prompt_title = true,
35
pointer = "",
36
+
marker = "│",
37
use_icons = package.loaded["mini.icons"] and true or false,
38
},
39
win = {
···
53
["<up>"] = "up",
54
["<cr>"] = "accept",
55
["<esc>"] = "cancel",
56
+
["<tab>"] = "mark",
57
["<c-l>"] = "togglepreview",
58
+
["<c-q>"] = "setqflist",
59
+
["<c-w>"] = "setqflistmark",
60
},
61
}
62
+28
lua/artio/picker.lua
···
27
---@class artio.Picker : artio.Picker.config
28
---@field idx integer 1-indexed
29
---@field matches artio.Picker.match[]
0
30
---@field actions? artio.Actions
31
local Picker = {}
32
Picker.__index = Picker
···
55
cancel = function(_, co)
56
coroutine.resume(co, action_enum.cancel)
57
end,
0
0
0
0
0
0
0
0
0
0
58
togglepreview = function(self, _)
59
self.view:togglepreview()
60
end,
···
72
idx = 0,
73
items = {},
74
matches = {},
0
75
}, require("artio.config").get(), props)
76
77
if not t.prompttext then
···
165
table.sort(self.matches, function(a, b)
166
return a[3] > b[3]
167
end)
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
168
end
169
170
return Picker
···
27
---@class artio.Picker : artio.Picker.config
28
---@field idx integer 1-indexed
29
---@field matches artio.Picker.match[]
30
+
---@field marked table<integer, true|nil>
31
---@field actions? artio.Actions
32
local Picker = {}
33
Picker.__index = Picker
···
56
cancel = function(_, co)
57
coroutine.resume(co, action_enum.cancel)
58
end,
59
+
mark = function(self, _)
60
+
local match = self.matches[self.idx]
61
+
if not match then
62
+
return
63
+
end
64
+
local idx = match[1]
65
+
self:mark(idx, not self.marked[idx])
66
+
self.view:showmatches() -- redraw marker
67
+
self.view:hlselect()
68
+
end,
69
togglepreview = function(self, _)
70
self.view:togglepreview()
71
end,
···
83
idx = 0,
84
items = {},
85
matches = {},
86
+
marked = {},
87
}, require("artio.config").get(), props)
88
89
if not t.prompttext then
···
177
table.sort(self.matches, function(a, b)
178
return a[3] > b[3]
179
end)
180
+
end
181
+
182
+
---@param idx integer
183
+
---@param yes? boolean
184
+
function Picker:mark(idx, yes)
185
+
self.marked[idx] = yes == nil and true or yes
186
+
end
187
+
188
+
---@return integer[]
189
+
function Picker:getmarked()
190
+
return vim
191
+
.iter(pairs(self.marked))
192
+
:map(function(k, v)
193
+
return v and k or nil
194
+
end)
195
+
:totable()
196
end
197
198
return Picker
+30
lua/artio/utils.lua
···
30
end
31
end
32
0
0
33
function utils.make_setqflist(fn)
34
return function(self, co)
35
vim.fn.setqflist(vim
···
45
end)
46
coroutine.resume(co, 1)
47
end
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
48
end
49
50
return utils
···
30
end
31
end
32
33
+
---@param fn fun(item: artio.Picker.item): vim.quickfix.entry
34
+
---@return artio.Picker.action
35
function utils.make_setqflist(fn)
36
return function(self, co)
37
vim.fn.setqflist(vim
···
47
end)
48
coroutine.resume(co, 1)
49
end
50
+
end
51
+
52
+
---@param fn fun(item: artio.Picker.item): vim.quickfix.entry
53
+
---@return artio.Picker.action
54
+
function utils.make_setqflistmark(fn)
55
+
return function(self, co)
56
+
vim.fn.setqflist(vim
57
+
.iter(ipairs(self:getmarked()))
58
+
:map(function(_, id)
59
+
local item = self.items[id]
60
+
local qfitem = fn(item)
61
+
return qfitem
62
+
end)
63
+
:totable())
64
+
vim.schedule(function()
65
+
vim.cmd.copen()
66
+
end)
67
+
coroutine.resume(co, 1)
68
+
end
69
+
end
70
+
71
+
---@param fn fun(item: artio.Picker.item): vim.quickfix.entry
72
+
---@return table<string, artio.Picker.action>
73
+
function utils.make_setqflistactions(fn)
74
+
return {
75
+
setqflist = utils.make_setqflist(fn),
76
+
setqflistmark = utils.make_setqflistmark(fn),
77
+
}
78
end
79
80
return utils
+12
lua/artio/view.lua
···
441
local hls = {}
442
local icons = {} ---@type ([string, string]|false)[]
443
local custom_hls = {} ---@type (artio.Picker.hl[]|false)[]
0
444
for i = 1 + offset, math.min(#self.picker.matches, maxlistheight + offset) do
445
local match = self.picker.matches[i]
446
local item = self.picker.items[match[1]]
···
459
item.hls = hl
460
end
461
custom_hls[#custom_hls + 1] = hl or false
0
0
462
463
lines[#lines + 1] = ("%s%s%s"):format(prefix, icon, item.text)
464
hls[#hls + 1] = match[2]
···
500
})
501
)
502
end
0
0
0
0
0
0
0
0
0
503
end
504
505
if hls[i] then
···
441
local hls = {}
442
local icons = {} ---@type ([string, string]|false)[]
443
local custom_hls = {} ---@type (artio.Picker.hl[]|false)[]
444
+
local marks = {} ---@type boolean[]
445
for i = 1 + offset, math.min(#self.picker.matches, maxlistheight + offset) do
446
local match = self.picker.matches[i]
447
local item = self.picker.items[match[1]]
···
460
item.hls = hl
461
end
462
custom_hls[#custom_hls + 1] = hl or false
463
+
464
+
marks[#marks + 1] = self.picker.marked[item.id] or false
465
466
lines[#lines + 1] = ("%s%s%s"):format(prefix, icon, item.text)
467
hls[#hls + 1] = match[2]
···
503
})
504
)
505
end
506
+
end
507
+
508
+
if marks[i] then
509
+
self:mark(cmdline.srow + i - 1, indent - 1, {
510
+
virt_text = { { self.picker.opts.marker, "ArtioMarker" } },
511
+
hl_mode = "combine",
512
+
virt_text_pos = "overlay",
513
+
invalidate = true,
514
+
})
515
end
516
517
if hls[i] then