mrcjkb / haskell-tools.nvim

🦥 Supercharge your Haskell experience in neovim!
GNU General Public License v2.0
452 stars 17 forks source link

Allow bindings for hover actions #395

Open expipiplus1 opened 5 hours ago

expipiplus1 commented 5 hours ago

Feature description

Is it possible to add support for automatically executing the hover actions in a hover meny (for example to have a keybinding to open source or documentation in browser)?

(It's definitely possible with send_keys or whatever KK/Open documentation in browser<CR><CR>, but hardly elegant)

mrcjkb commented 4 hours ago

Hey 👋

Sure, I could probably add some <Plug> mappings. I'll look into it when I have some time.

expipiplus1 commented 2 hours ago

here's what I'm using, I updated it to support Source and Documentation, and also go to definition if it's available instead

It makes a great gd mapping

local function open_lsp_browser_link(link_type)
  local function make_hover_request(callback, retry)
    -- First, try to go to definition
    local definition_found = false
    vim.lsp.buf.definition {
      on_list = function()
        definition_found = true
        vim.lsp.buf.definition()
      end,
    }

    -- If definition is found, we're done
    if definition_found then return end

    -- If no definition, proceed with hover request
    local params = vim.lsp.util.make_position_params()
    vim.lsp.buf_request(0, "textDocument/hover", params, function(err, result, _, _)
      if err or not result or not result.contents then
        if not retry then print "No hover information available" end
        return
      end

      local markdown_lines = vim.lsp.util.convert_input_to_markdown_lines(result.contents)
      local uri

      for _, line in ipairs(markdown_lines) do
        if vim.startswith(line, "[" .. link_type .. "]") then
          uri = string.match(line, "%[" .. link_type .. "%]%((.+)%)")
          if uri then
            callback(uri)
            return
          end
        end
      end

      if not retry then
        -- If we didn't find the link, try once more
        vim.defer_fn(function() make_hover_request(callback, true) end, 100)
      else
        print("Could not find " .. link_type .. " link")
      end
    end)
  end

  make_hover_request(function(uri)
    if uri then
      local OS = require "haskell-tools.os"
      OS.open_browser(uri)
      print("Opening " .. link_type .. " in browser")
    end
  end)
end