feat: Add tags (#219)
This commit is contained in:
@@ -923,4 +923,54 @@ builtin.keymaps = function(opts)
|
|||||||
}):find()
|
}):find()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
builtin.tags = function(opts)
|
||||||
|
opts = opts or {}
|
||||||
|
|
||||||
|
local ctags_file = opts.ctags_file or 'tags'
|
||||||
|
|
||||||
|
if not vim.loop.fs_open(vim.fn.expand(ctags_file), "r", 438) then
|
||||||
|
print('Tags file does not exists. Create one with ctags -R')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local fd = assert(vim.loop.fs_open(vim.fn.expand(ctags_file), "r", 438))
|
||||||
|
local stat = assert(vim.loop.fs_fstat(fd))
|
||||||
|
local data = assert(vim.loop.fs_read(fd, stat.size, 0))
|
||||||
|
assert(vim.loop.fs_close(fd))
|
||||||
|
|
||||||
|
local results = vim.split(data, '\n')
|
||||||
|
|
||||||
|
pickers.new(opts,{
|
||||||
|
prompt = 'Tags',
|
||||||
|
finder = finders.new_table {
|
||||||
|
results = results,
|
||||||
|
entry_maker = make_entry.gen_from_ctags(opts),
|
||||||
|
},
|
||||||
|
previewer = previewers.ctags.new(opts),
|
||||||
|
sorter = conf.generic_sorter(opts),
|
||||||
|
attach_mappings = function(prompt_bufnr)
|
||||||
|
actions._goto_file_selection:enhance {
|
||||||
|
post = function()
|
||||||
|
local selection = actions.get_selected_entry(prompt_bufnr)
|
||||||
|
|
||||||
|
local scode = string.gsub(selection.scode, '[$]$', '')
|
||||||
|
scode = string.gsub(scode, [[\\]], [[\]])
|
||||||
|
scode = string.gsub(scode, [[\/]], [[/]])
|
||||||
|
scode = string.gsub(scode, '[*]', [[\*]])
|
||||||
|
|
||||||
|
vim.cmd('norm! gg')
|
||||||
|
vim.fn.search(scode)
|
||||||
|
vim.cmd('norm! zz')
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
}):find()
|
||||||
|
end
|
||||||
|
|
||||||
|
builtin.current_buffer_tags = function(opts)
|
||||||
|
opts = opts or {}
|
||||||
|
return builtin.tags(vim.tbl_extend("force", {only_current_file = true, hide_filename = true}, opts))
|
||||||
|
end
|
||||||
|
|
||||||
return builtin
|
return builtin
|
||||||
|
|||||||
@@ -559,4 +559,73 @@ function make_entry.gen_from_vimoptions(opts)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function make_entry.gen_from_ctags(opts)
|
||||||
|
opts = opts or {}
|
||||||
|
|
||||||
|
local cwd = vim.fn.expand(opts.cwd or vim.fn.getcwd())
|
||||||
|
local current_file = path.normalize(vim.fn.expand('%'), cwd)
|
||||||
|
|
||||||
|
local display_items = {
|
||||||
|
{ width = 30 },
|
||||||
|
{ remaining = true },
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.show_line then
|
||||||
|
table.insert(display_items, 2, { width = 30 })
|
||||||
|
end
|
||||||
|
|
||||||
|
local displayer = entry_display.create {
|
||||||
|
separator = " │ ",
|
||||||
|
items = display_items,
|
||||||
|
}
|
||||||
|
|
||||||
|
local make_display = function(entry)
|
||||||
|
local filename
|
||||||
|
if not opts.hide_filename then
|
||||||
|
if opts.shorten_path then
|
||||||
|
filename = path.shorten(entry.filename)
|
||||||
|
else
|
||||||
|
filename = entry.filename
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local scode
|
||||||
|
if opts.show_line then
|
||||||
|
scode = entry.scode
|
||||||
|
end
|
||||||
|
|
||||||
|
return displayer {
|
||||||
|
filename,
|
||||||
|
entry.tag,
|
||||||
|
scode,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return function(line)
|
||||||
|
if line == '' or line:sub(1, 1) == '!' then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local tag, file, scode = string.match(line, '([^\t]+)\t([^\t]+)\t/^\t?(.*)/;"\t+.*')
|
||||||
|
|
||||||
|
if opts.only_current_file and file ~= current_file then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
valid = true,
|
||||||
|
|
||||||
|
ordinal = file .. ': ' .. tag,
|
||||||
|
display = make_display,
|
||||||
|
scode = scode,
|
||||||
|
tag = tag,
|
||||||
|
|
||||||
|
filename = file,
|
||||||
|
|
||||||
|
col = 1,
|
||||||
|
lnum = 1,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return make_entry
|
return make_entry
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ end
|
|||||||
|
|
||||||
local function truncate(str, len)
|
local function truncate(str, len)
|
||||||
-- TODO: This doesn't handle multi byte chars...
|
-- TODO: This doesn't handle multi byte chars...
|
||||||
if vim.fn.strdisplaywidth(str) > len - 1 then
|
if vim.fn.strdisplaywidth(str) > len then
|
||||||
str = str:sub(1, len)
|
str = str:sub(1, len - 1)
|
||||||
str = str .. "…"
|
str = str .. "…"
|
||||||
end
|
end
|
||||||
return str
|
return str
|
||||||
@@ -68,8 +68,10 @@ entry_display.create = function(configuration)
|
|||||||
|
|
||||||
return function(self, picker)
|
return function(self, picker)
|
||||||
local results = {}
|
local results = {}
|
||||||
for k, v in ipairs(self) do
|
for i = 1, table.getn(generator) do
|
||||||
table.insert(results, generator[k](v, picker))
|
if self[i] ~= nil then
|
||||||
|
table.insert(results, generator[i](self[i], picker))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return table.concat(results, configuration.separator or "│")
|
return table.concat(results, configuration.separator or "│")
|
||||||
|
|||||||
@@ -400,6 +400,46 @@ previewers.vimgrep = defaulter(function(opts)
|
|||||||
}
|
}
|
||||||
end, {})
|
end, {})
|
||||||
|
|
||||||
|
previewers.ctags = defaulter(function(opts)
|
||||||
|
return previewers.new {
|
||||||
|
setup = function()
|
||||||
|
return {}
|
||||||
|
end,
|
||||||
|
|
||||||
|
teardown = function(self)
|
||||||
|
if self.state and self.state.hl_id then
|
||||||
|
pcall(vim.fn.matchdelete, self.state.hl_id, self.state.hl_win)
|
||||||
|
self.state.hl_id = nil
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
preview_fn = function(self, entry, status)
|
||||||
|
with_preview_window(status, nil, function()
|
||||||
|
local scode = string.gsub(entry.scode, '[$]$', '')
|
||||||
|
scode = string.gsub(scode, [[\\]], [[\]])
|
||||||
|
scode = string.gsub(scode, [[\/]], [[/]])
|
||||||
|
scode = string.gsub(scode, '[*]', [[\*]])
|
||||||
|
|
||||||
|
local new_bufnr = vim.fn.bufnr(entry.filename, true)
|
||||||
|
vim.fn.bufload(new_bufnr)
|
||||||
|
|
||||||
|
vim.api.nvim_win_set_buf(status.preview_win, new_bufnr)
|
||||||
|
vim.api.nvim_win_set_option(status.preview_win, 'wrap', false)
|
||||||
|
vim.api.nvim_win_set_option(status.preview_win, 'winhl', 'Normal:Normal')
|
||||||
|
vim.api.nvim_win_set_option(status.preview_win, 'signcolumn', 'no')
|
||||||
|
vim.api.nvim_win_set_option(status.preview_win, 'foldlevel', 100)
|
||||||
|
|
||||||
|
pcall(vim.fn.matchdelete, self.state.hl_id, self.state.hl_win)
|
||||||
|
vim.fn.search(scode)
|
||||||
|
vim.cmd "norm zz"
|
||||||
|
|
||||||
|
self.state.hl_win = status.preview_win
|
||||||
|
self.state.hl_id = vim.fn.matchadd('Search', scode)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end, {})
|
||||||
|
|
||||||
previewers.qflist = defaulter(function(opts)
|
previewers.qflist = defaulter(function(opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user