When storing a hovered file as bookmark it makes sense to use the reveal command to move to it. When storing the parent directory however, one has to cd to it. Otherwise the parent directory is opened and the stored directory is only focused.
292 lines
7.2 KiB
Lua
292 lines
7.2 KiB
Lua
-- 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("<key>", state.bookmarks[_idx].on)
|
|
message, _ = message:gsub("<folder>", 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("<key>", state.bookmarks[idx].on)
|
|
message, _ = message:gsub("<folder>", 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 '<key>' -> '<folder>'",
|
|
delete = "Deleted bookmark in '<key>'",
|
|
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,
|
|
}
|