feature: Vim help-tags picker (#117)
* feature: Vim help-tags picker * fix: filtered results were wrong because of missing `entry.value` * fix: filtered (Vim only help) items are listed in results as empty entries. * fix: avoid search history pollution by replacing / in cmd returned by taglist() with search() * fix: improve search() formatting * fix: escape tilde in search() command * fix: improve help-preview * fix: improve search() * fix: search() string fixes. * fix: use no magic to do magic Co-authored-by: TJ DeVries <devries.timothyj@gmail.com>
This commit is contained in:
11858
data/help/tags
Normal file
11858
data/help/tags
Normal file
File diff suppressed because it is too large
Load Diff
@@ -402,6 +402,45 @@ builtin.command_history = function(opts)
|
||||
}):find()
|
||||
end
|
||||
|
||||
builtin.help_tags = function(opts)
|
||||
opts = opts or {}
|
||||
|
||||
local sourced_file = require('plenary.debug_utils').sourced_filepath()
|
||||
local base_directory = vim.fn.fnamemodify(sourced_file, ":h:h:h")
|
||||
local file = base_directory .. "/data/help/tags"
|
||||
|
||||
local tags = {}
|
||||
local f = assert(io.open(file, "rb"))
|
||||
for line in f:lines() do
|
||||
table.insert(tags, line)
|
||||
end
|
||||
f:close()
|
||||
|
||||
pickers.new(opts, {
|
||||
prompt = 'Help',
|
||||
finder = finders.new_table {
|
||||
results = tags,
|
||||
entry_maker = make_entry.gen_from_tagfile(opts),
|
||||
},
|
||||
-- TODO: previewer for Vim help
|
||||
previewer = previewers.help.new(opts),
|
||||
sorter = sorters.get_generic_fuzzy_sorter(),
|
||||
attach_mappings = function(prompt_bufnr, map)
|
||||
local view_help = function()
|
||||
local selection = actions.get_selected_entry(prompt_bufnr)
|
||||
|
||||
actions.close(prompt_bufnr)
|
||||
vim.cmd("help " .. selection.value)
|
||||
end
|
||||
|
||||
map('i', '<CR>', view_help)
|
||||
map('n', '<CR>', view_help)
|
||||
|
||||
return true
|
||||
end
|
||||
}):find()
|
||||
end
|
||||
|
||||
-- TODO: What the heck should we do for accepting this.
|
||||
-- vim.fn.setreg("+", "nnoremap $TODO :lua require('telescope.builtin').<whatever>()<CR>")
|
||||
-- TODO: Can we just do the names instead?
|
||||
|
||||
@@ -284,4 +284,53 @@ function make_entry.gen_from_treesitter(opts)
|
||||
end
|
||||
end
|
||||
|
||||
function make_entry.gen_from_tagfile(opts)
|
||||
local help_entry, version
|
||||
local delim = string.char(7)
|
||||
|
||||
local make_display = function(line)
|
||||
help_entry = ""
|
||||
display = ""
|
||||
version = ""
|
||||
|
||||
line = line .. delim
|
||||
for section in line:gmatch("(.-)" .. delim) do
|
||||
if section:find("^vim:") == nil then
|
||||
local ver = section:match("^neovim:(.*)")
|
||||
if ver == nil then
|
||||
help_entry = section
|
||||
else
|
||||
version = ver:sub(1, -2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
result = {}
|
||||
if version ~= "" then -- some Vim only entries are unversioned
|
||||
if opts.show_version then
|
||||
result.display = string.format("%s [%s]", help_entry, version)
|
||||
else
|
||||
result.display = help_entry
|
||||
end
|
||||
result.value = help_entry
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
return function(line)
|
||||
local entry = {
|
||||
entry_type = make_entry.types.GENERIC,
|
||||
|
||||
}
|
||||
local d = make_display(line)
|
||||
entry.valid = next(d) ~= nil
|
||||
entry.display = d.display
|
||||
entry.value = d.value
|
||||
entry.ordinal = d.value
|
||||
|
||||
return entry
|
||||
end
|
||||
end
|
||||
|
||||
return make_entry
|
||||
|
||||
@@ -58,7 +58,7 @@ end
|
||||
local previewer_ns = vim.api.nvim_create_namespace('telescope.previewers')
|
||||
|
||||
local with_preview_window = function(status, bufnr, callable)
|
||||
if bufnr and vim.api.nvim_buf_call then
|
||||
if bufnr and vim.api.nvim_buf_call and false then
|
||||
vim.api.nvim_buf_call(bufnr, callable)
|
||||
else
|
||||
return context_manager.with(function()
|
||||
@@ -365,17 +365,17 @@ previewers.qflist = defaulter(function(opts)
|
||||
}
|
||||
end, {})
|
||||
|
||||
-- WIP
|
||||
previewers.help = defaulter(function(_)
|
||||
return previewers.new {
|
||||
preview_fn = function(_, entry, status)
|
||||
with_preview_window(status, nil, function()
|
||||
local old_tags = vim.o.tags
|
||||
vim.o.tags = vim.fn.expand("$VIMRUNTIME") .. '/doc/tags'
|
||||
local special_chars = ":~^.?/%[%]%*"
|
||||
|
||||
local taglist = vim.fn.taglist('^' .. entry.value .. '$')
|
||||
local escaped = vim.fn.escape(entry.value, special_chars)
|
||||
local tagfile = vim.fn.expand("$VIMRUNTIME") .. '/doc/tags'
|
||||
local taglist = vim.fn.taglist('^' .. escaped .. '$', tagfile)
|
||||
if vim.tbl_isempty(taglist) then
|
||||
taglist = vim.fn.taglist(entry.value)
|
||||
taglist = vim.fn.taglist(escaped, tagfile)
|
||||
end
|
||||
|
||||
if vim.tbl_isempty(taglist) then
|
||||
@@ -384,15 +384,23 @@ previewers.help = defaulter(function(_)
|
||||
|
||||
local best_entry = taglist[1]
|
||||
local new_bufnr = vim.fn.bufnr(best_entry.filename, true)
|
||||
|
||||
vim.api.nvim_buf_set_option(new_bufnr, 'filetype', 'help')
|
||||
vim.api.nvim_win_set_buf(status.preview_win, new_bufnr)
|
||||
|
||||
vim.cmd [["gg"]]
|
||||
print(best_entry.cmd)
|
||||
vim.cmd(string.format([[execute "%s"]], best_entry.cmd))
|
||||
local search_query = best_entry.cmd
|
||||
|
||||
vim.o.tags = old_tags
|
||||
-- remove leading '/'
|
||||
search_query = search_query:sub(2)
|
||||
|
||||
-- Set the query to "very nomagic".
|
||||
-- This should make it work quite nicely given tags.
|
||||
search_query = [[\V]] .. search_query
|
||||
|
||||
log.trace([[lua vim.fn.search("]], search_query, [[")]])
|
||||
|
||||
vim.cmd "norm! gg"
|
||||
vim.fn.search(search_query, "W")
|
||||
vim.cmd "norm zt"
|
||||
end)
|
||||
end
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user