mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 09:44:31 +00:00 
			
		
		
		
	feat(lsp): support documentColor dynamic registration #33800
				
					
				
			This commit is contained in:
		
				
					committed by
					
						
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							5c15df449a
						
					
				
				
					commit
					8f5bd569c5
				
			@@ -2212,15 +2212,12 @@ enable({enable}, {bufnr}, {opts})            *vim.lsp.document_color.enable()*
 | 
			
		||||
    Enables document highlighting from the given language client in the given
 | 
			
		||||
    buffer.
 | 
			
		||||
 | 
			
		||||
    You can enable document highlighting from a supporting client as follows: >lua
 | 
			
		||||
    You can enable document highlighting when a client attaches to a buffer as
 | 
			
		||||
    follows: >lua
 | 
			
		||||
        vim.api.nvim_create_autocmd('LspAttach', {
 | 
			
		||||
          callback = function(args)
 | 
			
		||||
            local client = vim.lsp.get_client_by_id(args.data.client_id)
 | 
			
		||||
 | 
			
		||||
            if client:supports_method('textDocument/documentColor') then
 | 
			
		||||
            vim.lsp.document_color.enable(true, args.buf)
 | 
			
		||||
          end
 | 
			
		||||
          end
 | 
			
		||||
        })
 | 
			
		||||
<
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -172,16 +172,6 @@ local function buf_clear(bufnr)
 | 
			
		||||
  api.nvim__redraw({ buf = bufnr, valid = true, flush = false })
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- @param bufnr integer
 | 
			
		||||
--- @param client_id? integer
 | 
			
		||||
local function buf_refresh(bufnr, client_id)
 | 
			
		||||
  util._refresh(ms.textDocument_documentColor, {
 | 
			
		||||
    bufnr = bufnr,
 | 
			
		||||
    handler = on_document_color,
 | 
			
		||||
    client_id = client_id,
 | 
			
		||||
  })
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- @param bufnr integer
 | 
			
		||||
local function buf_disable(bufnr)
 | 
			
		||||
  buf_clear(bufnr)
 | 
			
		||||
@@ -196,7 +186,7 @@ local function buf_enable(bufnr)
 | 
			
		||||
    on_reload = function(_, buf)
 | 
			
		||||
      buf_clear(buf)
 | 
			
		||||
      if bufstates[buf].enabled then
 | 
			
		||||
        buf_refresh(buf)
 | 
			
		||||
        M._buf_refresh(buf)
 | 
			
		||||
      end
 | 
			
		||||
    end,
 | 
			
		||||
    on_detach = function(_, buf)
 | 
			
		||||
@@ -215,7 +205,7 @@ local function buf_enable(bufnr)
 | 
			
		||||
        (method == ms.textDocument_didChange or method == ms.textDocument_didOpen)
 | 
			
		||||
        and bufstates[args.buf].enabled
 | 
			
		||||
      then
 | 
			
		||||
        buf_refresh(args.buf, args.data.client_id)
 | 
			
		||||
        M._buf_refresh(args.buf, args.data.client_id)
 | 
			
		||||
      end
 | 
			
		||||
    end,
 | 
			
		||||
  })
 | 
			
		||||
@@ -238,7 +228,18 @@ local function buf_enable(bufnr)
 | 
			
		||||
    end,
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  buf_refresh(bufnr)
 | 
			
		||||
  M._buf_refresh(bufnr)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- @nodoc
 | 
			
		||||
--- @param bufnr integer
 | 
			
		||||
--- @param client_id? integer
 | 
			
		||||
function M._buf_refresh(bufnr, client_id)
 | 
			
		||||
  util._refresh(ms.textDocument_documentColor, {
 | 
			
		||||
    bufnr = bufnr,
 | 
			
		||||
    handler = on_document_color,
 | 
			
		||||
    client_id = client_id,
 | 
			
		||||
  })
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- Query whether document colors are enabled in the given buffer.
 | 
			
		||||
@@ -259,16 +260,12 @@ end
 | 
			
		||||
 | 
			
		||||
--- Enables document highlighting from the given language client in the given buffer.
 | 
			
		||||
---
 | 
			
		||||
--- You can enable document highlighting from a supporting client as follows:
 | 
			
		||||
--- You can enable document highlighting when a client attaches to a buffer as follows:
 | 
			
		||||
--- ```lua
 | 
			
		||||
--- vim.api.nvim_create_autocmd('LspAttach', {
 | 
			
		||||
---   callback = function(args)
 | 
			
		||||
---     local client = vim.lsp.get_client_by_id(args.data.client_id)
 | 
			
		||||
---
 | 
			
		||||
---     if client:supports_method('textDocument/documentColor') then
 | 
			
		||||
---     vim.lsp.document_color.enable(true, args.buf)
 | 
			
		||||
---   end
 | 
			
		||||
---   end
 | 
			
		||||
--- })
 | 
			
		||||
--- ```
 | 
			
		||||
---
 | 
			
		||||
@@ -307,7 +304,7 @@ api.nvim_create_autocmd('ColorScheme', {
 | 
			
		||||
    for _, bufnr in ipairs(api.nvim_list_bufs()) do
 | 
			
		||||
      buf_clear(bufnr)
 | 
			
		||||
      if api.nvim_buf_is_loaded(bufnr) and bufstates[bufnr].enabled then
 | 
			
		||||
        buf_refresh(bufnr)
 | 
			
		||||
        M._buf_refresh(bufnr)
 | 
			
		||||
      else
 | 
			
		||||
        reset_bufstate(bufnr, false)
 | 
			
		||||
      end
 | 
			
		||||
 
 | 
			
		||||
@@ -128,6 +128,15 @@ RSC[ms.client_registerCapability] = function(_, params, ctx)
 | 
			
		||||
  for bufnr in pairs(client.attached_buffers) do
 | 
			
		||||
    vim.lsp._set_defaults(client, bufnr)
 | 
			
		||||
  end
 | 
			
		||||
  for _, reg in ipairs(params.registrations) do
 | 
			
		||||
    if reg.method == ms.textDocument_documentColor then
 | 
			
		||||
      for bufnr in pairs(client.attached_buffers) do
 | 
			
		||||
        if vim.lsp.document_color.is_enabled(bufnr) then
 | 
			
		||||
          vim.lsp.document_color._buf_refresh(bufnr, client.id)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  return vim.NIL
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -533,7 +533,7 @@ function protocol.make_client_capabilities()
 | 
			
		||||
        dynamicRegistration = false,
 | 
			
		||||
      },
 | 
			
		||||
      colorProvider = {
 | 
			
		||||
        dynamicRegistration = false,
 | 
			
		||||
        dynamicRegistration = true,
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    workspace = {
 | 
			
		||||
 
 | 
			
		||||
@@ -115,6 +115,49 @@ body {
 | 
			
		||||
    screen:expect({ grid = grid_without_colors })
 | 
			
		||||
  end)
 | 
			
		||||
 | 
			
		||||
  it('supports dynamic registration', function()
 | 
			
		||||
    local grid_with_dynamic_highlights = [[
 | 
			
		||||
  body {                                               |
 | 
			
		||||
    {2:color}: {2:#FFF};                                       |
 | 
			
		||||
    background-color: {3:rgb(0, 255, 255)};                |
 | 
			
		||||
  }                                                    |
 | 
			
		||||
  ^                                                     |
 | 
			
		||||
  {1:~                                                    }|*8
 | 
			
		||||
                                                       |
 | 
			
		||||
    ]]
 | 
			
		||||
 | 
			
		||||
    exec_lua(function()
 | 
			
		||||
      _G.server2 = _G._create_server({
 | 
			
		||||
        colorProvider = {
 | 
			
		||||
          documentSelector = nil,
 | 
			
		||||
        },
 | 
			
		||||
        handlers = {
 | 
			
		||||
          ['textDocument/documentColor'] = function(_, _, callback)
 | 
			
		||||
            callback(nil, {
 | 
			
		||||
              {
 | 
			
		||||
                range = {
 | 
			
		||||
                  start = { line = 1, character = 2 },
 | 
			
		||||
                  ['end'] = { line = 1, character = 7 },
 | 
			
		||||
                },
 | 
			
		||||
                color = { red = 1, green = 1, blue = 1 },
 | 
			
		||||
              },
 | 
			
		||||
            })
 | 
			
		||||
          end,
 | 
			
		||||
        },
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      local client_id2 = assert(vim.lsp.start({ name = 'dummy2', cmd = _G.server2.cmd }))
 | 
			
		||||
 | 
			
		||||
      vim.lsp.handlers['client/registerCapability'](nil, {
 | 
			
		||||
        registrations = {
 | 
			
		||||
          { id = 'documentColor', method = 'textDocument/documentColor' },
 | 
			
		||||
        },
 | 
			
		||||
      }, { client_id = client_id2, method = 'client/registerCapability' })
 | 
			
		||||
    end)
 | 
			
		||||
 | 
			
		||||
    screen:expect({ grid = grid_with_dynamic_highlights })
 | 
			
		||||
  end)
 | 
			
		||||
 | 
			
		||||
  it('does not clear document colors when one of several clients detaches', function()
 | 
			
		||||
    local client_id2 = exec_lua(function()
 | 
			
		||||
      _G.server2 = _G._create_server({
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user