Neovim quick file switcher
at main 2.9 kB view raw
1---@module 'snacks' 2 3local log = require("javelin.log") 4 5local Data = {} 6 7---@type JavelinConfig 8local options 9 10local data_dir 11local data_cache = {} 12 13---@param path string 14---@return string 15local function hash_path(path) 16 return vim.fn.sha256(vim.fn.resolve(path)) 17end 18 19---@param root_path string 20local function get_data_file(root_path) 21 return vim.fn.resolve(data_dir .. "/" .. hash_path(root_path)) 22end 23 24---@param root_path string 25---@param path string 26---@return string 27local function normalize_path(root_path, path) 28 root_path = root_path .. "/" 29 if vim.startswith(path, root_path) then 30 return path:sub(#root_path + 1) 31 end 32 33 return path 34end 35 36---@param root_path string 37---@param list string[] 38---@return string[] 39local function normalize_list(root_path, list) 40 local new_list = {} 41 for _, path in ipairs(list) do 42 if path ~= "" then 43 table.insert(new_list, path) 44 end 45 end 46 47 for i, path in ipairs(new_list) do 48 new_list[i] = normalize_path(root_path, path) 49 end 50 51 return new_list 52end 53 54---@param root_path string 55local function load(root_path) 56 local data_file = get_data_file(root_path) 57 if not vim.uv.fs_stat(data_file) then 58 return {} 59 end 60 61 return normalize_list(root_path, vim.fn.readfile(data_file)) 62end 63 64---@param root_path string 65local function write(root_path) 66 vim.fn.writefile(Data.get_list(root_path), get_data_file(root_path)) 67end 68 69---@param root_path string 70---@param path string 71local function add_path(root_path, path) 72 local list = Data.get_list(root_path) 73 path = normalize_path(root_path, vim.fn.fnamemodify(path, ":~")) 74 75 if vim.tbl_contains(list, path) then 76 log.warn("File already in list: " .. path) 77 return 78 end 79 80 table.insert(list, path) 81 write(root_path) 82end 83 84---@param root_path string 85---@return string[] 86function Data.get_list(root_path) 87 local hash = hash_path(root_path) 88 if data_cache[hash] == nil then 89 data_cache[hash] = load(root_path) 90 end 91 92 return data_cache[hash] 93end 94 95---@return string[] 96function Data.get_current() 97 return Data.get_list(Data.get_root()) 98end 99 100function Data.add_current() 101 local filename = vim.api.nvim_buf_get_name(0) 102 local buftype = vim.api.nvim_get_option_value("buftype", { buf = 0 }) 103 104 if filename ~= "" and buftype == "" then 105 add_path(Data.get_root(), filename) 106 else 107 log.warn("Cannot add this buffer") 108 end 109end 110 111---@param root_path string 112---@param lines string[] 113function Data.update(root_path, lines) 114 data_cache[hash_path(root_path)] = normalize_list(root_path, lines) 115 write(root_path) 116end 117 118---@return string 119function Data.get_root() 120 local root = vim.fn.getcwd() 121 122 if options.use_git_root then 123 local git_root = Snacks.git.get_root(root) 124 if git_root then 125 root = git_root 126 end 127 end 128 129 return vim.fn.fnamemodify(root, ":~") 130end 131 132function Data.setup(opt) 133 options = opt 134 135 data_dir = vim.fn.resolve(vim.fn.stdpath("data") .. "/javelin") 136 if not vim.uv.fs_stat(data_dir) then 137 vim.uv.fs_mkdir(data_dir, tonumber("755", 8)) 138 end 139end 140 141return Data