aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/nvim/.config
diff options
context:
space:
mode:
Diffstat (limited to 'nvim/.config')
-rw-r--r--nvim/.config/nvim/lua/tobyvin/keymaps.lua9
-rw-r--r--nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua27
-rw-r--r--nvim/.config/nvim/lua/tobyvin/plugins/dap/hover.lua25
-rw-r--r--nvim/.config/nvim/lua/tobyvin/plugins/rust-tools.lua6
-rw-r--r--nvim/.config/nvim/lua/tobyvin/utils/documentation.lua119
-rw-r--r--nvim/.config/nvim/lua/tobyvin/utils/hover.lua10
6 files changed, 152 insertions, 44 deletions
diff --git a/nvim/.config/nvim/lua/tobyvin/keymaps.lua b/nvim/.config/nvim/lua/tobyvin/keymaps.lua
index 951613b..57a7cd3 100644
--- a/nvim/.config/nvim/lua/tobyvin/keymaps.lua
+++ b/nvim/.config/nvim/lua/tobyvin/keymaps.lua
@@ -10,7 +10,14 @@ local hover = function()
return "K"
end
-vim.keymap.set("n", "gk", utils.documentation.open, { desc = "documentation" })
+local external_docs = function()
+ if utils.documentation.open() then
+ return "<Ignore>"
+ end
+ return "gx"
+end
+
+vim.keymap.set("n", "gx", external_docs, { desc = "external_docs", expr = true })
vim.keymap.set("n", "K", hover, { expr = true, desc = "hover" })
vim.keymap.set("n", "<C-u>", "<C-u>zz", { desc = "up half page and center" })
vim.keymap.set("n", "<C-d>", "<C-d>zz", { desc = "down half page and center" })
diff --git a/nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua b/nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua
index 6785715..deb2d53 100644
--- a/nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua
+++ b/nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua
@@ -1,17 +1,33 @@
local utils = require("tobyvin.utils")
-local location_handler = vim.lsp.handlers["textDocument/definition"]
-local definition_handler = function(err, result, ctx, config)
+function vim.lsp.buf.external_docs()
+ ---@diagnostic disable-next-line: missing-parameter
+ local params = vim.lsp.util.make_position_params()
+ return vim.lsp.buf_request(0, "experimental/externalDocs", params)
+end
+
+local definition_handler = vim.lsp.handlers["textDocument/definition"]
+vim.lsp.handlers["textDocument/definition"] = function(err, result, ctx, config)
if not result or vim.tbl_isempty(result) then
vim.notify("No location found", vim.log.levels.INFO, { title = "[LSP] " .. ctx.method })
elseif vim.tbl_islist(result) then
result = result[1]
end
- location_handler(err, result, ctx, config)
+ return definition_handler(err, result, ctx, config)
+end
+
+local external_docs_handler = vim.lsp.handlers["experimental/externalDocs"]
+vim.lsp.handlers["experimental/externalDocs"] = function(err, result, ctx, config)
+ if external_docs_handler then
+ result, err = external_docs_handler(err, result, ctx, config)
+ elseif result then
+ vim.fn["netrw#BrowseX"](result, 0)
+ end
end
-local show_message = function(_, result, ctx)
+---@diagnostic disable-next-line: duplicate-set-field
+vim.lsp.handlers["window/showMessage"] = function(_, result, ctx)
vim.notify(string.format("%s", result.message), 5 - result.type, {
title = string.format("[LSP] %s", vim.lsp.get_client_by_id(ctx.client_id)),
})
@@ -20,8 +36,6 @@ end
local hover_ops = { border = "single" }
vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, hover_ops)
vim.lsp.handlers["textDocument/signatureHelp"] = vim.lsp.with(vim.lsp.handlers.signature_help, hover_ops)
-vim.lsp.handlers["textDocument/definition"] = definition_handler
-vim.lsp.handlers["window/showMessage"] = show_message
vim.api.nvim_create_autocmd("LspAttach", {
group = vim.api.nvim_create_augroup("tobyvin_lsp_handlers", { clear = true }),
@@ -34,6 +48,7 @@ vim.api.nvim_create_autocmd("LspAttach", {
end
utils.hover.register(vim.lsp.buf.hover, { desc = "lsp", buffer = bufnr, priority = 1 })
+ utils.hover.register(vim.lsp.buf.external_docs, { desc = "lsp", buffer = bufnr, priority = 1 })
vim.keymap.set("n", "<C-k>", vim.lsp.buf.signature_help, { desc = "signature help", buffer = bufnr })
vim.keymap.set("n", "gd", vim.lsp.buf.definition, { desc = "definition", buffer = bufnr })
diff --git a/nvim/.config/nvim/lua/tobyvin/plugins/dap/hover.lua b/nvim/.config/nvim/lua/tobyvin/plugins/dap/hover.lua
index 214bcdd..7eb0c58 100644
--- a/nvim/.config/nvim/lua/tobyvin/plugins/dap/hover.lua
+++ b/nvim/.config/nvim/lua/tobyvin/plugins/dap/hover.lua
@@ -1,15 +1,6 @@
local utils = require("tobyvin.utils")
local M = {}
-M.hover = function()
- local widgets = require("dap.ui.widgets")
- if M.hover_available() then
- widgets.hover()
- else
- utils.hover.open()
- end
-end
-
M.hover_available = function()
local session = require("dap").session()
if not session then
@@ -34,24 +25,22 @@ M.hover_available = function()
end
M.setup = function()
+ local dap_hover_id
vim.api.nvim_create_autocmd("User", {
pattern = "DapAttach",
callback = function()
- -- TODO: figure out why calling dap.ui.widgets.hover from util.hover is causing error
- -- vim.g.dap_hover_id = utils.hover.register(M.hover, {
- -- enabled = M.hover_available,
- -- desc = "dap",
- -- priority = 20,
- -- })
- vim.keymap.set("n", "K", M.hover, { desc = "hover" })
+ dap_hover_id = utils.hover.register(require("dap.ui.widgets").hover, {
+ desc = "lsp",
+ enabled = M.hover_available,
+ priority = 20,
+ })
end,
})
vim.api.nvim_create_autocmd("User", {
pattern = "DapDetach",
callback = function()
- -- utils.hover.unregister(vim.g.dap_hover_id)
- vim.keymap.set("n", "K", utils.hover.open, { desc = "hover" })
+ utils.hover.unregister(dap_hover_id)
end,
})
end
diff --git a/nvim/.config/nvim/lua/tobyvin/plugins/rust-tools.lua b/nvim/.config/nvim/lua/tobyvin/plugins/rust-tools.lua
index b602a31..c108e8e 100644
--- a/nvim/.config/nvim/lua/tobyvin/plugins/rust-tools.lua
+++ b/nvim/.config/nvim/lua/tobyvin/plugins/rust-tools.lua
@@ -33,9 +33,7 @@ function M.init()
local runnables = require("rust-tools").runnables.runnables
local debuggables = require("rust-tools").debuggables.debuggables
local open_cargo_toml = require("rust-tools").open_cargo_toml.open_cargo_toml
- local external_docs = require("rust-tools").external_docs.open_external_docs
local expand_macro = require("rust-tools").expand_macro.expand_macro
- local hover_actions = require("rust-tools").hover_actions.hover_actions
local ssr = require("rust-tools").ssr.ssr
vim.keymap.set("n", "<leader>dd", debuggables, { desc = "debug", buffer = bufnr })
@@ -44,9 +42,7 @@ function M.init()
vim.keymap.set("n", "<leader>le", expand_macro, { desc = "expand macro", buffer = bufnr })
vim.keymap.set("n", "<leader>rs", ssr, { desc = "ssr", buffer = bufnr })
- local utils = require("tobyvin.utils")
- utils.documentation.register("rust", external_docs)
- utils.hover.register(hover_actions, { desc = "rust-tools hover actions", buffer = bufnr, priority = 10 })
+ vim.lsp.handlers["textDocument/hover"] = require("rust-tools").hover_actions.hover_actions.handler
end,
})
end
diff --git a/nvim/.config/nvim/lua/tobyvin/utils/documentation.lua b/nvim/.config/nvim/lua/tobyvin/utils/documentation.lua
index 855b495..683e0b6 100644
--- a/nvim/.config/nvim/lua/tobyvin/utils/documentation.lua
+++ b/nvim/.config/nvim/lua/tobyvin/utils/documentation.lua
@@ -1,26 +1,117 @@
local M = {}
-M.sources = {
- vim = function()
- vim.cmd("help " .. vim.fn.expand("<cword>"))
- end,
- help = function()
- vim.cmd("Man " .. vim.fn.expand("<cword>"))
+---@type Provider[]
+vim.g.doc_providers = {}
+
+local default_opts = {
+ enabled = function()
+ return true
end,
}
-M.register = function(filetypes, callback)
- for _, filetype in ipairs(vim.tbl_flatten({ filetypes })) do
- M.sources[filetype] = callback
+---@param buffer number?
+---@return Provider[]
+local get_providers = function(buffer)
+ if buffer then
+ return vim.F.if_nil(vim.b[buffer].doc_providers, {})
+ else
+ return vim.g.doc_providers
+ end
+end
+
+---@param buffer number?
+---@param providers Provider[]
+local set_providers = function(buffer, providers)
+ if buffer == nil then
+ vim.g.doc_providers = providers
+ else
+ vim.b[buffer].doc_providers = providers
end
end
-M.open = function()
- local filetype = vim.bo.filetype
- if vim.tbl_contains(vim.tbl_keys(M.sources), filetype) then
- M.sources[filetype]()
+---@param a Provider
+---@param b Provider
+---@return boolean
+local sort_providers = function(a, b)
+ if a.opts.priority and b.opts.priority then
+ return a.opts.priority > b.opts.priority
else
- vim.notify("[Utils] Documentation not available", vim.log.levels.ERROR)
+ return not b.opts.priority
+ end
+end
+
+---@param buffer number
+---@return Provider[]
+M.buf_providers = function(buffer)
+ local providers = {}
+ if vim.api.nvim_buf_is_valid(buffer) and type(vim.b[buffer].doc_providers) == "table" then
+ vim.list_extend(providers, get_providers(buffer))
+ end
+ vim.list_extend(providers, get_providers())
+ table.sort(providers, sort_providers)
+ return providers
+end
+
+---@param handler ProviderHandler
+---@param opts ProviderOpts
+---@return ProviderId
+M.register = function(handler, opts)
+ ---@type ProviderOpts
+ opts = vim.F.if_nil(opts, {})
+ opts = vim.tbl_extend("keep", opts, default_opts)
+
+ ---@type Provider
+ local provider = { handler = handler, opts = opts }
+
+ local providers = get_providers(provider.opts.buffer)
+ local id
+
+ if #providers > 0 and provider.opts.priority then
+ for i, p in ipairs(providers) do
+ if not p.opts.priority or p.opts.priority < provider.opts.priority or i == #providers then
+ table.insert(providers, i, provider)
+ id = i
+ break
+ end
+ end
+ else
+ table.insert(providers, provider)
+ id = #providers
+ end
+
+ set_providers(provider.opts.buffer, providers)
+ return id
+end
+
+---@param id ProviderId
+---@param buffer number?
+M.unregister = function(id, buffer)
+ local providers = get_providers(buffer)
+
+ local provider = table.remove(providers, id)
+
+ set_providers(buffer, providers)
+ return provider
+end
+
+--- Returns `true` if a provider successfully handled the request, otherwise returns `false`.
+-- Example usage:
+-- ```lua
+-- vim.keymap.set("n", "gx", function()
+-- if utils.documentation.open() then
+-- return "<Ignore>"
+-- end
+-- return "gx"
+-- end, { desc = "documentation", expr = true })
+-- ```
+---@param buffer number?
+M.open = function(buffer)
+ buffer = buffer or vim.api.nvim_get_current_buf()
+ local providers = M.buf_providers(buffer)
+ for _, provider in ipairs(providers) do
+ if provider.opts.enabled and provider.opts.enabled() and not provider.handler() then
+ return true
+ end
end
end
diff --git a/nvim/.config/nvim/lua/tobyvin/utils/hover.lua b/nvim/.config/nvim/lua/tobyvin/utils/hover.lua
index 3b967eb..47e2e53 100644
--- a/nvim/.config/nvim/lua/tobyvin/utils/hover.lua
+++ b/nvim/.config/nvim/lua/tobyvin/utils/hover.lua
@@ -107,6 +107,16 @@ M.unregister = function(id, buffer)
return provider
end
+--- Returns `true` if a provider successfully handled the request, otherwise returns `false`.
+-- Example usage:
+-- ```lua
+-- vim.keymap.set("n", "K", function()
+-- if utils.hover.open() then
+-- return "<Ignore>"
+-- end
+-- return "K"
+-- end, { desc = "hover", expr = true }
+-- ```
---@param buffer number?
M.open = function(buffer)
buffer = buffer or vim.api.nvim_get_current_buf()