From 601d7f6a2e399226a669fd2a73f7da77726cb32f Mon Sep 17 00:00:00 2001 From: amrbashir Date: Sun, 12 Feb 2023 00:41:55 +0200 Subject: [PATCH] feat: add update_mode option and `:DocsViewUpdate`, closes #6 --- README.md | 29 ++++++++++-- lua/docs-view.lua | 116 ++++++++++++++++++++++++++-------------------- 2 files changed, 93 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 9339278..85450cc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # nvim-docs-view A neovim plugin to display lsp hover documentation in a side panel. + > Inspired by the VSCode extension [Docs View](https://marketplace.visualstudio.com/items?itemName=bierner.docs-view). doc-view-example @@ -36,10 +37,32 @@ lua << EOF EOF ``` -## Usage +## Options -Use `:DocsViewToggle` to open/close the docs view panel +- `position`: + - description: Determines where to open the docs view panel. + - type: `string` + - default: `right` + - possible: `right` | `left` | `top` | `bottom` +- `height`: + - description: Hieght of the docs view panel when position is set to `top` or `bottom` + - type: `number` + - default: `10` +- `width`: + - description: Width of the docs view panel when position is set to `right` or `left` + - type: `number` + - default: `60` +- `update_mode`: + - description: Determines the mechanism used to update the docs view panel content. If `auto`, the content will update upon cursor move. If `manual`, the content will only update once `:DocsViewUpdate` is called. + - type: `string` + - default: `auto` + - possible: `auto` | `manual` + +## Commands + +- `:DocsViewToggle` to open/close the docs view panel. +- `:DocsViewUpdate` to manually update the docs view panel (will open the docs view panel if necessary). ## LICENSE -[MIT](./LICENSE) © Amr Bashir \ No newline at end of file +[MIT](./LICENSE) © Amr Bashir diff --git a/lua/docs-view.lua b/lua/docs-view.lua index a77f779..37112ca 100644 --- a/lua/docs-view.lua +++ b/lua/docs-view.lua @@ -6,11 +6,17 @@ local get_clients local function toggle() if win and vim.api.nvim_win_is_valid(win) then vim.api.nvim_win_close(win, false) - vim.api.nvim_del_autocmd(autocmd) + if autocmd then + vim.api.nvim_del_autocmd(autocmd) + end buf, win, prev_win, autocmd = nil, nil, nil, nil else local height = cfg["height"] local width = cfg["width"] + local update_mode = cfg["update_mode"] + if update_mode ~= "manual" then + update_mode = "auto" + end prev_win = vim.api.nvim_get_current_win() @@ -43,68 +49,80 @@ local function toggle() vim.api.nvim_set_current_win(prev_win) - if vim.fn.has("nvim-0.8.0") then - get_clients = function() - return vim.lsp.get_active_clients() - end - else - get_clients = function() - return vim.lsp.buf_get_clients(0) - end + if update_mode == "auto" then + autocmd = vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { + pattern = "*", + callback = function() + if win and vim.api.nvim_win_is_valid(win) then + update() + else + vim.api.nvim_del_autocmd(autocmd) + buf, win, prev_win, autocmd = nil, nil, nil, nil + end + end, + }) end - - autocmd = vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { - pattern = "*", - callback = function() - if win and vim.api.nvim_win_is_valid(win) then - local clients = get_clients() - local gotHover = false - for i = 1, #clients do - if clients[i].supports_method("textDocument/hover") then - gotHover = true - break - end - end - if not gotHover then - return - end - - local l, c = unpack(vim.api.nvim_win_get_cursor(0)) - vim.lsp.buf_request(0, "textDocument/hover", { - textDocument = { uri = "file://" .. vim.api.nvim_buf_get_name(0) }, - position = { line = l - 1, character = c }, - }, function(err, result, ctx, config) - if win and vim.api.nvim_win_is_valid(win) and result and result.contents then - local md_lines = vim.lsp.util.convert_input_to_markdown_lines(result.contents) - md_lines = vim.lsp.util.trim_empty_lines(md_lines) - if vim.tbl_isempty(md_lines) then - return - end - - vim.api.nvim_buf_set_option(buf, "modifiable", true) - vim.lsp.util.stylize_markdown(buf, md_lines) - vim.api.nvim_buf_set_option(buf, "modifiable", false) - end - end) - else - vim.api.nvim_del_autocmd(autocmd) - buf, win, prev_win, autocmd = nil, nil, nil, nil - end - end, - }) end end +local function update() + if not win or not vim.api.nvim_win_is_valid(win) then + toggle() + end + + local clients = get_clients() + local gotHover = false + for i = 1, #clients do + if clients[i].supports_method("textDocument/hover") then + gotHover = true + break + end + end + if not gotHover then + return + end + + local l, c = unpack(vim.api.nvim_win_get_cursor(0)) + vim.lsp.buf_request(0, "textDocument/hover", { + textDocument = { uri = "file://" .. vim.api.nvim_buf_get_name(0) }, + position = { line = l - 1, character = c }, + }, function(err, result, ctx, config) + if win and vim.api.nvim_win_is_valid(win) and result and result.contents then + local md_lines = vim.lsp.util.convert_input_to_markdown_lines(result.contents) + md_lines = vim.lsp.util.trim_empty_lines(md_lines) + if vim.tbl_isempty(md_lines) then + return + end + + vim.api.nvim_buf_set_option(buf, "modifiable", true) + vim.lsp.util.stylize_markdown(buf, md_lines) + vim.api.nvim_buf_set_option(buf, "modifiable", false) + end + end) +end + M.setup = function(user_cfg) local default_cfg = { position = "right", height = 10, width = 60, + update_mode = "auto", } cfg = vim.tbl_extend("force", default_cfg, user_cfg) + if vim.fn.has("nvim-0.8.0") then + get_clients = function() + return vim.lsp.get_active_clients() + end + else + get_clients = function() + return vim.lsp.buf_get_clients(0) + end + end + vim.api.nvim_create_user_command("DocsViewToggle", toggle, { nargs = 0 }) + vim.api.nvim_create_user_command("DocsViewUpdate", update, { nargs = 0 }) end return M