feat!: init proj , add some lua functions the proj need

This commit is contained in:
tomasky 2022-06-30 19:55:17 +08:00
parent d05b554d54
commit 810abbfa32
9 changed files with 506 additions and 1 deletions

View File

@ -1,2 +1,48 @@
# bookmarks.nvim
A Bookmarks Plugin With Global File Store For Neovim Written In Lua.
A Bookmarks Plugin With Global File Store For Neovim Written In Lua.
## Requirements
- Neovim >= 0.7.0
## Installation
[packer.nvim] :
```lua
use {
'tomasky/bookmarks.nvim',
-- tag = 'release' -- To use the latest release
}
```
## Usage
For basic setup with all default configs using [packer.nvim]
```lua
use {
'tomasky/bookmarks.nvim',
config = function()
require('bookmarks').setup()
end
}
```
Here is an example with most of the default settings:
```lua
require('bookmarks').setup {
}
```
## Credits
- [gitsigns.nvim] most lua functions come from this plugin
- [vim-bookmarks](https://github.com/MattesGroeger/vim-bookmarks) inspired by this vim plugin
[gitsigns.nvim]: https://github.com/lewis6991/gitsigns.nvim
[packer.nvim]: https://github.com/wbthomason/packer.nvim

12
lua/bookmarks.lua Normal file
View File

@ -0,0 +1,12 @@
local void = require('gitsigns.async').void
local scheduler = require('gitsigns.async').scheduler
local api = vim.api
local uv = vim.loop
local current_buf = api.nvim_get_current_buf
local M = {}
M.setup = void(function(cfg)
end)
return M

19
lua/bookmarks/actions.lua Normal file
View File

@ -0,0 +1,19 @@
local config = require("bookmarks.config").config
local void = require("gitsigns.async").void
local M = {}
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_add = function() end
M.bookmark_rm = function() end
M.bookmark_clean = function() end
M.bookmark_ann = function() end
M.refresh = function() end

87
lua/bookmarks/async.lua Normal file
View File

@ -0,0 +1,87 @@
local co = coroutine
local Async = {}
local async_thread = {
threads = {},
}
local function threadtostring(x)
if jit then
return string.format("%p", x)
else
return tostring(x):match "thread: (.*)"
end
end
function async_thread.running()
local thread = co.running()
local id = threadtostring(thread)
return async_thread.threads[id]
end
function async_thread.create(fn)
local thread = co.create(fn)
local id = threadtostring(thread)
async_thread.threads[id] = true
return thread
end
function async_thread.finished(x)
if co.status(x) == "dead" then
local id = threadtostring(x)
async_thread.threads[id] = nil
return true
end
return false
end
local function execute(async_fn, ...)
local thread = async_thread.create(async_fn)
local function step(...)
local ret = { co.resume(thread, ...) }
local stat, err_or_fn, nargs = unpack(ret)
if not stat then
error(string.format("The coroutine failed with this message: %s\n%s", err_or_fn, debug.traceback(thread)))
end
if async_thread.finished(thread) then
return
end
assert(type(err_or_fn) == "function", "type error :: expected func")
local ret_fn = err_or_fn
local args = { select(4, unpack(ret)) }
args[nargs] = step
ret_fn(unpack(args, 1, nargs))
end
step(...)
end
local M = {}
function M.wrap(func, argc)
return function(...)
if not async_thread.running() then
return func(...)
end
return co.yield(func, argc, ...)
end
end
function M.void(func)
return function(...)
if async_thread.running() then
return func(...)
end
execute(func, ...)
end
end
M.scheduler = M.wrap(vim.schedule, 1)
return M

47
lua/bookmarks/config.lua Normal file
View File

@ -0,0 +1,47 @@
local M = {}
M.config = {}
M.schema = {}
local function validate_config(config)
for k, v in pairs(config) do
local kschema = M.schema[k]
if kschema == nil then
warn("gitsigns: Ignoring invalid configuration field '%s'", k)
elseif kschema.type then
if type(kschema.type) == "string" then
vim.validate {
[k] = { v, kschema.type },
}
end
end
end
end
local function resolve_default(v)
if type(v.default) == "function" and v.type ~= "function" then
return (v.default)()
else
return v.default
end
end
function M.build(user_config)
user_config = user_config or {}
validate_config(user_config)
local config = M.config
for k, v in pairs(M.schema) do
if user_config[k] ~= nil then
if v.deep_extend then
local d = resolve_default(v)
config[k] = vim.tbl_deep_extend("force", d, user_config[k])
else
config[k] = user_config[k]
end
else
config[k] = resolve_default(v)
end
end
end
return M

View File

@ -0,0 +1,32 @@
local api = vim.api
local nvim = require "bookmarks.nvim"
local M = {}
local hls = {
{ BookMarksAdd = { "MarkAdd" } },
}
local function is_hl_set(hl_name)
local exists, hl = pcall(api.nvim_get_hl_by_name, hl_name, true)
local color = hl.foreground or hl.background or hl.reverse
return exists and color ~= nil
end
M.setup_highlights = function()
for _, hlg in ipairs(hls) do
for hl, candidates in pairs(hlg) do
if is_hl_set(hl) then
else
for _, d in ipairs(candidates) do
if is_hl_set(d) then
nvim.highlight(hl, { default = true, link = d })
break
end
end
end
end
end
end
return M

50
lua/bookmarks/nvim.lua Normal file
View File

@ -0,0 +1,50 @@
local M = {}
function M.autocmd(event, opts)
vim.api.nvim_create_autocmd(event, opts)
end
function M.augroup(name, opts)
vim.api.nvim_create_augroup(name, opts or {})
end
local callbacks = {}
function M._exec(id, ...)
callbacks[id](...)
end
local F = M
function M.set(fn, is_expr, args)
local id
if jit then
id = "cb" .. string.format("%p", fn)
else
id = "cb" .. tostring(fn):match "function: (.*)"
end
if is_expr then
F[id] = fn
return string.format("v:lua.require'bookmarks.nvim.callbacks'." .. id)
else
if args then
callbacks[id] = fn
return string.format('lua require("bookmarks.nvim.callbacks")._exec("%s", %s)', id, args)
else
callbacks[id] = function()
fn()
end
return string.format('lua require("bookmarks.nvim.callbacks")._exec("%s")', id)
end
end
end
function M.command(name, fn, opts)
vim.api.nvim_create_user_command(name, fn, opts)
end
function M.highlight(group, opts)
vim.api.nvim_set_hl(0, group, opts)
end

71
lua/bookmarks/signs.lua Normal file
View File

@ -0,0 +1,71 @@
local api = vim.api
local config = require("bookmarks.config").config
local M = {}
local group_base = "bookmarks_extmark_signs_"
function M.new(cfg, name)
local self = setmetatable({}, { __index = M })
self.config = cfg
self.group = group_base .. (name or "")
self.ns = api.nvim_create_namespace(self.group)
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
end
function M:remove(bufnr, start_lnum, end_lnum)
if start_lnum then
api.nvim_buf_clear_namespace(bufnr, self.ns, start_lnum - 1, end_lnum or 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 "",
priority = config.sign_priority,
sign_hl_group = cs.hl,
number_hl_group = config.numhl and cs.numhl or nil,
line_hl_group = config.linehl and cs.linehl or nil,
})
end
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 })
return #marks > 0
end
function M:reset()
for _, buf in ipairs(api.nvim_list_bufs()) do
self:remove(buf)
end
end
return M

141
lua/bookmarks/util.lua Normal file
View File

@ -0,0 +1,141 @@
local M = {}
function M.path_exists(path)
return vim.loop.fs_stat(path) and true or false
end
local jit_os
if jit then
jit_os = jit.os:lower()
end
local is_unix = false
if jit_os then
is_unix = jit_os == "linux" or jit_os == "osx" or jit_os == "bsd"
else
local binfmt = package.cpath:match "%p[\\|/]?%p(%a+)"
is_unix = binfmt ~= "dll"
end
function M.dirname(file)
return file:match(string.format("^(.+)%s[^%s]+", M.path_sep, M.path_sep))
end
function M.file_lines(file)
local text = {}
for line in io.lines(file) do
text[#text + 1] = line
end
return text
end
M.path_sep = package.config:sub(1, 1)
function M.buf_lines(bufnr)
local buftext = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
if vim.bo[bufnr].fileformat == "dos" then
for i = 1, #buftext do
buftext[i] = buftext[i] .. "\r"
end
end
return buftext
end
function M.set_lines(bufnr, start_row, end_row, lines)
if vim.bo[bufnr].fileformat == "dos" then
for i = 1, #lines do
lines[i] = lines[i]:gsub("\r$", "")
end
end
vim.api.nvim_buf_set_lines(bufnr, start_row, end_row, false, lines)
end
function M.tmpname()
if is_unix then
return os.tmpname()
end
return vim.fn.tempname()
end
function M.copy_array(x)
local r = {}
for i, e in ipairs(x) do
r[i] = e
end
return r
end
function M.strip_cr(xs0)
for i = 1, #xs0 do
if xs0[i]:sub(-1) ~= "\r" then
return xs0
end
end
local xs = vim.deepcopy(xs0)
for i = 1, #xs do
xs[i] = xs[i]:sub(1, -2)
end
return xs
end
function M.emptytable()
return setmetatable({}, {
__index = function(t, k)
t[k] = {}
return t[k]
end,
})
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
end
if not ok then
return err .. code
end
return data:gsub("\r", "")
end
function M.writefile(filename, data)
local ok
local fh, err, code = io.popen(filename, "w")
if fh then
ok, err, code = fh:write(data)
if ok then
ok, err, code = fh:close()
else
fh:close()
end
end
if not ok then
return err .. code
end
return data
end
function M.dump(o)
if type(o) == "table" then
local s = "{ "
for k, v in pairs(o) do
if type(k) ~= "number" then
k = '"' .. k .. '"'
end
s = s .. "[" .. k .. "] = " .. M.dump(v) .. ","
end
return s .. "} "
else
return tostring(o)
end
end
return M