local M = {} local cursors = {} local files = {} -- default maxsize M.maxsize = 1000 -- get the default system cache directory local get_default_cache_path = function() local HOME = os.getenv('HOME') local XDG_CACHE_HOME = os.getenv('XDG_CACHE_HOME') local BASE = XDG_CACHE_HOME or HOME return BASE .. '/.vis-cursors' end -- default save path M.path = get_default_cache_path() function read_files() -- read file local file = io.open(M.path) if file == nil then return end files = {} -- read positions per file path for line in file:lines() do for path, pos in string.gmatch(line, '(.+)[,%s](%d+)') do cursors[path] = pos table.insert(files, path) end end file:close() end -- read cursors from file on init local on_init = function() read_files() end -- apply cursor pos on win open local on_win_open = function(win) if win.file == nil or win.file.path == nil then return end -- init cursor path if nil local pos = cursors[win.file.path] if pos == nil then cursors[win.file.path] = win.selection.pos return end -- set current cursor win.selection.pos = tonumber(pos) -- center view around cursor vis:feedkeys("zz") end -- set cursor pos on close local on_win_close = function(win) if win.file == nil or win.file.path == nil then return end -- re-read files in case they've changed read_files() -- remove old occurences of current path for i, path in ipairs(files) do if path == win.file.path then table.remove(files, i) end end -- ignore files with cursor at the beginning if win.selection.pos == 0 then return end -- insert current path to top of files table.insert(files, 1, win.file.path) -- set cursor pos for current file path cursors[win.file.path] = win.selection.pos end -- write cursors to file on quit local on_quit = function() local file = io.open(M.path, 'w+') if file == nil then return end -- buffer cursors string local buffer = {} for i, path in ipairs(files) do table.insert(buffer, string.format('%s,%d', path, cursors[path])) if M.maxsize and #buffer >= M.maxsize then break end end local output = table.concat(buffer, '\n') file:write(output) file:close() end vis.events.subscribe(vis.events.INIT, on_init) vis.events.subscribe(vis.events.WIN_OPEN, on_win_open) vis.events.subscribe(vis.events.WIN_CLOSE, on_win_close) vis.events.subscribe(vis.events.QUIT, on_quit) return M