From a7957b2bdc5c3ce86092544448b4eb6ebcbb645e Mon Sep 17 00:00:00 2001 From: Senghan Bright Date: Wed, 7 Oct 2020 22:01:47 +0200 Subject: [PATCH] feat: Manpages finder (output of apropos) (#134) First edition. Sometimes weird things can happen with the previewer, but I think I got it 99% working. * feat: Manpages finder (output of apropos) * fixup: Add previewer and fix comments Co-authored-by: TJ DeVries --- lua/telescope/builtin.lua | 39 ++++++++++++++++++++++++++++++++ lua/telescope/make_entry.lua | 18 ++++++++++++--- lua/telescope/previewers.lua | 43 ++++++++++++++++++++++++++++++++++-- 3 files changed, 95 insertions(+), 5 deletions(-) diff --git a/lua/telescope/builtin.lua b/lua/telescope/builtin.lua index fc63f1f..de56da7 100644 --- a/lua/telescope/builtin.lua +++ b/lua/telescope/builtin.lua @@ -737,4 +737,43 @@ builtin.current_buffer_fuzzy_find = function(opts) }):find() end +builtin.man_pages = function(opts) + opts = opts or {} + + local cmd = opts.man_cmd or "apropos --sections=1 ''" + + local f = assert(io.popen(cmd, 'r')) + local pages = assert(f:read('*a')) + f:close() + + local lines = {} + for s in pages:gmatch("[^\r\n]+") do + table.insert(lines, s) + end + + pickers.new(opts, { + prompt = 'Man', + finder = finders.new_table { + results = lines, + entry_maker = make_entry.gen_from_apropos(opts), + }, + previewer = previewers.man.new(opts), + sorter = sorters.get_generic_fuzzy_sorter(), + attach_mappings = function(prompt_bufnr, map) + local view_manpage = function() + local selection = actions.get_selected_entry(prompt_bufnr) + + actions.close(prompt_bufnr) + print(vim.inspect(selection.value)) + vim.cmd("Man " .. selection.value) + end + + map('i', '', view_manpage) + map('n', '', view_manpage) + + return true + end + }):find() +end + return builtin diff --git a/lua/telescope/make_entry.lua b/lua/telescope/make_entry.lua index 276f149..891d4af 100644 --- a/lua/telescope/make_entry.lua +++ b/lua/telescope/make_entry.lua @@ -403,15 +403,27 @@ function make_entry.gen_from_packages(opts) return function(module_name) local entry = { valid = module_name ~= "", - entry_type = make_entry.types.GENERIC, - value = module_name, ordinal = module_name, - } + } entry.display = make_display(module_name) return entry end end +function make_entry.gen_from_apropos(opts) + opts = opts or {} + + return function(line) + local cmd, _, desc = line:match("^(.*)%s+%((.*)%)%s+%-%s(.*)$") + + return { + value = cmd, + ordinal = cmd, + display = string.format("%-30s : %s", cmd, desc) + } + end +end + return make_entry diff --git a/lua/telescope/previewers.lua b/lua/telescope/previewers.lua index 100a59c..7187549 100644 --- a/lua/telescope/previewers.lua +++ b/lua/telescope/previewers.lua @@ -2,6 +2,7 @@ local context_manager = require('plenary.context_manager') local from_entry = require('telescope.from_entry') local log = require('telescope.log') +local debounce = require('telescope.debounce') local utils = require('telescope.utils') local flatten = vim.tbl_flatten @@ -62,9 +63,9 @@ local with_preview_window = function(status, bufnr, callable) vim.api.nvim_buf_call(bufnr, callable) else return context_manager.with(function() - vim.cmd(string.format("noautocmd call win_gotoid(%s)", status.preview_win)) + vim.cmd(string.format("noautocmd call nvim_set_current_win(%s)", status.preview_win)) coroutine.yield() - vim.cmd(string.format("noautocmd call win_gotoid(%s)", status.prompt_win)) + vim.cmd(string.format("noautocmd call nvim_set_current_win(%s)", status.prompt_win)) end, callable) end end @@ -495,6 +496,44 @@ previewers.nvim_file = defaulter(function(_) } end) +previewers.man = defaulter(function(_) + return previewers.new { + preview_fn = debounce.throttle_leading(function(_, entry, status) + local cmd = entry.value + + local st = {} + st.prompt_win = status.prompt_win + st.preview_win = status.preview_win + + with_preview_window(st, nil, function() + if not vim.api.nvim_win_is_valid(st.preview_win) then + return + end + + local man_value = vim.fn['man#goto_tag'](cmd, '', '') + if #man_value == 0 then + print("No value for:", cmd) + return + end + + local filename = man_value[1].filename + if vim.api.nvim_buf_get_name(0) == filename then + return + end + + local bufnr = vim.api.nvim_create_buf(false, true) + vim.api.nvim_win_set_buf(st.preview_win, bufnr) + vim.api.nvim_command('view ' .. filename) + + vim.api.nvim_buf_set_option(bufnr, 'buftype', 'nofile') + vim.api.nvim_buf_set_option(bufnr, 'bufhidden', 'hide') + vim.api.nvim_buf_set_option(bufnr, 'swapfile', false) + vim.api.nvim_buf_set_option(bufnr, 'buflisted', false) + end) + end, 5) + } +end) + previewers.Previewer = Previewer return previewers