zk-nvim/lua/zk/root_pattern_util.lua
Karim Abou Zeid b0ce17b020
major refactoring, custom commands, configurable picker (#14)
* new way of defining user commands

* add FZF picker

* support vim.ui.select as picker

* refactor

* update readme

* Improved architecture, according to https://github.com/mickael-menu/zk-nvim/pull/14#pullrequestreview-840097886

* fix lsp not attaching buffers

* make "select" the default picker

* update README

* simplify picker api, make multi_select=true the default

* rename action->cb

* amend

* rename path->notebook_path and move into options arg

* fix

* Update README

* easier command syntax

* use new command api

* clean up commands

* easier command syntax

* doc

* update README

* add more code documentation

* update README

* remove lspconfig dependency

* add autogenerated vimdoc (md2vim)

* fix command viml syntax

* better command syntax

* correctly (not) handle character encoding when getting selected text

* README fixes

* Remove `zk.edit_from_tags`

* fixes, also remove `:Telescope zk tags`

* update vimdoc

Co-authored-by: Mickaël Menu <mickael.menu@gmail.com>
2022-01-02 00:13:36 +01:00

108 lines
2.3 KiB
Lua

-- NOTE: everything in this module is copied from nvim-lspconfig (https://github.com/neovim/nvim-lspconfig)
-- NOTE: we need this util until the code from lspconfig is merged into core
local vim = vim
local validate = vim.validate
local uv = vim.loop
local M = {}
-- Some path utilities
M.path = (function()
local is_windows = uv.os_uname().version:match 'Windows'
local function exists(filename)
local stat = uv.fs_stat(filename)
return stat and stat.type or false
end
local function is_fs_root(path)
if is_windows then
return path:match '^%a:$'
else
return path == '/'
end
end
local function dirname(path)
local strip_dir_pat = '/([^/]+)$'
local strip_sep_pat = '/$'
if not path or #path == 0 then
return
end
local result = path:gsub(strip_sep_pat, ''):gsub(strip_dir_pat, '')
if #result == 0 then
if is_windows then
return path:sub(1, 2):upper()
else
return '/'
end
end
return result
end
local function path_join(...)
return table.concat(vim.tbl_flatten { ... }, '/')
end
-- Iterate the path until we find the rootdir.
local function iterate_parents(path)
local function it(_, v)
if v and not is_fs_root(v) then
v = dirname(v)
else
return
end
if v and uv.fs_realpath(v) then
return v, path
else
return
end
end
return it, path, path
end
return {
exists = exists,
join = path_join,
iterate_parents = iterate_parents,
}
end)()
function M.search_ancestors(startpath, func)
validate { func = { func, 'f' } }
if func(startpath) then
return startpath
end
local guard = 100
for path in M.path.iterate_parents(startpath) do
-- Prevent infinite recursion if our algorithm breaks
guard = guard - 1
if guard == 0 then
return
end
if func(path) then
return path
end
end
end
function M.root_pattern(...)
local patterns = vim.tbl_flatten { ... }
local function matcher(path)
for _, pattern in ipairs(patterns) do
for _, p in ipairs(vim.fn.glob(M.path.join(path, pattern), true, true)) do
if M.path.exists(p) then
return path
end
end
end
end
return function(startpath)
return M.search_ancestors(startpath, matcher)
end
end
return M