Neovim quick file switcher
1---@module 'snacks'
2
3local data = require("javelin.data")
4local log = require("javelin.log")
5
6local UI = {}
7
8---@type JavelinConfig
9local options
10
11local function open_buf(file)
12 -- nvim 0.11 only command
13 if vim.fn.exists("*isabsolutepath") == 1 then
14 if not vim.fn.isabsolutepath(file) then
15 file = data.get_root() .. "/" .. file
16 end
17 else
18 if file:sub(1, 1) ~= "/" and file:sub(1, 1) ~= "~" then
19 file = data.get_root() .. "/" .. file
20 end
21 end
22
23 local bufnr = vim.fn.bufadd(vim.fn.expand(file))
24 vim.fn.bufload(bufnr)
25 vim.api.nvim_set_option_value("buflisted", true, {
26 buf = bufnr,
27 })
28 vim.api.nvim_set_current_buf(bufnr)
29end
30
31---@param index number
32function UI.select(index)
33 local file = data.get_current()[index]
34 if file ~= nil then
35 open_buf(file)
36 end
37end
38
39function UI.open()
40 local root = data.get_root()
41 local initial_text = data.get_list(root)
42 Snacks.win.new({
43 text = initial_text,
44 title = root,
45 title_pos = options.menu.title_pos,
46 width = options.menu.width,
47 height = options.menu.height,
48 border = options.menu.border,
49 keys = options.menu.keys,
50 fixbuf = true,
51 wo = {
52 number = true,
53 },
54 bo = {
55 modifiable = true,
56 readonly = false,
57 buftype = "nofile",
58 bufhidden = "wipe",
59 },
60 actions = {
61 ["goto"] = function(self)
62 local file = vim.api.nvim_get_current_line()
63 self:close()
64 open_buf(file)
65 end,
66 },
67 on_close = function(self)
68 if self.buf then
69 local lines = self:lines()
70 if #lines == 1 and lines[1] == "" then
71 lines = {}
72 end
73 if not vim.deep_equal(initial_text, lines) then
74 data.update(root, self:lines())
75 log.info("Javelin updated.")
76 end
77 else
78 log.error("No buf on win")
79 end
80 end,
81 })
82end
83
84function UI.setup(opt)
85 options = opt
86end
87
88return UI