diff --git a/lua/bookmarks.lua b/lua/bookmarks.lua index c0bd01e..ca14749 100644 --- a/lua/bookmarks.lua +++ b/lua/bookmarks.lua @@ -49,7 +49,6 @@ M.detach_all = void(function(bufnr) bufnr = bufnr or current_buf() scheduler() actions.detach(bufnr) - actions.saveBookmarks() end) local function on_or_after_vimenter(fn) diff --git a/lua/bookmarks/actions.lua b/lua/bookmarks/actions.lua index 3fccffc..e60896d 100644 --- a/lua/bookmarks/actions.lua +++ b/lua/bookmarks/actions.lua @@ -16,35 +16,41 @@ M.detach = function(bufnr, keep_signs) end end +local function updateBookmarks_fpath(filepath, lnum, mark, ann) + 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 } + end + data[filepath] = marks + M.saveBookmarks() -- always save to file +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 + updateBookmarks_fpath(filepath, lnum, mark, ann) end M.toggle_signs = function(value) @@ -74,6 +80,12 @@ M.bookmark_toggle = function() end end +M.bookmark_reload = function() + M.loadBookmarks() + M.setup() + M.refresh() +end + M.bookmark_clean = function() local bufnr = current_buf() signs:remove(bufnr) @@ -99,7 +111,17 @@ M.bookmark_ann = function() 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)] + local text = nil + local ann = answer or "" + if string.sub(ann, 1, 1) == "@" then + text = config.keywords[string.sub(ann, 1, 2)] + else + local first_char = vim.fn.strcharpart(ann, 0, 1) + if first_char ~= "" and first_char ~= " " then + text = first_char + end + end + if text then signlines[1]["text"] = text end @@ -108,6 +130,21 @@ M.bookmark_ann = function() end) end +M.bookmark_del = function(filename, lnum) + local buf_list = api.nvim_list_bufs() + for _, buf in ipairs(buf_list) do + if api.nvim_buf_is_loaded(buf) then + local buf_name = api.nvim_buf_get_name(buf) + local buf_path = uv.fs_realpath(buf_name) + if buf_path == filename or buf_name == filename then + signs:remove(buf, lnum) + break + end + end + end + updateBookmarks_fpath(filename, lnum, "") +end + local jump_line = function(prev) local lnum = api.nvim_win_get_cursor(0)[1] local marks = M.bookmark_line() @@ -177,8 +214,18 @@ M.refresh = function(bufnr) type = v.a and "ann" or "add", lnum = tonumber(k), } - local pref = string.sub(v.a or "", 1, 2) - local text = config.keywords[pref] + local ann = v.a or "" + local text = nil + if string.sub(ann, 1, 1) == "@" then + local pref = string.sub(ann, 1, 2) + text = config.keywords[pref] + else + local first_char = vim.fn.strcharpart(ann, 0, 1) + if first_char ~= "" and first_char ~= " " then + text = first_char + end + end + if text then ma["text"] = text end diff --git a/lua/telescope/_extensions/bookmarks.lua b/lua/telescope/_extensions/bookmarks.lua index f6420d5..f4d8c38 100644 --- a/lua/telescope/_extensions/bookmarks.lua +++ b/lua/telescope/_extensions/bookmarks.lua @@ -8,66 +8,107 @@ local pickers = require "telescope.pickers" local entry_display = require "telescope.pickers.entry_display" local conf = require("telescope.config").values local config = require("bookmarks.config").config +local bm = require("bookmarks") local utils = require "telescope.utils" +local actions = require('telescope.actions') +local action_state = require('telescope.actions.state') +local transform_mod = require('telescope.actions.mt').transform_mod local function get_text(annotation) - local pref = string.sub(annotation, 1, 2) - local ret = config.keywords[pref] + local ret = nil + if string.sub(annotation, 1, 1) == "@" then + local pref = string.sub(annotation, 1, 2) + ret = config.keywords[pref] + else + local first_char = vim.fn.strcharpart(annotation, 0, 1) + if first_char ~= "" and first_char ~= " " then + ret = first_char + end + end if ret == nil then ret = config.signs.ann.text .. " " end return ret .. annotation end -local function bookmark(opts) - opts = opts or {} - local allmarks = config.cache.data - local marklist = {} - for k, ma in pairs(allmarks) do - for l, v in pairs(ma) do - table.insert(marklist, { - filename = k, - lnum = tonumber(l), - text = v.a and get_text(v.a) or v.m, - }) - end - end - local display = function(entry) - local displayer = entry_display.create { - separator = "▏", - items = { +local function get_list() + local allmarks = config.cache.data + local marklist = {} + for k, ma in pairs(allmarks) do + for l, v in pairs(ma) do + table.insert(marklist, { + filename = k, + lnum = tonumber(l), + text = v.a and get_text(v.a) or v.m, + }) + end + end + return marklist +end + +local function display(entry) + local displayer = entry_display.create { + separator = "▏", + items = { { width = 5 }, - { width = 30 }, + { width = 100 }, { remaining = true }, - }, - } - local line_info = { entry.lnum, "TelescopeResultsLineNr" } - return displayer { - line_info, - entry.text:gsub(".* | ", ""), - utils.path_smart(entry.filename), -- or path_tail - } - end - pickers.new(opts, { - prompt_title = "bookmarks", - finder = finders.new_table { - results = marklist, - entry_maker = function(entry) + }, + } + local line_info = { entry.lnum, "TelescopeResultsLineNr" } + return displayer { + line_info, + entry.text:gsub(".* | ", ""), + utils.path_tail(entry.filename), -- or path_tail + } +end + +local function make_finder() + return finders.new_table { + results = get_list(), + entry_maker = function(entry) return { - valid = true, - value = entry, - display = display, - ordinal = entry.filename .. entry.text, - filename = entry.filename, - lnum = entry.lnum, - col = 1, - text = entry.text, + valid = true, + value = entry, + display = display, + ordinal = entry.filename .. entry.text, + filename = entry.filename, + lnum = entry.lnum, + col = 1, + text = entry.text, } - end, - }, - sorter = conf.generic_sorter(opts), - previewer = conf.qflist_previewer(opts), - }):find() + end, + } +end + +function bm_delete(prompt_bufnr) + local selectedEntry = action_state.get_selected_entry() + bm.bookmark_del(selectedEntry.filename, selectedEntry.lnum) + local current_picker = action_state.get_current_picker(prompt_bufnr) + current_picker:refresh(make_finder()) +end + +local bm_actions = transform_mod { + delete_selected = bm_delete, +} + +local function bookmark(opts) + opts = opts or {} + pickers.new(opts, { + prompt_title = "bookmarks", + finder = make_finder(), + sorter = conf.generic_sorter(opts), + previewer = conf.qflist_previewer(opts), + attach_mappings = function(prompt_bufnr, map) + map('n', '', bm_actions.delete_selected) + map('i', '', bm_actions.delete_selected) + return true + end, + }):find() +end + +local function bm_reload() + bm.bookmark_reload() end -return telescope.register_extension { exports = { list = bookmark } } +return telescope.register_extension { exports = { list = bookmark, actions = bm_actions, reload = bm_reload } }