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 preview window
robinwobin.dev
4 months ago
8a6f329e
f75d3367
+94
-2
4 changed files
expand all
collapse all
unified
split
lua
artio
builtins.lua
config.lua
picker.lua
view.lua
+6
lua/artio/builtins.lua
···
51
51
get_icon = config.get().opts.use_icons and function(item)
52
52
return require("mini.icons").get("file", item.v)
53
53
end or nil,
54
54
+
preview_item = function(item)
55
55
+
return vim.fn.bufadd(item)
56
56
+
end,
54
57
})
55
58
end
56
59
···
100
103
get_icon = config.get().opts.use_icons and function(item)
101
104
return require("mini.icons").get("file", vim.api.nvim_buf_get_name(item.v))
102
105
end or nil,
106
106
+
preview_item = function(item)
107
107
+
return item
108
108
+
end,
103
109
})
104
110
end
105
111
+10
-1
lua/artio/config.lua
···
16
16
---@class artio.config.win
17
17
---@field height? integer|number
18
18
---@field hidestatusline? boolean
19
19
+
---@field preview_opts? fun(view: artio.View): vim.api.keyset.win_config
19
20
20
21
local M = {}
21
22
···
30
31
promptprefix = "",
31
32
prompt_title = true,
32
33
pointer = "",
33
33
-
use_icons = package.loaded['mini.icons'] and true or false,
34
34
+
use_icons = package.loaded["mini.icons"] and true or false,
34
35
},
35
36
win = {
36
37
height = 0.4,
37
38
hidestatusline = false, -- works best with laststatus=3
39
39
+
preview_opts = function(view)
40
40
+
return {
41
41
+
width = vim.o.columns,
42
42
+
height = view.win.height,
43
43
+
col = 0,
44
44
+
row = vim.o.lines - vim.o.cmdheight * 2 - 1 - (vim.o.winborder == 'none' and 0 or 2),
45
45
+
}
46
46
+
end,
38
47
},
39
48
}
40
49
+5
-1
lua/artio/picker.lua
···
3
3
---@alias artio.Picker.item { id: integer, v: string, text: string, icon?: string, icon_hl?: string }
4
4
---@alias artio.Picker.match [integer, integer[], integer] [item, pos[], score]
5
5
6
6
-
---@class artio.Picker.proto
6
6
+
---@class artio.Picker.proto<T>
7
7
---@field items? artio.Picker.item[]
8
8
---@field fn? fun(lst: artio.Picker.item[], input: string): artio.Picker.match[]
9
9
---@field on_close? fun(text: string, idx: integer)
10
10
---@field format_item? fun(item: string): string
11
11
+
---@field preview_item? fun(item: string): integer, fun(win: integer)
11
12
---@field get_icon? fun(item: artio.Picker.item): string, string
12
13
---@field opts? artio.config.opts
13
14
---@field win? artio.config.win
···
99
100
elseif typed == "<esc>" then
100
101
cancelled = true
101
102
coroutine.resume(co)
103
103
+
return ""
104
104
+
elseif typed == "<c-l>" then
105
105
+
self.view:togglepreview()
102
106
return ""
103
107
end
104
108
end)
+73
lua/artio/view.lua
···
53
53
---@field picker artio.Picker
54
54
---@field closed boolean
55
55
---@field win artio.View.win
56
56
+
---@field preview_win integer
56
57
local View = {}
57
58
View.__index = View
58
59
···
244
245
end
245
246
self.closed = true
246
247
cmdline.cmdline_show = self.prev_show
248
248
+
self:closepreview()
247
249
vim.schedule(function()
248
250
vim.cmd.stopinsert()
249
251
self:revertopts()
···
427
429
vim.api.nvim_buf_del_extmark(ext.bufs.cmd, view_ns, self.select_ext)
428
430
end
429
431
432
432
+
self:softupdatepreview()
433
433
+
430
434
self.picker:fix()
431
435
local idx = self.picker.idx
432
436
if idx == 0 then
···
451
455
self.select_ext = result
452
456
end
453
457
end
458
458
+
end
459
459
+
460
460
+
function View:togglepreview()
461
461
+
if self.preview_win then
462
462
+
self:closepreview()
463
463
+
return
464
464
+
end
465
465
+
466
466
+
self:updatepreview()
467
467
+
end
468
468
+
469
469
+
---@return integer
470
470
+
---@return fun(win: integer)?
471
471
+
function View:openpreview()
472
472
+
if self.picker.idx == 0 then
473
473
+
return -1
474
474
+
end
475
475
+
476
476
+
local match = self.picker.matches[self.picker.idx]
477
477
+
local item = self.picker.items[match[1]]
478
478
+
479
479
+
if not item or not (self.picker.preview_item and vim.is_callable(self.picker.preview_item)) then
480
480
+
return -1
481
481
+
end
482
482
+
483
483
+
return self.picker.preview_item(item.v)
484
484
+
end
485
485
+
486
486
+
function View:updatepreview()
487
487
+
local buf, on_win = self:openpreview()
488
488
+
if buf < 0 then
489
489
+
return
490
490
+
end
491
491
+
492
492
+
if not self.preview_win then
493
493
+
self.preview_win = vim.api.nvim_open_win(buf, false, vim.tbl_extend("force", self.picker.win.preview_opts(self), {
494
494
+
relative = "editor",
495
495
+
style = "minimal",
496
496
+
}))
497
497
+
else
498
498
+
vim.api.nvim_win_set_buf(self.preview_win, buf)
499
499
+
end
500
500
+
501
501
+
vim.api.nvim_set_option_value("previewwindow", true, { scope = "local", win = self.preview_win })
502
502
+
503
503
+
if on_win and vim.is_callable(on_win) then
504
504
+
on_win(self.preview_win)
505
505
+
end
506
506
+
end
507
507
+
508
508
+
function View:softupdatepreview()
509
509
+
if self.picker.idx == 0 then
510
510
+
self:closepreview()
511
511
+
end
512
512
+
513
513
+
if not self.preview_win then
514
514
+
return
515
515
+
end
516
516
+
517
517
+
self:updatepreview()
518
518
+
end
519
519
+
520
520
+
function View:closepreview()
521
521
+
if not self.preview_win then
522
522
+
return
523
523
+
end
524
524
+
525
525
+
vim.api.nvim_win_close(self.preview_win, true)
526
526
+
self.preview_win = nil
454
527
end
455
528
456
529
return View