mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 09:44:31 +00:00 
			
		
		
		
	feat(lsp): add vim.lsp.buf.subtypes(), vim.lsp.buf.supertypes() (#28388)
Co-authored-by: Mathias Fußenegger <mfussenegger@users.noreply.github.com> Co-authored-by: Maria José Solano <majosolano99@gmail.com>
This commit is contained in:
		@@ -182,6 +182,7 @@ won't run if your server doesn't support them.
 | 
			
		||||
- textDocument/hover
 | 
			
		||||
- textDocument/implementation*
 | 
			
		||||
- textDocument/inlayHint
 | 
			
		||||
- textDocument/prepareTypeHierarchy
 | 
			
		||||
- textDocument/publishDiagnostics
 | 
			
		||||
- textDocument/rangeFormatting
 | 
			
		||||
- textDocument/references
 | 
			
		||||
@@ -190,6 +191,8 @@ won't run if your server doesn't support them.
 | 
			
		||||
- textDocument/semanticTokens/full/delta
 | 
			
		||||
- textDocument/signatureHelp
 | 
			
		||||
- textDocument/typeDefinition*
 | 
			
		||||
- typeHierarchy/subtypes
 | 
			
		||||
- typeHierarchy/supertypes
 | 
			
		||||
- window/logMessage
 | 
			
		||||
- window/showMessage
 | 
			
		||||
- window/showDocument
 | 
			
		||||
@@ -1428,6 +1431,16 @@ signature_help()                                *vim.lsp.buf.signature_help()*
 | 
			
		||||
    Displays signature information about the symbol under the cursor in a
 | 
			
		||||
    floating window.
 | 
			
		||||
 | 
			
		||||
subtypes()                                            *vim.lsp.buf.subtypes()*
 | 
			
		||||
    Lists all the subtypes of the symbol under the cursor in the |quickfix|
 | 
			
		||||
    window. If the symbol can resolve to multiple items, the user can pick one
 | 
			
		||||
    using |vim.ui.select()|.
 | 
			
		||||
 | 
			
		||||
supertypes()                                        *vim.lsp.buf.supertypes()*
 | 
			
		||||
    Lists all the supertypes of the symbol under the cursor in the |quickfix|
 | 
			
		||||
    window. If the symbol can resolve to multiple items, the user can pick one
 | 
			
		||||
    using |vim.ui.select()|.
 | 
			
		||||
 | 
			
		||||
type_definition({options})                     *vim.lsp.buf.type_definition()*
 | 
			
		||||
    Jumps to the definition of the type of the symbol under the cursor.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -215,6 +215,8 @@ The following new APIs and features were added.
 | 
			
		||||
    https://microsoft.github.io/language-server-protocol/specification/#textDocument_inlayHint
 | 
			
		||||
  • Implemented pull diagnostic textDocument/diagnostic: |vim.lsp.diagnostic.on_diagnostic()|
 | 
			
		||||
    https://microsoft.github.io/language-server-protocol/specification/#textDocument_diagnostic
 | 
			
		||||
  • Implemented LSP type hierarchy: |vim.lsp.buf.supertypes()| and |vim.lsp.buf.subtypes()|
 | 
			
		||||
    https://microsoft.github.io/language-server-protocol/specification/#textDocument_prepareTypeHierarchy
 | 
			
		||||
  • |vim.lsp.status()| consumes the last progress messages as a string.
 | 
			
		||||
  • LSP client now always saves and restores named buffer marks when applying
 | 
			
		||||
    text edits.
 | 
			
		||||
 
 | 
			
		||||
@@ -43,6 +43,9 @@ lsp._request_name_to_capability = {
 | 
			
		||||
  [ms.textDocument_prepareCallHierarchy] = { 'callHierarchyProvider' },
 | 
			
		||||
  [ms.callHierarchy_incomingCalls] = { 'callHierarchyProvider' },
 | 
			
		||||
  [ms.callHierarchy_outgoingCalls] = { 'callHierarchyProvider' },
 | 
			
		||||
  [ms.textDocument_prepareTypeHierarchy] = { 'typeHierarchyProvider' },
 | 
			
		||||
  [ms.typeHierarchy_subtypes] = { 'typeHierarchyProvider' },
 | 
			
		||||
  [ms.typeHierarchy_supertypes] = { 'typeHierarchyProvider' },
 | 
			
		||||
  [ms.textDocument_rename] = { 'renameProvider' },
 | 
			
		||||
  [ms.textDocument_prepareRename] = { 'renameProvider', 'prepareProvider' },
 | 
			
		||||
  [ms.textDocument_codeAction] = { 'codeActionProvider' },
 | 
			
		||||
 
 | 
			
		||||
@@ -495,6 +495,90 @@ function M.outgoing_calls()
 | 
			
		||||
  call_hierarchy(ms.callHierarchy_outgoingCalls)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- @param method string
 | 
			
		||||
local function type_hierarchy(method)
 | 
			
		||||
  --- Merge results from multiple clients into a single table. Client-ID is preserved.
 | 
			
		||||
  ---
 | 
			
		||||
  --- @param results table<integer, {error: lsp.ResponseError, result: lsp.TypeHierarchyItem[]?}>
 | 
			
		||||
  local function merge_results(results)
 | 
			
		||||
    local merged_results = {}
 | 
			
		||||
    for client_id, client_result in pairs(results) do
 | 
			
		||||
      if client_result.error then
 | 
			
		||||
        vim.notify(client_result.error.message, vim.log.levels.WARN)
 | 
			
		||||
      elseif client_result.result then
 | 
			
		||||
        for _, item in pairs(client_result.result) do
 | 
			
		||||
          table.insert(merged_results, { client_id, item })
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    return merged_results
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  local bufnr = api.nvim_get_current_buf()
 | 
			
		||||
  local params = util.make_position_params()
 | 
			
		||||
  --- @param results table<integer, {error: lsp.ResponseError, result: lsp.TypeHierarchyItem[]?}>
 | 
			
		||||
  vim.lsp.buf_request_all(bufnr, ms.textDocument_prepareTypeHierarchy, params, function(results)
 | 
			
		||||
    local merged_results = merge_results(results)
 | 
			
		||||
    if #merged_results == 0 then
 | 
			
		||||
      vim.notify('No items resolved', vim.log.levels.INFO)
 | 
			
		||||
      return
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if #merged_results == 1 then
 | 
			
		||||
      --- @type {integer, lsp.TypeHierarchyItem}
 | 
			
		||||
      local item = merged_results[1]
 | 
			
		||||
      local client = vim.lsp.get_client_by_id(item[1])
 | 
			
		||||
      if client then
 | 
			
		||||
        --- @type lsp.TypeHierarchyItem
 | 
			
		||||
        client.request(method, { item = item[2] }, nil, bufnr)
 | 
			
		||||
      else
 | 
			
		||||
        vim.notify(
 | 
			
		||||
          string.format('Client with id=%d disappeared during call hierarchy request', item[1]),
 | 
			
		||||
          vim.log.levels.WARN
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
    else
 | 
			
		||||
      local opts = {
 | 
			
		||||
        prompt = 'Select a type hierarchy item:',
 | 
			
		||||
        kind = 'typehierarchy',
 | 
			
		||||
        format_item = function(item)
 | 
			
		||||
          if not item[2].detail or #item[2].detail == 0 then
 | 
			
		||||
            return item[2].name
 | 
			
		||||
          end
 | 
			
		||||
          return string.format('%s %s', item[2].name, item[2].detail)
 | 
			
		||||
        end,
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      vim.ui.select(merged_results, opts, function(item)
 | 
			
		||||
        local client = vim.lsp.get_client_by_id(item[1])
 | 
			
		||||
        if client then
 | 
			
		||||
          --- @type lsp.TypeHierarchyItem
 | 
			
		||||
          client.request(method, { item = item[2] }, nil, bufnr)
 | 
			
		||||
        else
 | 
			
		||||
          vim.notify(
 | 
			
		||||
            string.format('Client with id=%d disappeared during call hierarchy request', item[1]),
 | 
			
		||||
            vim.log.levels.WARN
 | 
			
		||||
          )
 | 
			
		||||
        end
 | 
			
		||||
      end)
 | 
			
		||||
    end
 | 
			
		||||
  end)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- Lists all the subtypes of the symbol under the
 | 
			
		||||
--- cursor in the |quickfix| window. If the symbol can resolve to
 | 
			
		||||
--- multiple items, the user can pick one using |vim.ui.select()|.
 | 
			
		||||
function M.subtypes()
 | 
			
		||||
  type_hierarchy(ms.typeHierarchy_subtypes)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- Lists all the supertypes of the symbol under the
 | 
			
		||||
--- cursor in the |quickfix| window. If the symbol can resolve to
 | 
			
		||||
--- multiple items, the user can pick one using |vim.ui.select()|.
 | 
			
		||||
function M.supertypes()
 | 
			
		||||
  type_hierarchy(ms.typeHierarchy_supertypes)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- List workspace folders.
 | 
			
		||||
---
 | 
			
		||||
function M.list_workspace_folders()
 | 
			
		||||
 
 | 
			
		||||
@@ -565,6 +565,45 @@ M[ms.callHierarchy_incomingCalls] = make_call_hierarchy_handler('from')
 | 
			
		||||
--- @see # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#callHierarchy_outgoingCalls
 | 
			
		||||
M[ms.callHierarchy_outgoingCalls] = make_call_hierarchy_handler('to')
 | 
			
		||||
 | 
			
		||||
--- Displays type hierarchy in the quickfix window.
 | 
			
		||||
local function make_type_hierarchy_handler()
 | 
			
		||||
  --- @param result lsp.TypeHierarchyItem[]
 | 
			
		||||
  return function(_, result, ctx, _)
 | 
			
		||||
    if not result then
 | 
			
		||||
      return
 | 
			
		||||
    end
 | 
			
		||||
    local function format_item(item)
 | 
			
		||||
      if not item.detail or #item.detail == 0 then
 | 
			
		||||
        return item.name
 | 
			
		||||
      end
 | 
			
		||||
      return string.format('%s %s', item.name, item.detail)
 | 
			
		||||
    end
 | 
			
		||||
    local client = assert(vim.lsp.get_client_by_id(ctx.client_id))
 | 
			
		||||
    local items = {}
 | 
			
		||||
    for _, type_hierarchy_item in pairs(result) do
 | 
			
		||||
      local col = util._get_line_byte_from_position(
 | 
			
		||||
        ctx.bufnr,
 | 
			
		||||
        type_hierarchy_item.range.start,
 | 
			
		||||
        client.offset_encoding
 | 
			
		||||
      )
 | 
			
		||||
      table.insert(items, {
 | 
			
		||||
        filename = assert(vim.uri_to_fname(type_hierarchy_item.uri)),
 | 
			
		||||
        text = format_item(type_hierarchy_item),
 | 
			
		||||
        lnum = type_hierarchy_item.range.start.line + 1,
 | 
			
		||||
        col = col + 1,
 | 
			
		||||
      })
 | 
			
		||||
    end
 | 
			
		||||
    vim.fn.setqflist({}, ' ', { title = 'LSP type hierarchy', items = items })
 | 
			
		||||
    api.nvim_command('botright copen')
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- @see # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#typeHierarchy_incomingCalls
 | 
			
		||||
M[ms.typeHierarchy_subtypes] = make_type_hierarchy_handler()
 | 
			
		||||
 | 
			
		||||
--- @see # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#typeHierarchy_outgoingCalls
 | 
			
		||||
M[ms.typeHierarchy_supertypes] = make_type_hierarchy_handler()
 | 
			
		||||
 | 
			
		||||
--- @see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_logMessage
 | 
			
		||||
--- @param result lsp.LogMessageParams
 | 
			
		||||
M[ms.window_logMessage] = function(_, result, ctx, _)
 | 
			
		||||
 
 | 
			
		||||
@@ -3461,6 +3461,442 @@ describe('LSP', function()
 | 
			
		||||
    end)
 | 
			
		||||
  end)
 | 
			
		||||
 | 
			
		||||
  describe('vim.lsp.buf.subtypes', function()
 | 
			
		||||
    it('does nothing for an empty response', function()
 | 
			
		||||
      local qflist_count = exec_lua([=[
 | 
			
		||||
        require'vim.lsp.handlers'['typeHierarchy/subtypes'](nil, nil, {})
 | 
			
		||||
        return #vim.fn.getqflist()
 | 
			
		||||
      ]=])
 | 
			
		||||
      eq(0, qflist_count)
 | 
			
		||||
    end)
 | 
			
		||||
 | 
			
		||||
    it('opens the quickfix list with the right subtypes', function()
 | 
			
		||||
      clear()
 | 
			
		||||
      exec_lua(create_server_definition)
 | 
			
		||||
      local qflist = exec_lua([=[
 | 
			
		||||
        local clangd_response = { {
 | 
			
		||||
          data = {
 | 
			
		||||
            parents = { {
 | 
			
		||||
              parents = { {
 | 
			
		||||
                parents = { {
 | 
			
		||||
                  parents = {},
 | 
			
		||||
                  symbolID = "62B3D268A01B9978"
 | 
			
		||||
                } },
 | 
			
		||||
                symbolID = "DC9B0AD433B43BEC"
 | 
			
		||||
              } },
 | 
			
		||||
              symbolID = "06B5F6A19BA9F6A8"
 | 
			
		||||
            } },
 | 
			
		||||
            symbolID = "EDC336589C09ABB2"
 | 
			
		||||
          },
 | 
			
		||||
          kind = 5,
 | 
			
		||||
          name = "D2",
 | 
			
		||||
          range = {
 | 
			
		||||
            ["end"] = {
 | 
			
		||||
              character = 8,
 | 
			
		||||
              line = 9
 | 
			
		||||
            },
 | 
			
		||||
            start = {
 | 
			
		||||
              character = 6,
 | 
			
		||||
              line = 9
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          selectionRange = {
 | 
			
		||||
            ["end"] = {
 | 
			
		||||
              character = 8,
 | 
			
		||||
              line = 9
 | 
			
		||||
            },
 | 
			
		||||
            start = {
 | 
			
		||||
              character = 6,
 | 
			
		||||
              line = 9
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          uri = "file:///home/jiangyinzuo/hello.cpp"
 | 
			
		||||
        }, {
 | 
			
		||||
          data = {
 | 
			
		||||
            parents = { {
 | 
			
		||||
              parents = { {
 | 
			
		||||
                parents = { {
 | 
			
		||||
                  parents = {},
 | 
			
		||||
                  symbolID = "62B3D268A01B9978"
 | 
			
		||||
                } },
 | 
			
		||||
                symbolID = "DC9B0AD433B43BEC"
 | 
			
		||||
              } },
 | 
			
		||||
              symbolID = "06B5F6A19BA9F6A8"
 | 
			
		||||
            } },
 | 
			
		||||
            symbolID = "AFFCAED15557EF08"
 | 
			
		||||
          },
 | 
			
		||||
          kind = 5,
 | 
			
		||||
          name = "D1",
 | 
			
		||||
          range = {
 | 
			
		||||
            ["end"] = {
 | 
			
		||||
              character = 8,
 | 
			
		||||
              line = 8
 | 
			
		||||
            },
 | 
			
		||||
            start = {
 | 
			
		||||
              character = 6,
 | 
			
		||||
              line = 8
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          selectionRange = {
 | 
			
		||||
            ["end"] = {
 | 
			
		||||
              character = 8,
 | 
			
		||||
              line = 8
 | 
			
		||||
            },
 | 
			
		||||
            start = {
 | 
			
		||||
              character = 6,
 | 
			
		||||
              line = 8
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          uri = "file:///home/jiangyinzuo/hello.cpp"
 | 
			
		||||
        } }
 | 
			
		||||
 | 
			
		||||
        local server = _create_server({
 | 
			
		||||
          capabilities = {
 | 
			
		||||
            positionEncoding = "utf-8"
 | 
			
		||||
          },
 | 
			
		||||
        })
 | 
			
		||||
        local client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd })
 | 
			
		||||
        local handler = require'vim.lsp.handlers'['typeHierarchy/subtypes']
 | 
			
		||||
        handler(nil, clangd_response, { client_id = client_id, bufnr = 1 })
 | 
			
		||||
        return vim.fn.getqflist()
 | 
			
		||||
      ]=])
 | 
			
		||||
 | 
			
		||||
      local expected = {
 | 
			
		||||
        {
 | 
			
		||||
          bufnr = 2,
 | 
			
		||||
          col = 7,
 | 
			
		||||
          end_col = 0,
 | 
			
		||||
          end_lnum = 0,
 | 
			
		||||
          lnum = 10,
 | 
			
		||||
          module = '',
 | 
			
		||||
          nr = 0,
 | 
			
		||||
          pattern = '',
 | 
			
		||||
          text = 'D2',
 | 
			
		||||
          type = '',
 | 
			
		||||
          valid = 1,
 | 
			
		||||
          vcol = 0,
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          bufnr = 2,
 | 
			
		||||
          col = 7,
 | 
			
		||||
          end_col = 0,
 | 
			
		||||
          end_lnum = 0,
 | 
			
		||||
          lnum = 9,
 | 
			
		||||
          module = '',
 | 
			
		||||
          nr = 0,
 | 
			
		||||
          pattern = '',
 | 
			
		||||
          text = 'D1',
 | 
			
		||||
          type = '',
 | 
			
		||||
          valid = 1,
 | 
			
		||||
          vcol = 0,
 | 
			
		||||
        },
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      eq(expected, qflist)
 | 
			
		||||
    end)
 | 
			
		||||
 | 
			
		||||
    it('opens the quickfix list with the right subtypes and details', function()
 | 
			
		||||
      clear()
 | 
			
		||||
      exec_lua(create_server_definition)
 | 
			
		||||
      local qflist = exec_lua([=[
 | 
			
		||||
        local jdtls_response = {
 | 
			
		||||
          {
 | 
			
		||||
            data = { element = '=hello-java_ed323c3c/_<{Main.java[Main[A' },
 | 
			
		||||
            detail = '',
 | 
			
		||||
            kind = 5,
 | 
			
		||||
            name = 'A',
 | 
			
		||||
            range = {
 | 
			
		||||
              ['end'] = { character = 26, line = 3 },
 | 
			
		||||
              start = { character = 1, line = 3 },
 | 
			
		||||
            },
 | 
			
		||||
            selectionRange = {
 | 
			
		||||
              ['end'] = { character = 8, line = 3 },
 | 
			
		||||
              start = { character = 7, line = 3 },
 | 
			
		||||
            },
 | 
			
		||||
            tags = {},
 | 
			
		||||
            uri = 'file:///home/jiangyinzuo/hello-java/Main.java',
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            data = { element = '=hello-java_ed323c3c/_<mylist{MyList.java[MyList[Inner' },
 | 
			
		||||
            detail = 'mylist',
 | 
			
		||||
            kind = 5,
 | 
			
		||||
            name = 'MyList$Inner',
 | 
			
		||||
            range = {
 | 
			
		||||
              ['end'] = { character = 37, line = 3 },
 | 
			
		||||
              start = { character = 1, line = 3 },
 | 
			
		||||
            },
 | 
			
		||||
            selectionRange = {
 | 
			
		||||
              ['end'] = { character = 19, line = 3 },
 | 
			
		||||
              start = { character = 14, line = 3 },
 | 
			
		||||
            },
 | 
			
		||||
            tags = {},
 | 
			
		||||
            uri = 'file:///home/jiangyinzuo/hello-java/mylist/MyList.java',
 | 
			
		||||
          },
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        local server = _create_server({
 | 
			
		||||
          capabilities = {
 | 
			
		||||
            positionEncoding = "utf-8"
 | 
			
		||||
          },
 | 
			
		||||
        })
 | 
			
		||||
        local client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd })
 | 
			
		||||
        local handler = require'vim.lsp.handlers'['typeHierarchy/subtypes']
 | 
			
		||||
        handler(nil, jdtls_response, { client_id = client_id, bufnr = 1 })
 | 
			
		||||
        return vim.fn.getqflist()
 | 
			
		||||
      ]=])
 | 
			
		||||
 | 
			
		||||
      local expected = {
 | 
			
		||||
        {
 | 
			
		||||
          bufnr = 2,
 | 
			
		||||
          col = 2,
 | 
			
		||||
          end_col = 0,
 | 
			
		||||
          end_lnum = 0,
 | 
			
		||||
          lnum = 4,
 | 
			
		||||
          module = '',
 | 
			
		||||
          nr = 0,
 | 
			
		||||
          pattern = '',
 | 
			
		||||
          text = 'A',
 | 
			
		||||
          type = '',
 | 
			
		||||
          valid = 1,
 | 
			
		||||
          vcol = 0,
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          bufnr = 3,
 | 
			
		||||
          col = 2,
 | 
			
		||||
          end_col = 0,
 | 
			
		||||
          end_lnum = 0,
 | 
			
		||||
          lnum = 4,
 | 
			
		||||
          module = '',
 | 
			
		||||
          nr = 0,
 | 
			
		||||
          pattern = '',
 | 
			
		||||
          text = 'MyList$Inner mylist',
 | 
			
		||||
          type = '',
 | 
			
		||||
          valid = 1,
 | 
			
		||||
          vcol = 0,
 | 
			
		||||
        },
 | 
			
		||||
      }
 | 
			
		||||
      eq(expected, qflist)
 | 
			
		||||
    end)
 | 
			
		||||
  end)
 | 
			
		||||
 | 
			
		||||
  describe('vim.lsp.buf.supertypes', function()
 | 
			
		||||
    it('does nothing for an empty response', function()
 | 
			
		||||
      local qflist_count = exec_lua([=[
 | 
			
		||||
        require'vim.lsp.handlers'['typeHierarchy/supertypes'](nil, nil, {})
 | 
			
		||||
        return #vim.fn.getqflist()
 | 
			
		||||
      ]=])
 | 
			
		||||
      eq(0, qflist_count)
 | 
			
		||||
    end)
 | 
			
		||||
 | 
			
		||||
    it('opens the quickfix list with the right supertypes', function()
 | 
			
		||||
      clear()
 | 
			
		||||
      exec_lua(create_server_definition)
 | 
			
		||||
      local qflist = exec_lua([=[
 | 
			
		||||
        local clangd_response = { {
 | 
			
		||||
          data = {
 | 
			
		||||
            parents = { {
 | 
			
		||||
              parents = { {
 | 
			
		||||
                parents = { {
 | 
			
		||||
                  parents = {},
 | 
			
		||||
                  symbolID = "62B3D268A01B9978"
 | 
			
		||||
                } },
 | 
			
		||||
                symbolID = "DC9B0AD433B43BEC"
 | 
			
		||||
              } },
 | 
			
		||||
              symbolID = "06B5F6A19BA9F6A8"
 | 
			
		||||
            } },
 | 
			
		||||
            symbolID = "EDC336589C09ABB2"
 | 
			
		||||
          },
 | 
			
		||||
          kind = 5,
 | 
			
		||||
          name = "D2",
 | 
			
		||||
          range = {
 | 
			
		||||
            ["end"] = {
 | 
			
		||||
              character = 8,
 | 
			
		||||
              line = 9
 | 
			
		||||
            },
 | 
			
		||||
            start = {
 | 
			
		||||
              character = 6,
 | 
			
		||||
              line = 9
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          selectionRange = {
 | 
			
		||||
            ["end"] = {
 | 
			
		||||
              character = 8,
 | 
			
		||||
              line = 9
 | 
			
		||||
            },
 | 
			
		||||
            start = {
 | 
			
		||||
              character = 6,
 | 
			
		||||
              line = 9
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          uri = "file:///home/jiangyinzuo/hello.cpp"
 | 
			
		||||
        }, {
 | 
			
		||||
          data = {
 | 
			
		||||
            parents = { {
 | 
			
		||||
              parents = { {
 | 
			
		||||
                parents = { {
 | 
			
		||||
                  parents = {},
 | 
			
		||||
                  symbolID = "62B3D268A01B9978"
 | 
			
		||||
                } },
 | 
			
		||||
                symbolID = "DC9B0AD433B43BEC"
 | 
			
		||||
              } },
 | 
			
		||||
              symbolID = "06B5F6A19BA9F6A8"
 | 
			
		||||
            } },
 | 
			
		||||
            symbolID = "AFFCAED15557EF08"
 | 
			
		||||
          },
 | 
			
		||||
          kind = 5,
 | 
			
		||||
          name = "D1",
 | 
			
		||||
          range = {
 | 
			
		||||
            ["end"] = {
 | 
			
		||||
              character = 8,
 | 
			
		||||
              line = 8
 | 
			
		||||
            },
 | 
			
		||||
            start = {
 | 
			
		||||
              character = 6,
 | 
			
		||||
              line = 8
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          selectionRange = {
 | 
			
		||||
            ["end"] = {
 | 
			
		||||
              character = 8,
 | 
			
		||||
              line = 8
 | 
			
		||||
            },
 | 
			
		||||
            start = {
 | 
			
		||||
              character = 6,
 | 
			
		||||
              line = 8
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          uri = "file:///home/jiangyinzuo/hello.cpp"
 | 
			
		||||
        } }
 | 
			
		||||
 | 
			
		||||
        local server = _create_server({
 | 
			
		||||
          capabilities = {
 | 
			
		||||
            positionEncoding = "utf-8"
 | 
			
		||||
          },
 | 
			
		||||
        })
 | 
			
		||||
        local client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd })
 | 
			
		||||
        local handler = require'vim.lsp.handlers'['typeHierarchy/supertypes']
 | 
			
		||||
        handler(nil, clangd_response, { client_id = client_id, bufnr = 1 })
 | 
			
		||||
        return vim.fn.getqflist()
 | 
			
		||||
      ]=])
 | 
			
		||||
 | 
			
		||||
      local expected = {
 | 
			
		||||
        {
 | 
			
		||||
          bufnr = 2,
 | 
			
		||||
          col = 7,
 | 
			
		||||
          end_col = 0,
 | 
			
		||||
          end_lnum = 0,
 | 
			
		||||
          lnum = 10,
 | 
			
		||||
          module = '',
 | 
			
		||||
          nr = 0,
 | 
			
		||||
          pattern = '',
 | 
			
		||||
          text = 'D2',
 | 
			
		||||
          type = '',
 | 
			
		||||
          valid = 1,
 | 
			
		||||
          vcol = 0,
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          bufnr = 2,
 | 
			
		||||
          col = 7,
 | 
			
		||||
          end_col = 0,
 | 
			
		||||
          end_lnum = 0,
 | 
			
		||||
          lnum = 9,
 | 
			
		||||
          module = '',
 | 
			
		||||
          nr = 0,
 | 
			
		||||
          pattern = '',
 | 
			
		||||
          text = 'D1',
 | 
			
		||||
          type = '',
 | 
			
		||||
          valid = 1,
 | 
			
		||||
          vcol = 0,
 | 
			
		||||
        },
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      eq(expected, qflist)
 | 
			
		||||
    end)
 | 
			
		||||
 | 
			
		||||
    it('opens the quickfix list with the right supertypes and details', function()
 | 
			
		||||
      clear()
 | 
			
		||||
      exec_lua(create_server_definition)
 | 
			
		||||
      local qflist = exec_lua([=[
 | 
			
		||||
        local jdtls_response = {
 | 
			
		||||
          {
 | 
			
		||||
            data = { element = '=hello-java_ed323c3c/_<{Main.java[Main[A' },
 | 
			
		||||
            detail = '',
 | 
			
		||||
            kind = 5,
 | 
			
		||||
            name = 'A',
 | 
			
		||||
            range = {
 | 
			
		||||
              ['end'] = { character = 26, line = 3 },
 | 
			
		||||
              start = { character = 1, line = 3 },
 | 
			
		||||
            },
 | 
			
		||||
            selectionRange = {
 | 
			
		||||
              ['end'] = { character = 8, line = 3 },
 | 
			
		||||
              start = { character = 7, line = 3 },
 | 
			
		||||
            },
 | 
			
		||||
            tags = {},
 | 
			
		||||
            uri = 'file:///home/jiangyinzuo/hello-java/Main.java',
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            data = { element = '=hello-java_ed323c3c/_<mylist{MyList.java[MyList[Inner' },
 | 
			
		||||
            detail = 'mylist',
 | 
			
		||||
            kind = 5,
 | 
			
		||||
            name = 'MyList$Inner',
 | 
			
		||||
            range = {
 | 
			
		||||
              ['end'] = { character = 37, line = 3 },
 | 
			
		||||
              start = { character = 1, line = 3 },
 | 
			
		||||
            },
 | 
			
		||||
            selectionRange = {
 | 
			
		||||
              ['end'] = { character = 19, line = 3 },
 | 
			
		||||
              start = { character = 14, line = 3 },
 | 
			
		||||
            },
 | 
			
		||||
            tags = {},
 | 
			
		||||
            uri = 'file:///home/jiangyinzuo/hello-java/mylist/MyList.java',
 | 
			
		||||
          },
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        local server = _create_server({
 | 
			
		||||
          capabilities = {
 | 
			
		||||
            positionEncoding = "utf-8"
 | 
			
		||||
          },
 | 
			
		||||
        })
 | 
			
		||||
        local client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd })
 | 
			
		||||
        local handler = require'vim.lsp.handlers'['typeHierarchy/supertypes']
 | 
			
		||||
        handler(nil, jdtls_response, { client_id = client_id, bufnr = 1 })
 | 
			
		||||
        return vim.fn.getqflist()
 | 
			
		||||
      ]=])
 | 
			
		||||
 | 
			
		||||
      local expected = {
 | 
			
		||||
        {
 | 
			
		||||
          bufnr = 2,
 | 
			
		||||
          col = 2,
 | 
			
		||||
          end_col = 0,
 | 
			
		||||
          end_lnum = 0,
 | 
			
		||||
          lnum = 4,
 | 
			
		||||
          module = '',
 | 
			
		||||
          nr = 0,
 | 
			
		||||
          pattern = '',
 | 
			
		||||
          text = 'A',
 | 
			
		||||
          type = '',
 | 
			
		||||
          valid = 1,
 | 
			
		||||
          vcol = 0,
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          bufnr = 3,
 | 
			
		||||
          col = 2,
 | 
			
		||||
          end_col = 0,
 | 
			
		||||
          end_lnum = 0,
 | 
			
		||||
          lnum = 4,
 | 
			
		||||
          module = '',
 | 
			
		||||
          nr = 0,
 | 
			
		||||
          pattern = '',
 | 
			
		||||
          text = 'MyList$Inner mylist',
 | 
			
		||||
          type = '',
 | 
			
		||||
          valid = 1,
 | 
			
		||||
          vcol = 0,
 | 
			
		||||
        },
 | 
			
		||||
      }
 | 
			
		||||
      eq(expected, qflist)
 | 
			
		||||
    end)
 | 
			
		||||
  end)
 | 
			
		||||
 | 
			
		||||
  describe('vim.lsp.buf.rename', function()
 | 
			
		||||
    for _, test in ipairs({
 | 
			
		||||
      {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user