-- stylua: ignore local SUPPORTED_KEYS = { { on = "0"}, { on = "1"}, { on = "2"}, { on = "3"}, { on = "4"}, { on = "5"}, { on = "6"}, { on = "7"}, { on = "8"}, { on = "9"}, { on = "A"}, { on = "B"}, { on = "C"}, { on = "D"}, { on = "E"}, { on = "F"}, { on = "G"}, { on = "H"}, { on = "I"}, { on = "J"}, { on = "K"}, { on = "L"}, { on = "M"}, { on = "N"}, { on = "O"}, { on = "P"}, { on = "Q"}, { on = "R"}, { on = "S"}, { on = "T"}, { on = "U"}, { on = "V"}, { on = "W"}, { on = "X"}, { on = "Y"}, { on = "Z"}, { on = "a"}, { on = "b"}, { on = "c"}, { on = "d"}, { on = "e"}, { on = "f"}, { on = "g"}, { on = "h"}, { on = "i"}, { on = "j"}, { on = "k"}, { on = "l"}, { on = "m"}, { on = "n"}, { on = "o"}, { on = "p"}, { on = "q"}, { on = "r"}, { on = "s"}, { on = "t"}, { on = "u"}, { on = "v"}, { on = "w"}, { on = "x"}, { on = "y"}, { on = "z"}, } local _send_notification = ya.sync( function(state, message) ya.notify { title = "Bookmarks", content = message, timeout = state.notify.timeout, } end ) local _get_real_index = ya.sync(function(state, idx) for key, value in pairs(state.bookmarks) do if value.on == SUPPORTED_KEYS[idx].on then return key end end return nil end) local _get_bookmark_file = ya.sync(function(state) local folder = cx.active.current if state.file_pick_mode == "parent" or not folder.hovered then return { url = folder.cwd, is_parent = true } end return { url = folder.hovered.url, is_parent = false } end) local _generate_description = ya.sync(function(state, file) -- if this is true, we don't have information about the folder, so just return the folder url if file.is_parent then return tostring(file.url) end if state.desc_format == "parent" then return tostring(file.url:parent()) end -- full description return tostring(file.url) end) local _load_state = ya.sync(function(state) ps.sub_remote("@bookmarks", function(body) if not state.bookmarks and body then state.bookmarks = {} for _, value in pairs(body) do table.insert(state.bookmarks, value) end end end) end) local _save_state = ya.sync(function(state, bookmarks) if not bookmarks then ps.pub_to(0, "@bookmarks", nil) return end local save_state = {} if state.persist == "all" then save_state = bookmarks else -- VIM mode local idx = 1 for _, value in pairs(bookmarks) do -- Only save bookmarks in upper case keys if string.match(value.on, "%u") then save_state[idx] = value idx = idx + 1 end end end ps.pub_to(0, "@bookmarks", save_state) end) local _save_last_directory = ya.sync(function(state, persist) if persist then ps.sub_remote("@bookmarks-lastdir", function(body) state.curr_dir = body end) end ps.sub("cd", function() local file = _get_bookmark_file() state.last_dir = state.curr_dir if persist and state.last_dir then ps.pub_to(0, "@bookmarks-lastdir", state.last_dir) end state.curr_dir = { on = "'", desc = _generate_description(file), path = tostring(file.url), is_parent = file.is_parent, } end) ps.sub("hover", function() local file = _get_bookmark_file() state.curr_dir.desc = _generate_description(file) state.curr_dir.path = tostring(file.url) end) end) -- *********************************************** -- **============= C O M M A N D S =============** -- *********************************************** local save_bookmark = ya.sync(function(state, idx) local file = _get_bookmark_file() state.bookmarks = state.bookmarks or {} local _idx = _get_real_index(idx) if not _idx then _idx = #state.bookmarks + 1 end state.bookmarks[_idx] = { on = SUPPORTED_KEYS[idx].on, desc = _generate_description(file), path = tostring(file.url), is_parent = file.is_parent, } if state.persist then _save_state(state.bookmarks) end if state.notify and state.notify.enable then local message = state.notify.message.new message, _ = message:gsub("", state.bookmarks[_idx].on) message, _ = message:gsub("", state.bookmarks[_idx].desc) _send_notification(message) end end) local all_bookmarks = ya.sync(function(state, append_last_dir) local bookmarks = {} if state.bookmarks then for _, value in pairs(state.bookmarks) do table.insert(bookmarks, value) end end if append_last_dir and state.last_dir then table.insert(bookmarks, state.last_dir) end return bookmarks end) local delete_bookmark = ya.sync(function(state, idx) if state.notify and state.notify.enable then local message = state.notify.message.delete message, _ = message:gsub("", state.bookmarks[idx].on) message, _ = message:gsub("", state.bookmarks[idx].desc) _send_notification(message) end table.remove(state.bookmarks, idx) if state.persist then _save_state(state.bookmarks) end end) local delete_all_bookmarks = ya.sync(function(state) state.bookmarks = nil if state.persist then _save_state(nil) end if state.notify and state.notify.enable then _send_notification(state.notify.message.delete_all) end end) return { entry = function(_, args) local action = args[1] if not action then return end if action == "save" then local key = ya.which { cands = SUPPORTED_KEYS, silent = true } if key then save_bookmark(key) end return end if action == "delete_all" then return delete_all_bookmarks() end local bookmarks = all_bookmarks(action == "jump") local selected = #bookmarks > 0 and ya.which { cands = bookmarks } if not selected then return end if action == "jump" then if bookmarks[selected].is_parent then ya.manager_emit("cd", { bookmarks[selected].path }) else ya.manager_emit("reveal", { bookmarks[selected].path }) end elseif action == "delete" then delete_bookmark(selected) end end, setup = function(state, args) if not args then return end -- TODO: DEPRECATED if args.save_last_directory then _save_last_directory() elseif type(args.last_directory) == "table" then if args.last_directory.enable then _save_last_directory(args.last_directory.persist) end end if args.persist == "all" or args.persist == "vim" then state.persist = args.persist _load_state() end if args.desc_format == "parent" then state.desc_format = "parent" else state.desc_format = "full" end if args.file_pick_mode == "parent" then state.file_pick_mode = "parent" else state.file_pick_mode = "hover" end state.notify = { enable = false, timeout = 1, message = { new = "New bookmark '' -> ''", delete = "Deleted bookmark in ''", delete_all = "Deleted all bookmarks", }, } if type(args.notify) == "table" then if type(args.notify.enable) == "boolean" then state.notify.enable = args.notify.enable end if type(args.notify.timeout) == "number" then state.notify.timeout = args.notify.timeout end if type(args.notify.message) == "table" then if type(args.notify.message.new) == "string" then state.notify.message.new = args.notify.message.new end if type(args.notify.message.delete) == "string" then state.notify.message.delete = args.notify.message.delete end if type(args.notify.message.delete_all) == "string" then state.notify.message.delete_all = args.notify.message.delete_all end end end end, }