From af35741caf551dd5bf28dbe26400b3b584821539 Mon Sep 17 00:00:00 2001 From: Luckas Date: Wed, 29 Nov 2023 11:45:20 +0300 Subject: [PATCH] feat: extend filetype to docs mappings (#30) Closes #30, #53. --- README.md | 5 +++ lua/nvim-devdocs/config.lua | 1 + lua/nvim-devdocs/filetypes.lua | 26 ++++-------- lua/nvim-devdocs/init.lua | 21 ++++++++-- lua/nvim-devdocs/operations.lua | 73 ++++++++++++++++++--------------- lua/nvim-devdocs/pickers.lua | 6 ++- 6 files changed, 77 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 13d9db5..a4539ab 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,11 @@ Here is the default configuration: { dir_path = vim.fn.stdpath("data") .. "/devdocs", -- installation directory telescope = {}, -- passed to the telescope picker + filetypes = { + -- extends the filetype to docs mappings used by the `DevdocsOpenCurrent` command, the version doesn't have to be specified + -- scss = "sass", + -- javascript = { "node", "javascript" } + }, float_win = { -- passed to nvim_open_win(), see :h api-floatwin relative = "editor", height = 25, diff --git a/lua/nvim-devdocs/config.lua b/lua/nvim-devdocs/config.lua index 97401df..7d008f2 100644 --- a/lua/nvim-devdocs/config.lua +++ b/lua/nvim-devdocs/config.lua @@ -6,6 +6,7 @@ local path = require("plenary.path") local default = { dir_path = vim.fn.stdpath("data") .. "/devdocs", telescope = {}, + filetypes = {}, float_win = { relative = "editor", height = 25, diff --git a/lua/nvim-devdocs/filetypes.lua b/lua/nvim-devdocs/filetypes.lua index edb2c01..be744c9 100644 --- a/lua/nvim-devdocs/filetypes.lua +++ b/lua/nvim-devdocs/filetypes.lua @@ -1,21 +1,13 @@ local M = { - ["sh"] = "bash", - ["lua"] = "lua-5.4", - ["vue"] = "vue-3", - ["dart"] = "dart-2", - ["ruby"] = "ruby-3.2", - ["twig"] = "twig-3", - ["less"] = "less-4", - ["scss"] = "sass", - ["make"] = "gnu_make", - ["dockerfile"] = "docker", - ["cjs"] = "node", - ["mjs"] = "node", - ["json"] = "jq", - ["yaml"] = "ansible", - ["python"] = "python-3.11", - ["javascriptreact"] = "react", - ["typescriptreact"] = "react", + sh = "bash", + scss = "sass", + make = "gnu_make", + dockerfile = "docker", + javascript = { "node", "javascript" }, + json = "jq", + yaml = "ansible", + javascriptreact = { "javascript", "react" }, + typescriptreact = { "typescript", "react" }, } return M diff --git a/lua/nvim-devdocs/init.lua b/lua/nvim-devdocs/init.lua index 4178833..75b0ede 100644 --- a/lua/nvim-devdocs/init.lua +++ b/lua/nvim-devdocs/init.lua @@ -28,8 +28,9 @@ end M.open_doc = function(args, float) if vim.tbl_isempty(args.fargs) then - local entries = operations.get_all_entries() - pickers.open_picker(entries, float) + local installed = list.get_installed_alias() + local entries = operations.get_entries(installed) + pickers.open_picker(entries or {}, float) else local alias = args.fargs[1] pickers.open_picker_alias(alias, float) @@ -40,8 +41,20 @@ M.open_doc_float = function(args) M.open_doc(args, true) end M.open_doc_current_file = function(float) local filetype = vim.bo.filetype - local alias = filetypes[filetype] or filetype - pickers.open_picker_alias(alias, float) + local names = config.options.filetypes[filetype] or filetypes[filetype] or filetype + + if type(names) == "string" then names = { names } end + + local docs = vim.tbl_flatten( + vim.tbl_map(function(value) return operations.get_doc_variants(value) end, names) + ) + local entries = operations.get_entries(docs) + + if entries and not vim.tbl_isempty(entries) then + pickers.open_picker(entries, float) + else + notify.log_err("No documentation found for the current filetype") + end end M.update = function(args) diff --git a/lua/nvim-devdocs/operations.lua b/lua/nvim-devdocs/operations.lua index e50909f..da1d7b4 100644 --- a/lua/nvim-devdocs/operations.lua +++ b/lua/nvim-devdocs/operations.lua @@ -148,44 +148,34 @@ M.uninstall = function(alias) end end ----@param alias string +---@param aliases string[] ---@return DocEntry[] | nil -M.get_entries = function(alias) - local installed = list.get_installed_alias() - local is_installed = vim.tbl_contains(installed, alias) +M.get_entries = function(aliases) + if not INDEX_PATH:exists() then return end - if not INDEX_PATH:exists() or not is_installed then return end + local entries = {} + local index = vim.fn.json_decode(INDEX_PATH:read()) - local index_parsed = vim.fn.json_decode(INDEX_PATH:read()) - local entries = index_parsed[alias].entries + for _, alias in pairs(aliases) do + if index[alias] then + local current_entries = index[alias].entries - for key, _ in ipairs(entries) do - entries[key].alias = alias - end + for idx, doc_entry in ipairs(current_entries) do + local next_path = nil + local entries_count = #current_entries - return entries -end + if idx < entries_count then next_path = current_entries[idx + 1].path end ----@return DocEntry[] -M.get_all_entries = function() - if not INDEX_PATH:exists() then return {} end + local entry = { + name = doc_entry.name, + path = doc_entry.path, + link = doc_entry.link, + alias = alias, + next_path = next_path, + } - local entries = {} - local index_parsed = vim.fn.json_decode(INDEX_PATH:read()) - - for alias, index in pairs(index_parsed) do - local entries_count = #index.entries - for idx, doc_entry in ipairs(index.entries) do - local next_path = nil - if idx < entries_count then next_path = index.entries[idx + 1].path end - local entry = { - name = doc_entry.name, - path = doc_entry.path, - link = doc_entry.link, - alias = alias, - next_path = next_path, - } - table.insert(entries, entry) + table.insert(entries, entry) + end end end @@ -323,7 +313,7 @@ M.keywordprg = function(keyword) local alias = state.get("current_doc") local float = state.get("last_mode") == "float" local bufnr = vim.api.nvim_create_buf(false, false) - local entries = M.get_entries(alias) + local entries = M.get_entries({ alias }) local entry local function callback(filtered_lines) @@ -344,4 +334,23 @@ M.keywordprg = function(keyword) if not entry then notify.log("No documentation found for " .. keyword) end end +---@param name string +---@return string[] +M.get_doc_variants = function(name) + if not REGISTERY_PATH:exists() then return {} end + + local variants = {} + ---@type RegisteryEntry[] + local entries = vim.fn.json_decode(REGISTERY_PATH:read()) + + for _, entry in pairs(entries) do + if vim.startswith(entry.slug, name) then + local alias = entry.slug:gsub("~", "-") + table.insert(variants, alias) + end + end + + return variants +end + return M diff --git a/lua/nvim-devdocs/pickers.lua b/lua/nvim-devdocs/pickers.lua index e684ab0..d3edf2c 100644 --- a/lua/nvim-devdocs/pickers.lua +++ b/lua/nvim-devdocs/pickers.lua @@ -194,9 +194,11 @@ end ---@param alias string ---@param float? boolean M.open_picker_alias = function(alias, float) - local entries = operations.get_entries(alias) + local entries = operations.get_entries({ alias }) - if not entries then + if not entries then return end + + if vim.tbl_isempty(entries) then notify.log_err(alias .. " documentation is not installed") else plugin_state.set("current_doc", alias)