7

Whenever I open a hover window with my LSP plugin,

:lua vim.lsp.buf.hover()

I get a floating window hovered over text, but then I can not close it? I've tried ESC and the like. How do you close these hovered windows?

Evan Carroll
  • 1,304
  • 14
  • 39

3 Answers3

6

If you do NOT focus (click inside) of the hover, closing it is as simple as using any navigation key (h, j, k, l). However, if you do click inside, you'll either have to focus outside again or use :q.

Evan Carroll
  • 1,304
  • 14
  • 39
2

Improving Telemachus' answer further, if you want to toggle the hover with K, you can do the following:

vim.api.nvim_create_autocmd("LspAttach", {
    callback = function(ev)
        vim.keymap.set("n", "K", function()
            local base_win_id = vim.api.nvim_get_current_win()
            local windows = vim.api.nvim_tabpage_list_wins(0)
            for _, win_id in ipairs(windows) do
                if win_id ~= base_win_id then
                    local win_cfg = vim.api.nvim_win_get_config(win_id)
                    if win_cfg.relative == "win" and win_cfg.win == base_win_id then
                        vim.api.nvim_win_close(win_id, {})
                        return
                    end
                end
            end
            vim.lsp.buf.hover()
        end, { remap = false, silent = true, buffer = ev.buf, desc = "Toggle hover" })
        -- Probably lots of other keymaps...
    end
})
Friedrich
  • 1,846
  • 1
  • 11
  • 21
Daniel
  • 121
  • 2
  • 1
    This is neat, but I'll mention one thing: it steps on the default secondary function of K with the LSP. By default, if you open a window with K and then enter K again, the cursor will move into the window opened by the first K. As I mention in my answer, this can be useful if the documentation window is long and you want to move around through it. – Telemachus Mar 25 '24 at 00:01
1

I had the same problem and Google sent me here. I was disappointed by the accepted answer, so here's what I came up with after a little research.

First, the situation as I understand it:

  • If you call vim.lsp.buf.hover twice, you will jump into the window. (This can be useful if you want to read further into a long piece of documentation.) If vim.lsp.buf.hover is mapped to K in normal mode, as it often is, then KK will jump you into the window.
  • Once you are in the window, you can easily close it with q. (You don't even need :q, though that works too.)
  • As the OP says in their answer, if you are not in the hover window, and you do any movement, the window will automatically close. That's fine, but annoying if you don't want to move the cursor.
  • One simple answer is to map something to hl (or jk). That will move the cursor back and forth one character (or one line) but (usually) leave the character where you started. However, this can cause small annoyances if you open a hover window when you are on the first column (or the last line if you use jk). In those cases, the cursor will move since the first movement won't do anything and the second will over correct.

After being annoyed about all of this, I came up with the following.

local hover_close = function(base_win_id)
    local windows = vim.api.nvim_tabpage_list_wins(0)
    for _, win_id in ipairs(windows) do
        if win_id ~= base_win_id then
            local win_cfg = vim.api.nvim_win_get_config(win_id)
            if win_cfg.relative == "win" and win_cfg.win == base_win_id then
                vim.api.nvim_win_close(win_id, {})
                break
            end
        end
    end
end

-- Later, or in another file, when you create keymaps for LSP vim.api.nvim_create_autocmd("LspAttach", { callback = function(ev) local keymap_opts = { remap = false, silent = true, buffer = ev.buf } -- Probably lots of other keymaps, but the relevant two... vim.keymap.set("n", "K", lsp.buf.hover, keymap_opts) vim.keymap.set("n", "<Leader>;", function() hover_close(vim.api.nvim_get_current_win()) end, keymap_opts) end, })

Telemachus
  • 181
  • 7