diff --git a/lua/symbols-outline/preview.lua b/lua/symbols-outline/preview.lua index 8399976..2ad4885 100644 --- a/lua/symbols-outline/preview.lua +++ b/lua/symbols-outline/preview.lua @@ -1,228 +1,236 @@ local vim = vim -local main = require('symbols-outline') -local config = require('symbols-outline.config') -local buf_request = require('symbols-outline.utils.lsp_utils').request +local main = require("symbols-outline") +local config = require("symbols-outline.config") +local buf_request = require("symbols-outline.utils.lsp_utils").request local M = {} local state = { - preview_buf = nil, - preview_win = nil, - hover_buf = nil, - hover_win = nil + preview_buf = nil, + preview_win = nil, + hover_buf = nil, + hover_win = nil, } local function is_current_win_outline() - local curwin = vim.api.nvim_get_current_win() - return curwin == main.state.outline_win + local curwin = vim.api.nvim_get_current_win() + return curwin == main.state.outline_win end local function has_code_win() - local isWinValid = vim.api.nvim_win_is_valid(main.state.code_win) - if not isWinValid then return false end - local bufnr = vim.api.nvim_win_get_buf(main.state.code_win) - local isBufValid = vim.api.nvim_buf_is_valid(bufnr) - return isBufValid + local isWinValid = vim.api.nvim_win_is_valid(main.state.code_win) + if not isWinValid then + return false + end + local bufnr = vim.api.nvim_win_get_buf(main.state.code_win) + local isBufValid = vim.api.nvim_buf_is_valid(bufnr) + return isBufValid end local function get_offset() - local outline_winnr = main.state.outline_win - local width = 53 - local height = 0 + local outline_winnr = main.state.outline_win + local width = 53 + local height = 0 - if config.has_numbers() then - width = width + 4; - end + if config.has_numbers() then + width = width + 4 + end - if config.options.position == 'right' then - width = 0 - width - else - width = vim.api.nvim_win_get_width(outline_winnr) + 1 - end - return {height, width} + if config.options.position == "right" then + width = 0 - width + else + width = vim.api.nvim_win_get_width(outline_winnr) + 1 + end + return { height, width } end local function get_height() - local uis = vim.api.nvim_list_uis() - return math.ceil(uis[1].height / 3) + local uis = vim.api.nvim_list_uis() + return math.ceil(uis[1].height / 3) end local function get_hovered_node() - local hovered_line = vim.api.nvim_win_get_cursor(main.state.outline_win)[1] - local node = main.state.flattened_outline_items[hovered_line] - return node + local hovered_line = vim.api.nvim_win_get_cursor(main.state.outline_win)[1] + local node = main.state.flattened_outline_items[hovered_line] + return node end local function update_preview(code_buf) - code_buf = code_buf or vim.api.nvim_win_get_buf(main.state.code_win) + code_buf = code_buf or vim.api.nvim_win_get_buf(main.state.code_win) - local node = get_hovered_node() - if not node then return end - local lines = vim.api.nvim_buf_get_lines(code_buf, 0, -1, false) + local node = get_hovered_node() + if not node then + return + end + local lines = vim.api.nvim_buf_get_lines(code_buf, 0, -1, false) - if state.preview_buf ~= nil then - vim.api.nvim_buf_set_lines(state.preview_buf, 0, -1, 0, lines) - vim.api.nvim_win_set_cursor(state.preview_win, - {node.line + 1, node.character}) - end + if state.preview_buf ~= nil then + vim.api.nvim_buf_set_lines(state.preview_buf, 0, -1, 0, lines) + vim.api.nvim_win_set_cursor(state.preview_win, { node.line + 1, node.character }) + end end local function setup_preview_buf() - local code_buf = vim.api.nvim_win_get_buf(main.state.code_win) - local ft = vim.api.nvim_buf_get_option(code_buf, "filetype") + local code_buf = vim.api.nvim_win_get_buf(main.state.code_win) + local ft = vim.api.nvim_buf_get_option(code_buf, "filetype") - local function treesitter_attach() - local ts_highlight = require('nvim-treesitter.highlight') + local function treesitter_attach() + local ts_highlight = require("nvim-treesitter.highlight") - ts_highlight.attach(state.preview_buf, ft) - end + ts_highlight.attach(state.preview_buf, ft) + end - -- user might not have tree sitter installed - pcall(treesitter_attach) + -- user might not have tree sitter installed + pcall(treesitter_attach) - vim.api.nvim_buf_set_option(state.preview_buf, "syntax", ft) - vim.api.nvim_buf_set_option(state.preview_buf, "bufhidden", "delete") - vim.api.nvim_win_set_option(state.preview_win, "cursorline", true) - update_preview(code_buf) + vim.api.nvim_buf_set_option(state.preview_buf, "syntax", ft) + vim.api.nvim_buf_set_option(state.preview_buf, "bufhidden", "delete") + vim.api.nvim_win_set_option(state.preview_win, "cursorline", true) + update_preview(code_buf) end local function get_hover_params(node, winnr) - local bufnr = vim.api.nvim_win_get_buf(winnr) - local uri = vim.uri_from_bufnr(bufnr) + local bufnr = vim.api.nvim_win_get_buf(winnr) + local uri = vim.uri_from_bufnr(bufnr) - return { - textDocument = {uri = uri}, - position = {line = node.line, character = node.character}, - bufnr = bufnr - } + return { + textDocument = { uri = uri }, + position = { line = node.line, character = node.character }, + bufnr = bufnr, + } end local function update_hover() - if not has_code_win() then return end + if not has_code_win() then + return + end - local node = get_hovered_node() - if not node then return end - local params = get_hover_params(node, main.state.code_win) + local node = get_hovered_node() + if not node then + return + end - buf_request(params.bufnr, "textDocument/hover", params, - function(err, result) - if err then print(vim.inspect(err)) end - local markdown_lines = {} - if result ~= nil then - markdown_lines = vim.lsp.util.convert_input_to_markdown_lines( - result.contents) - end - markdown_lines = vim.lsp.util.trim_empty_lines(markdown_lines) - if vim.tbl_isempty(markdown_lines) then - markdown_lines = {"###No info available!"} - end + local provider = _G._symbols_outline_current_provider + local params = get_hover_params(node, main.state.code_win) - markdown_lines = vim.lsp.util.stylize_markdown(state.hover_buf, markdown_lines, {}) + provider.hover_info(params.bufnr, params, function(err, result) + if err then + print(vim.inspect(err)) + end + local markdown_lines = {} + if result ~= nil then + markdown_lines = vim.lsp.util.convert_input_to_markdown_lines(result.contents) + end + markdown_lines = vim.lsp.util.trim_empty_lines(markdown_lines) + if vim.tbl_isempty(markdown_lines) then + markdown_lines = { "###No info available!" } + end - if state.hover_buf ~= nil then - vim.api.nvim_buf_set_lines(state.hover_buf, 0, -1, 0, markdown_lines) - end - end) + markdown_lines = vim.lsp.util.stylize_markdown(state.hover_buf, markdown_lines, {}) + + if state.hover_buf ~= nil then + vim.api.nvim_buf_set_lines(state.hover_buf, 0, -1, 0, markdown_lines) + end + end) end local function setup_hover_buf() - if not has_code_win() then return end - local code_buf = vim.api.nvim_win_get_buf(main.state.code_win) - local ft = vim.api.nvim_buf_get_option(code_buf, "filetype") - vim.api.nvim_buf_set_option(state.hover_buf, "syntax", ft) - vim.api.nvim_buf_set_option(state.hover_buf, "bufhidden", "delete") - vim.api.nvim_win_set_option(state.hover_win, "wrap", true) - vim.api.nvim_win_set_option(state.hover_win, "cursorline", false) - update_hover() + if not has_code_win() then + return + end + local code_buf = vim.api.nvim_win_get_buf(main.state.code_win) + local ft = vim.api.nvim_buf_get_option(code_buf, "filetype") + vim.api.nvim_buf_set_option(state.hover_buf, "syntax", ft) + vim.api.nvim_buf_set_option(state.hover_buf, "bufhidden", "delete") + vim.api.nvim_win_set_option(state.hover_win, "wrap", true) + vim.api.nvim_win_set_option(state.hover_win, "cursorline", false) + update_hover() end local function set_bg_hl() - local winhi = "Normal:" .. config.options.preview_bg_highlight - vim.api.nvim_win_set_option(state.preview_win, "winhighlight", winhi) - vim.api.nvim_win_set_option(state.hover_win, "winhighlight", winhi) + local winhi = "Normal:" .. config.options.preview_bg_highlight + vim.api.nvim_win_set_option(state.preview_win, "winhighlight", winhi) + vim.api.nvim_win_set_option(state.hover_win, "winhighlight", winhi) end local function show_preview() - if state.preview_win == nil and state.preview_buf == nil then - state.preview_buf = vim.api.nvim_create_buf(false, true) - vim.api.nvim_buf_attach(state.preview_buf, false, { - on_detach = function() - state.preview_buf = nil - state.preview_win = nil - end - }) - local offsets = get_offset() - state.preview_win = vim.api.nvim_open_win(state.preview_buf, false, { - relative = 'win', - width = 50, - height = get_height(), - bufpos = {0, 0}, - row = offsets[1], - col = offsets[2], - border = 'single' - }) - setup_preview_buf() - else - update_preview() - end + if state.preview_win == nil and state.preview_buf == nil then + state.preview_buf = vim.api.nvim_create_buf(false, true) + vim.api.nvim_buf_attach(state.preview_buf, false, { + on_detach = function() + state.preview_buf = nil + state.preview_win = nil + end, + }) + local offsets = get_offset() + state.preview_win = vim.api.nvim_open_win(state.preview_buf, false, { + relative = "win", + width = 50, + height = get_height(), + bufpos = { 0, 0 }, + row = offsets[1], + col = offsets[2], + border = "single", + }) + setup_preview_buf() + else + update_preview() + end end local function show_hover() - if state.hover_win == nil and state.hover_buf == nil then - state.hover_buf = vim.api.nvim_create_buf(false, true) - vim.api.nvim_buf_attach(state.hover_buf, false, { - on_detach = function() - state.hover_buf = nil - state.hover_win = nil - end - }) - local offsets = get_offset() - local height = get_height() - state.hover_win = vim.api.nvim_open_win(state.hover_buf, false, { - relative = 'win', - width = 50, - height = height, - bufpos = {0, 0}, - row = offsets[1] + height + 2, - col = offsets[2], - border = 'single' - }) - setup_hover_buf() - else - update_hover() - end + if state.hover_win == nil and state.hover_buf == nil then + state.hover_buf = vim.api.nvim_create_buf(false, true) + vim.api.nvim_buf_attach(state.hover_buf, false, { + on_detach = function() + state.hover_buf = nil + state.hover_win = nil + end, + }) + local offsets = get_offset() + local height = get_height() + state.hover_win = vim.api.nvim_open_win(state.hover_buf, false, { + relative = "win", + width = 50, + height = height, + bufpos = { 0, 0 }, + row = offsets[1] + height + 2, + col = offsets[2], + border = "single", + }) + setup_hover_buf() + else + update_hover() + end end function M.show() - if not is_current_win_outline() or - #vim.api.nvim_list_wins() < 2 then - return - end + if not is_current_win_outline() or #vim.api.nvim_list_wins() < 2 then + return + end - show_preview() - show_hover() - set_bg_hl() + show_preview() + show_hover() + set_bg_hl() end function M.close() - if has_code_win() then - if state.preview_win ~= nil and - vim.api.nvim_win_is_valid(state.preview_win) then - vim.api.nvim_win_close(state.preview_win, true) - end - if state.hover_win ~= nil and - vim.api.nvim_win_is_valid(state.hover_win) then - vim.api.nvim_win_close(state.hover_win, true) - end - end + if has_code_win() then + if state.preview_win ~= nil and vim.api.nvim_win_is_valid(state.preview_win) then + vim.api.nvim_win_close(state.preview_win, true) + end + if state.hover_win ~= nil and vim.api.nvim_win_is_valid(state.hover_win) then + vim.api.nvim_win_close(state.hover_win, true) + end + end end function M.toggle() - if state.preview_win ~= nil then - M.close() - else - M.show() - end + if state.preview_win ~= nil then + M.close() + else + M.show() + end end return M diff --git a/lua/symbols-outline/providers/coc.lua b/lua/symbols-outline/providers/coc.lua index 4c14060..72f9064 100644 --- a/lua/symbols-outline/providers/coc.lua +++ b/lua/symbols-outline/providers/coc.lua @@ -1,21 +1,30 @@ local M = {} function M.should_use_provider(_) - local coc_installed = vim.fn.exists("*CocActionAsync") + local coc_installed = vim.fn.exists("*CocActionAsync") - if coc_installed == 0 then return end + if coc_installed == 0 then + return + end - local coc_attached = vim.fn.call('CocAction', {'ensureDocument'}) - local has_symbols = vim.fn.call('CocHasProvider', {'documentSymbol'}) + local coc_attached = vim.fn.call("CocAction", { "ensureDocument" }) + local has_symbols = vim.fn.call("CocHasProvider", { "documentSymbol" }) - return coc_attached and has_symbols; + return coc_attached and has_symbols +end + +function M.hover_info(_, _, on_info) + on_info(nil, { contents = { kind = "markdown", contents = { "No extra information availaible!" } } }) end ---@param on_symbols function function M.request_symbols(on_symbols) - vim.fn.call('CocActionAsync', {'documentSymbols', function (_, symbols) - on_symbols{[1000000]={result=symbols}} - end}) + vim.fn.call("CocActionAsync", { + "documentSymbols", + function(_, symbols) + on_symbols({ [1000000] = { result = symbols } }) + end, + }) end return M diff --git a/lua/symbols-outline/providers/init.lua b/lua/symbols-outline/providers/init.lua index 8c8bba1..da3622f 100644 --- a/lua/symbols-outline/providers/init.lua +++ b/lua/symbols-outline/providers/init.lua @@ -1,34 +1,35 @@ local M = {} local providers = { - 'symbols-outline/providers/nvim-lsp', - 'symbols-outline/providers/coc', - 'symbols-outline/providers/markdown' + "symbols-outline/providers/nvim-lsp", + "symbols-outline/providers/coc", + "symbols-outline/providers/markdown", } -local current_provider; +_G._symbols_outline_current_provider = nil function M.has_provider() - local ret = false; - for _, value in ipairs(providers) do - local provider = require(value) - if provider.should_use_provider(0) then - ret = true; - break - end - end - return ret + local ret = false + for _, value in ipairs(providers) do + local provider = require(value) + if provider.should_use_provider(0) then + ret = true + break + end + end + return ret end ---@param on_symbols function function M.request_symbols(on_symbols) - for _, value in ipairs(providers) do - local provider = require(value) - if provider.should_use_provider(0) then - provider.request_symbols(on_symbols) - break - end - end + for _, value in ipairs(providers) do + local provider = require(value) + if provider.should_use_provider(0) then + _G._symbols_outline_current_provider = provider + provider.request_symbols(on_symbols) + break + end + end end return M diff --git a/lua/symbols-outline/providers/markdown.lua b/lua/symbols-outline/providers/markdown.lua index 441c6c3..225dd66 100644 --- a/lua/symbols-outline/providers/markdown.lua +++ b/lua/symbols-outline/providers/markdown.lua @@ -1,15 +1,19 @@ -local md_parser = require('symbols-outline.markdown') +local md_parser = require("symbols-outline.markdown") local M = {} -- probably change this function M.should_use_provider(bufnr) - return vim.api.nvim_buf_get_option(bufnr, 'ft') == 'markdown' + return vim.api.nvim_buf_get_option(bufnr, "ft") == "markdown" +end + +function M.hover_info(_, _, on_info) + on_info(nil, { contents = { kind = "markdown", contents = { "No extra information availaible!" } } }) end ---@param on_symbols function function M.request_symbols(on_symbols) - on_symbols(md_parser.handle_markdown()) + on_symbols(md_parser.handle_markdown()) end return M diff --git a/lua/symbols-outline/providers/nvim-lsp.lua b/lua/symbols-outline/providers/nvim-lsp.lua index 57122a7..ccb5d17 100644 --- a/lua/symbols-outline/providers/nvim-lsp.lua +++ b/lua/symbols-outline/providers/nvim-lsp.lua @@ -1,35 +1,57 @@ -local config = require('symbols-outline.config') +local config = require("symbols-outline.config") local M = {} local function getParams() - return {textDocument = vim.lsp.util.make_text_document_params()} + return { textDocument = vim.lsp.util.make_text_document_params() } +end + +function M.hover_info(bufnr, params, on_info) + local clients = vim.lsp.buf_get_clients(bufnr) + local used_client + + for id, client in pairs(clients) do + if config.is_client_blacklisted(id) then + goto continue + else + if client.server_capabilities.hoverProvider then + used_client = client + break + end + end + ::continue:: + end + + if not used_client then + on_info(nil, { contents = { kind = "markdown", content = { "No extra information availaible!" } } }) + end + + used_client.request("textDocument/hover", params, on_info, bufnr) end -- probably change this function M.should_use_provider(bufnr) - local clients = vim.lsp.buf_get_clients(bufnr) - local ret = false + local clients = vim.lsp.buf_get_clients(bufnr) + local ret = false - for id, client in pairs(clients) do - if config.is_client_blacklisted(id) then - goto continue - else - if client.server_capabilities.documentSymbolProvider then - ret = true - break - end - end - ::continue:: - end + for id, client in pairs(clients) do + if config.is_client_blacklisted(id) then + goto continue + else + if client.server_capabilities.documentSymbolProvider then + ret = true + break + end + end + ::continue:: + end - return ret + return ret end ---@param on_symbols function function M.request_symbols(on_symbols) - vim.lsp.buf_request_all(0, "textDocument/documentSymbol", getParams(), - on_symbols) + vim.lsp.buf_request_all(0, "textDocument/documentSymbol", getParams(), on_symbols) end return M