mirror of
https://github.com/tiyn/nvim-docs-view.git
synced 2025-11-13 13:59:46 +01:00
135 lines
3.8 KiB
Lua
135 lines
3.8 KiB
Lua
local M = {}
|
|
local cfg = {}
|
|
local buf, win, prev_win, autocmd
|
|
local get_clients
|
|
|
|
M.update = function()
|
|
if not win or not vim.api.nvim_win_is_valid(win) then
|
|
M.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)
|
|
local md_lines_str = table.concat(md_lines,"\n")
|
|
md_lines = vim.gsplit(md_lines_str, "\n", { trimempty = true })
|
|
if vim.tbl_isempty(md_lines) then
|
|
return
|
|
end
|
|
|
|
vim.api.nvim_buf_set_option(buf, "modifiable", true)
|
|
vim.api.nvim_buf_set_lines(buf, 0, -1, true, {})
|
|
vim.lsp.util.stylize_markdown(buf, md_lines)
|
|
vim.api.nvim_buf_set_option(buf, "modifiable", false)
|
|
end
|
|
end)
|
|
end
|
|
|
|
M.toggle = function()
|
|
if win and vim.api.nvim_win_is_valid(win) then
|
|
vim.api.nvim_win_close(win, false)
|
|
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()
|
|
|
|
if cfg.position == "bottom" then
|
|
vim.api.nvim_command("bel new")
|
|
width = vim.api.nvim_win_get_width(prev_win)
|
|
elseif cfg.position == "top" then
|
|
vim.api.nvim_command("top new")
|
|
width = vim.api.nvim_win_get_height(prev_win)
|
|
elseif cfg.position == "left" then
|
|
vim.api.nvim_command("topleft vnew")
|
|
else
|
|
vim.api.nvim_command("botright vnew")
|
|
end
|
|
|
|
win = vim.api.nvim_get_current_win()
|
|
buf = vim.api.nvim_get_current_buf()
|
|
|
|
if cfg.position == "bottom" or cfg.position == "top" then
|
|
vim.api.nvim_win_set_height(win, math.ceil(height))
|
|
end
|
|
vim.api.nvim_win_set_width(win, math.ceil(width))
|
|
|
|
vim.api.nvim_buf_set_name(buf, "Docs View")
|
|
vim.api.nvim_buf_set_option(buf, "buftype", "nofile")
|
|
vim.api.nvim_buf_set_option(buf, "swapfile", false)
|
|
vim.api.nvim_buf_set_option(buf, "bufhidden", "wipe")
|
|
vim.api.nvim_buf_set_option(buf, "filetype", "nvim-docs-view")
|
|
vim.api.nvim_buf_set_option(buf, "buflisted", false)
|
|
|
|
vim.api.nvim_set_current_win(prev_win)
|
|
|
|
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
|
|
M.update()
|
|
else
|
|
vim.api.nvim_del_autocmd(autocmd)
|
|
buf, win, prev_win, autocmd = nil, nil, nil, nil
|
|
end
|
|
end,
|
|
})
|
|
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.11.0") then
|
|
get_clients = function()
|
|
return vim.lsp.get_clients()
|
|
end
|
|
elseif 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", M.toggle, { nargs = 0 })
|
|
vim.api.nvim_create_user_command("DocsViewUpdate", M.update, { nargs = 0 })
|
|
end
|
|
|
|
return M
|