diff --git a/README.md b/README.md index 818447b..f57a2f1 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,14 @@ return { end, keys = { { 'sad', 'ApidocsOpen', desc = 'Search Api Doc' }, + { + 'sac', + function() + local lang = vim.bo.filetype + require("apidocs").apidocs_search({ restrict_sources = { lang } }) + end, + desc = 'Search Api Doc (restricted to current file type)' + }, }, } ``` diff --git a/lua/apidocs.lua b/lua/apidocs.lua index 9621ff1..d7f9f2f 100644 --- a/lua/apidocs.lua +++ b/lua/apidocs.lua @@ -41,6 +41,15 @@ local function apidocs_open(opts) if opts and opts.restrict_sources then if vim.tbl_contains(opts.restrict_sources, name) then table.insert(installed_docs, name) + else + -- no exact match, check for partial match + -- e.g. "python" -> "python~3.12" + for _, source in ipairs(opts.restrict_sources) do + if name:match("^" .. source .. "~%d+(%.%d+)?$") then + table.insert(installed_docs, name) + break + end + end end else table.insert(installed_docs, name) diff --git a/lua/apidocs/snacks.lua b/lua/apidocs/snacks.lua index 3aa8e9a..b9c7abc 100644 --- a/lua/apidocs/snacks.lua +++ b/lua/apidocs/snacks.lua @@ -26,10 +26,19 @@ local function get_data_dirs(opts) return { data_dir } end local dirs = {} + local install_dirs = vim.fn.readdir(data_dir) for _, source in ipairs(opts.restrict_sources) do local dir = data_dir .. source .. "/" if vim.fn.isdirectory(dir) == 1 then table.insert(dirs, dir) + else + for _, entry in ipairs(install_dirs) do + if entry:match("^" .. source .. "~%d+") then + -- check for partial match + -- e.g. "python" -> "python~3.12" + table.insert(dirs, data_dir .. entry .. "/") + end + end end end return dirs diff --git a/lua/apidocs/telescope.lua b/lua/apidocs/telescope.lua index dc3737e..3c2e00b 100644 --- a/lua/apidocs/telescope.lua +++ b/lua/apidocs/telescope.lua @@ -2,8 +2,8 @@ local common = require("apidocs.common") local install = require("apidocs.install") local function telescope_attach_mappings(prompt_bufnr, map) - local actions = require('telescope.actions') - map('i', '', function(nr) + local actions = require("telescope.actions") + map("i", "", function(nr) actions.close(prompt_bufnr) local entry = require("telescope.actions.state").get_selected_entry(prompt_bufnr) common.open_doc_in_new_window(entry.filename or entry.value) @@ -11,14 +11,14 @@ local function telescope_attach_mappings(prompt_bufnr, map) vim.cmd(":" .. entry.lnum) vim.cmd("norm! zz") end - end, {buffer = true}) + end, { buffer = true }) return true end local function apidocs_open(params, slugs_to_mtimes, candidates) local docs_path = common.data_folder() - local pickers = require "telescope.pickers" - local finders = require "telescope.finders" + local pickers = require("telescope.pickers") + local finders = require("telescope.finders") local previewers = require("telescope.previewers") local conf = require("telescope.config").values @@ -31,75 +31,97 @@ local function apidocs_open(params, slugs_to_mtimes, candidates) } end - pickers.new({}, { - prompt_title = "API docs", - finder = finders.new_table { - results = candidates, - entry_maker = entry_maker - }, - previewer = previewers.new_buffer_previewer({ - -- messy because of the conceal - setup = function(self) - vim.schedule(function() - local winid = self.state.winid - vim.wo[winid].conceallevel = 2 - vim.wo[winid].concealcursor = "n" - local augroup = vim.api.nvim_create_augroup('TelescopeApiDocsResumeConceal', { clear = true }) - vim.api.nvim_create_autocmd({"User"}, { - group = augroup, - pattern = "TelescopeResumePost", - callback = function() - local action_state = require("telescope.actions.state") - local current_picker = action_state.get_current_picker(vim.api.nvim_get_current_buf()) - if current_picker.prompt_title == "API docs" or current_picker.prompt_title == "API docs search" then - local winid = current_picker.all_previewers[1].state.winid - vim.wo[winid].conceallevel = 2 - vim.wo[winid].concealcursor = "n" - end - end - }) - end) - return {} - end, - define_preview = function(self, entry) - common.load_doc_in_buffer(self.state.bufnr, entry.value) - end, - }), - sorter = conf.generic_sorter({}), - attach_mappings = telescope_attach_mappings, - }):find() + pickers + .new({}, { + prompt_title = "API docs", + finder = finders.new_table({ + results = candidates, + entry_maker = entry_maker, + }), + previewer = previewers.new_buffer_previewer({ + -- messy because of the conceal + setup = function(self) + vim.schedule(function() + local winid = self.state.winid + vim.wo[winid].conceallevel = 2 + vim.wo[winid].concealcursor = "n" + local augroup = vim.api.nvim_create_augroup("TelescopeApiDocsResumeConceal", { clear = true }) + vim.api.nvim_create_autocmd({ "User" }, { + group = augroup, + pattern = "TelescopeResumePost", + callback = function() + local action_state = require("telescope.actions.state") + local current_picker = action_state.get_current_picker(vim.api.nvim_get_current_buf()) + if current_picker.prompt_title == "API docs" or current_picker.prompt_title == "API docs search" then + local winid = current_picker.all_previewers[1].state.winid + vim.wo[winid].conceallevel = 2 + vim.wo[winid].concealcursor = "n" + end + end, + }) + end) + return {} + end, + define_preview = function(self, entry) + common.load_doc_in_buffer(self.state.bufnr, entry.value) + end, + }), + sorter = conf.generic_sorter({}), + attach_mappings = telescope_attach_mappings, + }) + :find() +end + +local function get_data_dirs(opts) + local data_dir = common.data_folder() + if not (opts and opts.restrict_sources) then + return { data_dir } + end + local dirs = {} + local install_dirs = vim.fn.readdir(data_dir) + for _, source in ipairs(opts.restrict_sources) do + local dir = data_dir .. source .. "/" + if vim.fn.isdirectory(dir) == 1 then + table.insert(dirs, dir) + else + for _, entry in ipairs(install_dirs) do + if entry:match("^" .. source .. "~%d+") then + -- check for partial match + -- e.g. "python" -> "python~3.12" + table.insert(dirs, data_dir .. entry .. "/") + end + end + end + end + return dirs end local function apidocs_search(opts) local previewers = require("telescope.previewers") - local make_entry = require "telescope.make_entry" + local make_entry = require("telescope.make_entry") local folder = common.data_folder() if opts and opts.source then folder = folder .. opts.source .. "/" end - local search_dirs = {folder} - if opts and opts.restrict_sources then - search_dirs = vim.tbl_map(function(d) return folder .. d end, opts.restrict_sources) - end - + local search_dirs = get_data_dirs(opts) local default_entry_maker = make_entry.gen_from_vimgrep() local function entry_maker(entry) local r = default_entry_maker(entry) - r.display = function(entry) - local entry_components = vim.split(entry.filename:sub(#folder+1), "#") - local source_length = entry_components[1]:find("/") - local hl_group = { - { {0, source_length}, "TelescopeResultsTitle"}, - { {source_length, #entry_components[1]}, "TelescopeResultsMethod" }, - { {#entry_components[1], #entry_components[1] + #(tostring(entry.lnum))+2}, "TelescopeResultsLineNr" }, - } - return string.format("%s:%d: %s", entry_components[1], entry.lnum, entry.text), hl_group - end + r.display = function(entry) + local entry_components = vim.split(entry.filename:sub(#folder + 1), "#") + local source_length = entry_components[1]:find("/") + local hl_group = { + { { 0, source_length }, "TelescopeResultsTitle" }, + { { source_length, #entry_components[1] }, "TelescopeResultsMethod" }, + { { #entry_components[1], #entry_components[1] + #(tostring(entry.lnum)) + 2 }, "TelescopeResultsLineNr" }, + } + return string.format("%s:%d: %s", entry_components[1], entry.lnum, entry.text), hl_group + end return r end - require('telescope.builtin').live_grep({ + require("telescope.builtin").live_grep({ cwd = folder, search_dirs = search_dirs, prompt_title = "API docs search", @@ -111,8 +133,8 @@ local function apidocs_search(opts) local winid = self.state.winid vim.wo[winid].conceallevel = 2 vim.wo[winid].concealcursor = "n" - local augroup = vim.api.nvim_create_augroup('TelescopeApiDocsResumeConceal', { clear = true }) - vim.api.nvim_create_autocmd({"User"}, { + local augroup = vim.api.nvim_create_augroup("TelescopeApiDocsResumeConceal", { clear = true }) + vim.api.nvim_create_autocmd({ "User" }, { group = augroup, pattern = "TelescopeResumePost", callback = function() @@ -123,7 +145,7 @@ local function apidocs_search(opts) vim.wo[winid].conceallevel = 2 vim.wo[winid].concealcursor = "n" end - end + end, }) end) return {} @@ -131,10 +153,10 @@ local function apidocs_search(opts) define_preview = function(self, entry) common.load_doc_in_buffer(self.state.bufnr, entry.filename) - local ns = vim.api.nvim_create_namespace('my_highlights') - vim.api.nvim_buf_set_extmark(self.state.bufnr, ns, entry.lnum-1, 0, { + local ns = vim.api.nvim_create_namespace("my_highlights") + vim.api.nvim_buf_set_extmark(self.state.bufnr, ns, entry.lnum - 1, 0, { end_line = entry.lnum, - hl_group = 'TelescopePreviewMatch', + hl_group = "TelescopePreviewMatch", strict = false, }) vim.schedule(function()