mirror of
https://github.com/gosticks/bookmarks.nvim.git
synced 2025-10-16 11:55:38 +00:00
feat(sign): update signs and markadd ,markrm,markclean etc functions
This commit is contained in:
parent
1ce6fdb40d
commit
e71384a5ce
@ -8,7 +8,7 @@ A Bookmarks Plugin With Global File Store For Neovim Written In Lua.
|
||||
|
||||
## Installation
|
||||
|
||||
[packer.nvim] :
|
||||
With [packer.nvim]:
|
||||
|
||||
```lua
|
||||
use {
|
||||
@ -43,6 +43,7 @@ require('bookmarks').setup {
|
||||
|
||||
- [gitsigns.nvim] most of lua functions come from this plugin
|
||||
- [vim-bookmarks](https://github.com/MattesGroeger/vim-bookmarks) inspired by this vim plugin
|
||||
- [possession.nvim](https://github.com/jedrzejboczar/possession.nvim) some util functions
|
||||
|
||||
[gitsigns.nvim]: https://github.com/lewis6991/gitsigns.nvim
|
||||
[packer.nvim]: https://github.com/wbthomason/packer.nvim
|
||||
|
||||
@ -5,11 +5,55 @@ local uv = vim.loop
|
||||
local current_buf = api.nvim_get_current_buf
|
||||
local config = require "bookmarks.config"
|
||||
local signs = require "bookmarks.signs"
|
||||
local nvim = require "bookmarks.nvim"
|
||||
local hl = require "bookmarks.highlight"
|
||||
local actions = require "bookmarks.actions"
|
||||
|
||||
local M = {}
|
||||
|
||||
local function wrap_func(fn, ...)
|
||||
local args = { ... }
|
||||
local nargs = select("#", ...)
|
||||
return function()
|
||||
fn(unpack(args, 1, nargs))
|
||||
end
|
||||
end
|
||||
local function autocmd(event, opts)
|
||||
local opts0 = {}
|
||||
if type(opts) == "function" then
|
||||
opts0.callback = wrap_func(opts)
|
||||
else
|
||||
opts0 = opts
|
||||
end
|
||||
opts0.group = "bookmarks"
|
||||
nvim.autocmd(event, opts0)
|
||||
end
|
||||
|
||||
M.attach = void(function(bufnr, aucmd)
|
||||
scheduler()
|
||||
actions.loadBookmarks()
|
||||
if config.on_attach then
|
||||
config.on_attach(bufnr)
|
||||
end
|
||||
end)
|
||||
|
||||
M.detach_all = void(function(bufnr)
|
||||
scheduler()
|
||||
signs.detach(bufnr)
|
||||
actions.saveBookmarks()
|
||||
end)
|
||||
|
||||
M.setup = void(function(cfg)
|
||||
config.build(cfg)
|
||||
signs.setup()
|
||||
nvim.augroup "bookmarks"
|
||||
autocmd("VimLeavePre", M.detach_all)
|
||||
autocmd("ColorScheme", hl.setup_highlights)
|
||||
autocmd("BufRead", wrap_func(M.attach, nil, "BufRead"))
|
||||
end)
|
||||
|
||||
return M
|
||||
return setmetatable(M, {
|
||||
__index = function(_, f)
|
||||
return actions[f]
|
||||
end,
|
||||
})
|
||||
|
||||
@ -1,11 +1,34 @@
|
||||
local config = require("bookmarks.config").config
|
||||
local void = require("bookmarks.async").void
|
||||
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 function updateBookmarks(bufnr, line, mark, ann)
|
||||
local filepath = uv.fs_realpath(api.nvim_buf_get_name(bufnr))
|
||||
local marks = config.cache[filepath]
|
||||
local isIns = false
|
||||
if line == -1 then
|
||||
marks = nil
|
||||
-- check buffer auto_save to file
|
||||
return
|
||||
end
|
||||
for i = 1, #marks do
|
||||
if marks[i].l == line and mark == "" then
|
||||
table.remove(marks, i)
|
||||
elseif marks[i].l == line then
|
||||
isIns = true
|
||||
end
|
||||
end
|
||||
if isIns == false then
|
||||
table.insert(marks, ann and { l = line, m = mark, a = ann } or { l = line, m = mark })
|
||||
-- check buffer auto_save to file
|
||||
-- M.saveBookmarks()
|
||||
end
|
||||
end
|
||||
|
||||
M.toggle_signs = function(value)
|
||||
if value ~= nil then
|
||||
config.signcolumn = value
|
||||
@ -16,44 +39,78 @@ M.toggle_signs = function(value)
|
||||
return config.signcolumn
|
||||
end
|
||||
|
||||
M.bookmark_add = function(lnum)
|
||||
local signlines = {}
|
||||
M.bookmark_add = function()
|
||||
local lnum = api.nvim_win_get_cursor(0)[1]
|
||||
local bufnr = current_buf()
|
||||
signlines[0] = {
|
||||
local signlines = { {
|
||||
type = "add",
|
||||
count = 1,
|
||||
lnum = lnum,
|
||||
}
|
||||
} }
|
||||
signs:add(bufnr, signlines)
|
||||
updateBookmarks(bufnr, lnum, "line ")
|
||||
end
|
||||
|
||||
M.bookmark_rm = function()
|
||||
local lnum = api.nvim_win_get_cursor(0)[1]
|
||||
local bufnr = current_buf()
|
||||
signs:remove(bufnr, lnum)
|
||||
updateBookmarks(bufnr, lnum, "")
|
||||
end
|
||||
|
||||
M.bookmark_clean = function()
|
||||
local bufnr = current_buf()
|
||||
updateBookmarks(bufnr, -1, "")
|
||||
end
|
||||
|
||||
M.bookmark_ann = function(old_annotation)
|
||||
local new_annotation = ""
|
||||
local input_msg = old_annotation ~= "" and "Edit" or "Enter"
|
||||
vim.ui.input(input_msg, old_annotation, function(answer)
|
||||
new_annotation = answer
|
||||
end)
|
||||
local lnum = api.nvim_win_get_cursor(0)[1]
|
||||
local bufnr = current_buf()
|
||||
local signlines = { {
|
||||
type = "ann",
|
||||
lnum = lnum,
|
||||
} }
|
||||
signs:add(bufnr, signlines)
|
||||
updateBookmarks(bufnr, lnum, "line ", new_annotation)
|
||||
end
|
||||
|
||||
M.bookmark_rm = function() end
|
||||
M.bookmark_clean = function() end
|
||||
M.bookmark_ann = function() end
|
||||
M.bookmark_prev = function() end
|
||||
M.bookmark_next = function() end
|
||||
M.refresh = function() end
|
||||
M.bookmark_showall = function() end
|
||||
|
||||
local function saveBookmarks(filepath)
|
||||
local content = {
|
||||
index = 1,
|
||||
data = {
|
||||
[filepath] = {
|
||||
{
|
||||
i = 1, -- index
|
||||
l = 1, -- line num
|
||||
c = "", -- mark content
|
||||
a = "", -- mark annotation
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
local data = vim.json.encode(content)
|
||||
M.refresh = function()
|
||||
local cache = config.cache
|
||||
local bufnr = current_buf()
|
||||
local file = uv.fs_realpath(api.nvim_buf_get_name(bufnr))
|
||||
local marks = cache.data[file]
|
||||
local signlines = {}
|
||||
if marks then
|
||||
for mark in marks do
|
||||
local ma = {
|
||||
type = mark.a and "ann" or "add",
|
||||
lnum = mark.l,
|
||||
}
|
||||
signs:remove(bufnr, ma.lnum)
|
||||
table.insert(signlines, ma)
|
||||
end
|
||||
signs:add(bufnr, signlines)
|
||||
end
|
||||
end
|
||||
|
||||
function M.loadBookmarks()
|
||||
utils.read_file(config.save_file, function(data)
|
||||
local contents = vim.json.decode(data)
|
||||
config.cache = contents
|
||||
end)
|
||||
end
|
||||
|
||||
function M.saveBookmarks()
|
||||
local data = vim.json.encode(config.cache)
|
||||
utils.write_file(config.save_file, data)
|
||||
end
|
||||
|
||||
local function loadBookmarks()
|
||||
utils.read_file(config.save_file, function(data)
|
||||
local marks = vim.json.decode(data)
|
||||
end)
|
||||
end
|
||||
return M
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
local co = coroutine
|
||||
|
||||
local Async = {}
|
||||
|
||||
local async_thread = {
|
||||
threads = {},
|
||||
}
|
||||
|
||||
@ -2,9 +2,34 @@ local M = {}
|
||||
M.config = {}
|
||||
|
||||
M.schema = {
|
||||
cache = {
|
||||
type = "table",
|
||||
deep_extend = true,
|
||||
default = {},
|
||||
},
|
||||
save_file = {
|
||||
type = "string",
|
||||
default = vim.fn.expand "~/.bookmarks",
|
||||
default = vim.fn.expand "$HOME/.bookmarks",
|
||||
},
|
||||
sign_priority = {
|
||||
type = "number",
|
||||
default = 6,
|
||||
},
|
||||
signcolumn = {
|
||||
type = "boolean",
|
||||
default = true,
|
||||
},
|
||||
numhl = {
|
||||
type = "boolean",
|
||||
default = false,
|
||||
},
|
||||
linehl = {
|
||||
type = "boolean",
|
||||
default = false,
|
||||
},
|
||||
on_attach = {
|
||||
type = "function",
|
||||
default = nil,
|
||||
},
|
||||
signs = {
|
||||
type = "table",
|
||||
|
||||
@ -48,3 +48,5 @@ end
|
||||
function M.highlight(group, opts)
|
||||
vim.api.nvim_set_hl(0, group, opts)
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
@ -13,41 +13,29 @@ function M.new(cfg, name)
|
||||
return self
|
||||
end
|
||||
|
||||
function M:on_lines(buf, _, last_orig, last_new)
|
||||
if last_orig > last_new then
|
||||
self:remove(buf, last_new + 1, last_orig)
|
||||
end
|
||||
function M:on_lines(buf, last_new)
|
||||
self:remove(buf, last_new + 1)
|
||||
end
|
||||
|
||||
function M:remove(bufnr, start_lnum, end_lnum)
|
||||
function M:remove(bufnr, start_lnum)
|
||||
if start_lnum then
|
||||
api.nvim_buf_clear_namespace(bufnr, self.ns, start_lnum - 1, end_lnum or start_lnum)
|
||||
api.nvim_buf_clear_namespace(bufnr, self.ns, start_lnum - 1, start_lnum)
|
||||
else
|
||||
api.nvim_buf_clear_namespace(bufnr, self.ns, 0, -1)
|
||||
end
|
||||
end
|
||||
|
||||
function M:add(bufnr, signs)
|
||||
if not config.signcolumn and not config.numhl and not config.linehl then
|
||||
return
|
||||
end
|
||||
|
||||
local cfg = self.config
|
||||
|
||||
for _, s in ipairs(signs) do
|
||||
if not self:contains(bufnr, s.lnum) then
|
||||
local cs = cfg[s.type]
|
||||
local text = cs.text
|
||||
if config.signcolumn and cs.show_count and s.count then
|
||||
local count = s.count
|
||||
local cc = config.count_chars
|
||||
local count_char = cc[count] or cc["+"] or ""
|
||||
text = cs.text .. count_char
|
||||
end
|
||||
|
||||
api.nvim_buf_set_extmark(bufnr, self.ns, s.lnum - 1, -1, {
|
||||
id = s.lnum,
|
||||
sign_text = config.signcolumn and text or "",
|
||||
sign_text = text,
|
||||
priority = config.sign_priority,
|
||||
sign_hl_group = cs.hl,
|
||||
number_hl_group = config.numhl and cs.numhl or nil,
|
||||
@ -57,8 +45,8 @@ function M:add(bufnr, signs)
|
||||
end
|
||||
end
|
||||
|
||||
function M:contains(bufnr, start, last)
|
||||
local marks = api.nvim_buf_get_extmarks(bufnr, self.ns, { start - 1, 0 }, { last or start, 0 }, { limit = 1 })
|
||||
function M:contains(bufnr, start)
|
||||
local marks = api.nvim_buf_get_extmarks(bufnr, self.ns, { start - 1, 0 }, { start, 0 }, { limit = 1 })
|
||||
return #marks > 0
|
||||
end
|
||||
|
||||
|
||||
@ -90,21 +90,23 @@ function M.emptytable()
|
||||
})
|
||||
end
|
||||
|
||||
function M.readfile(filename)
|
||||
local data, ok
|
||||
local fh, err, code = io.popen(filename, "r")
|
||||
if fh then
|
||||
data, err, code = fh:read "*a"
|
||||
if data then
|
||||
ok, err, code = fh:close()
|
||||
else
|
||||
fh:close()
|
||||
end
|
||||
function M.clear_prompt()
|
||||
vim.api.nvim_command "normal! :"
|
||||
end
|
||||
|
||||
function M.prompt_yes_no(prompt, callback, prompt_no_cr)
|
||||
prompt = string.format("%s [y/N] ", prompt)
|
||||
if prompt_no_cr then -- use getchar so no <cr> is required
|
||||
print(prompt)
|
||||
local ans = vim.fn.nr2char(vim.fn.getchar())
|
||||
local is_confirmed = ans:lower():match "^y"
|
||||
M.clear_prompt()
|
||||
callback(is_confirmed)
|
||||
else -- use vim.ui.input
|
||||
vim.ui.input({ prompt = prompt }, function(answer)
|
||||
callback(vim.tbl_contains({ "y", "yes" }, answer and answer:lower()))
|
||||
end)
|
||||
end
|
||||
if not ok then
|
||||
return err .. code
|
||||
end
|
||||
return data:gsub("\r", "")
|
||||
end
|
||||
|
||||
M.write_file = function(path, content)
|
||||
@ -150,4 +152,23 @@ function M.dump(o)
|
||||
end
|
||||
end
|
||||
|
||||
function M.warn(...)
|
||||
vim.notify(string.format(...), vim.log.levels.WARN)
|
||||
end
|
||||
|
||||
function M.error(...)
|
||||
vim.notify(string.format(...), vim.log.levels.ERROR)
|
||||
end
|
||||
|
||||
function M.lazy(fn)
|
||||
local cached
|
||||
return function(...)
|
||||
if cached == nil then
|
||||
cached = fn(...)
|
||||
assert(cached ~= nil, "lazy: fn returned nil")
|
||||
end
|
||||
return cached
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
Loading…
Reference in New Issue
Block a user