Files
bookmarks.nvim/lua/bookmarks/actions.lua
2023-04-26 22:52:49 +08:00

209 lines
5.1 KiB
Lua

local config = require("bookmarks.config").config
local uv = vim.loop
local Signs = require "bookmarks.signs"
local utils = require "bookmarks.util"
local api = vim.api
local current_buf = api.nvim_get_current_buf
local M = {}
local signs
M.setup = function()
signs = Signs.new(config.signs)
end
M.detach = function(bufnr, keep_signs)
if not keep_signs then
signs:remove(bufnr)
end
end
local function updateBookmarks(bufnr, lnum, mark, ann)
local filepath = uv.fs_realpath(api.nvim_buf_get_name(bufnr))
if filepath == nil then
return
end
local data = config.cache["data"]
local marks = data[filepath]
local isIns = false
if lnum == -1 then
marks = nil
isIns = true
-- check buffer auto_save to file
end
for k, _ in pairs(marks or {}) do
if k == tostring(lnum) then
isIns = true
if mark == "" then
marks[k] = nil
end
break
end
end
if isIns == false or ann then
marks = marks or {}
marks[tostring(lnum)] = ann and { m = mark, a = ann } or { m = mark }
-- check buffer auto_save to file
-- M.saveBookmarks()
end
data[filepath] = marks
end
M.toggle_signs = function(value)
if value ~= nil then
config.signcolumn = value
else
config.signcolumn = not config.signcolumn
end
M.refresh()
return config.signcolumn
end
M.bookmark_toggle = function()
local lnum = api.nvim_win_get_cursor(0)[1]
local bufnr = current_buf()
local signlines = { {
type = "add",
lnum = lnum,
} }
local isExt = signs:add(bufnr, signlines)
if isExt then
signs:remove(bufnr, lnum)
updateBookmarks(bufnr, lnum, "")
else
local line = api.nvim_buf_get_lines(bufnr, lnum - 1, lnum, false)[1]
updateBookmarks(bufnr, lnum, line)
end
end
M.bookmark_clean = function()
local bufnr = current_buf()
signs:remove(bufnr)
updateBookmarks(bufnr, -1, "")
end
M.bookmark_line = function(lnum, bufnr)
bufnr = bufnr or current_buf()
local file = uv.fs_realpath(api.nvim_buf_get_name(bufnr))
local marks = config.cache["data"][file] or {}
return lnum and marks[tostring(lnum)] or marks
end
M.bookmark_ann = function()
local lnum = api.nvim_win_get_cursor(0)[1]
local bufnr = current_buf()
local signlines = { {
type = "ann",
lnum = lnum,
} }
local mark = M.bookmark_line(lnum, bufnr)
vim.ui.input({ prompt = "Edit:", default = mark.a }, function(answer)
if answer == nil then return end
local line = api.nvim_buf_get_lines(bufnr, lnum - 1, lnum, false)[1]
signs:remove(bufnr, lnum)
local text = config.keywords[string.sub(answer or "", 1, 2)]
if text then
signlines[1]["text"] = text
end
signs:add(bufnr, signlines)
updateBookmarks(bufnr, lnum, line, answer)
end)
end
local jump_line = function(prev)
local lnum = api.nvim_win_get_cursor(0)[1]
local marks = M.bookmark_line()
local small, big = {}, {}
for k, _ in pairs(marks) do
k = tonumber(k)
if k < lnum then
table.insert(small, k)
elseif k > lnum then
table.insert(big, k)
end
end
if prev then
local tmp = #small > 0 and small or big
table.sort(tmp, function(a, b)
return a > b
end)
lnum = tmp[1]
else
local tmp = #big > 0 and big or small
table.sort(tmp)
lnum = tmp[1]
end
if lnum then
api.nvim_win_set_cursor(0, { lnum, 0 })
local mark = marks[tostring(lnum)]
if mark.a then
api.nvim_echo({ { "ann: " .. mark.a, "WarningMsg" } }, false, {})
else
end
end
end
M.bookmark_prev = function()
jump_line(true)
end
M.bookmark_next = function()
jump_line(false)
end
M.bookmark_list = function()
local allmarks = config.cache.data
local marklist = {}
for k, ma in pairs(allmarks) do
if utils.path_exists(k) == false then
allmarks[k] = nil
end
for l, v in pairs(ma) do
table.insert(marklist, { filename = k, lnum = l, text = v.m .. "|" .. (v.a or "") })
end
end
utils.setqflist(marklist)
end
M.refresh = function(bufnr)
bufnr = bufnr or current_buf()
local file = uv.fs_realpath(api.nvim_buf_get_name(bufnr))
if file == nil then
return
end
local marks = config.cache.data[file]
local signlines = {}
if marks then
for k, v in pairs(marks) do
local ma = {
type = v.a and "ann" or "add",
lnum = tonumber(k),
}
local pref = string.sub(v.a or "", 1, 2)
local text = config.keywords[pref]
if text then
ma["text"] = text
end
signs:remove(bufnr, ma.lnum)
table.insert(signlines, ma)
end
signs:add(bufnr, signlines)
end
end
function M.loadBookmarks()
if utils.path_exists(config.save_file) then
utils.read_file(config.save_file, function(data)
config.cache = vim.json.decode(data)
config.marks = data
end)
end
end
function M.saveBookmarks()
local data = vim.json.encode(config.cache)
if config.marks ~= data then
utils.write_file(config.save_file, data)
end
end
return M