mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	feat(lsp): add support for completionItem.command resolving
`command` was already resolved via a `completionItem/resolve` request but only if `additionalTextEdits` were also present, and the `resolveSupport` capability wasn't listed. Closes https://github.com/neovim/neovim/issues/32406
This commit is contained in:
		 Mathias Fussenegger
					Mathias Fussenegger
				
			
				
					committed by
					
						 Mathias Fußenegger
						Mathias Fußenegger
					
				
			
			
				
	
			
			
			 Mathias Fußenegger
						Mathias Fußenegger
					
				
			
						parent
						
							c091bc3b9a
						
					
				
				
					commit
					f20335a54c
				
			| @@ -610,13 +610,14 @@ local function on_complete_done() | ||||
|       clear_word() | ||||
|       if err then | ||||
|         vim.notify_once(err.message, vim.log.levels.WARN) | ||||
|       elseif result and result.additionalTextEdits then | ||||
|       elseif result then | ||||
|         if result.additionalTextEdits then | ||||
|           lsp.util.apply_text_edits(result.additionalTextEdits, bufnr, position_encoding) | ||||
|         end | ||||
|         if result.command then | ||||
|           completion_item.command = result.command | ||||
|         end | ||||
|       end | ||||
|  | ||||
|       apply_snippet_and_command() | ||||
|     end, bufnr) | ||||
|   else | ||||
|   | ||||
| @@ -458,6 +458,7 @@ function protocol.make_client_capabilities() | ||||
|           resolveSupport = { | ||||
|             properties = { | ||||
|               'additionalTextEdits', | ||||
|               'command', | ||||
|             }, | ||||
|           }, | ||||
|           tagSupport = { | ||||
|   | ||||
| @@ -770,20 +770,25 @@ end) | ||||
|  | ||||
| --- @param name string | ||||
| --- @param completion_result lsp.CompletionList | ||||
| --- @param trigger_chars? string[] | ||||
| --- @param opts? {trigger_chars?: string[], resolve_result?: lsp.CompletionItem} | ||||
| --- @return integer | ||||
| local function create_server(name, completion_result, trigger_chars) | ||||
| local function create_server(name, completion_result, opts) | ||||
|   opts = opts or {} | ||||
|   return exec_lua(function() | ||||
|     local server = _G._create_server({ | ||||
|       capabilities = { | ||||
|         completionProvider = { | ||||
|           triggerCharacters = trigger_chars or { '.' }, | ||||
|           triggerCharacters = opts.trigger_chars or { '.' }, | ||||
|           resolveProvider = opts.resolve_result ~= nil, | ||||
|         }, | ||||
|       }, | ||||
|       handlers = { | ||||
|         ['textDocument/completion'] = function(_, _, callback) | ||||
|           callback(nil, completion_result) | ||||
|         end, | ||||
|         ['completionItem/resolve'] = function(_, _, callback) | ||||
|           callback(nil, opts.resolve_result) | ||||
|         end, | ||||
|       }, | ||||
|     }) | ||||
|  | ||||
| @@ -794,7 +799,7 @@ local function create_server(name, completion_result, trigger_chars) | ||||
|       cmd = server.cmd, | ||||
|       on_attach = function(client, bufnr0) | ||||
|         vim.lsp.completion.enable(true, client.id, bufnr0, { | ||||
|           autotrigger = trigger_chars ~= nil, | ||||
|           autotrigger = opts.trigger_chars ~= nil, | ||||
|           convert = function(item) | ||||
|             return { abbr = item.label:gsub('%b()', '') } | ||||
|           end, | ||||
| @@ -968,7 +973,7 @@ describe('vim.lsp.completion: protocol', function() | ||||
|         }, | ||||
|       }, | ||||
|     } | ||||
|     create_server('dummy1', results1, { 'e' }) | ||||
|     create_server('dummy1', results1, { trigger_chars = { 'e' } }) | ||||
|     local results2 = { | ||||
|       isIncomplete = false, | ||||
|       items = { | ||||
| @@ -977,7 +982,7 @@ describe('vim.lsp.completion: protocol', function() | ||||
|         }, | ||||
|       }, | ||||
|     } | ||||
|     create_server('dummy2', results2, { 'h' }) | ||||
|     create_server('dummy2', results2, { trigger_chars = { 'h' } }) | ||||
|  | ||||
|     feed('h') | ||||
|     exec_lua(function() | ||||
| @@ -1042,6 +1047,59 @@ describe('vim.lsp.completion: protocol', function() | ||||
|     end) | ||||
|   end) | ||||
|  | ||||
|   it('resolves and executes commands', function() | ||||
|     local completion_list = { | ||||
|       isIncomplete = false, | ||||
|       items = { | ||||
|         { | ||||
|           label = 'hello', | ||||
|         }, | ||||
|       }, | ||||
|     } | ||||
|     local client_id = create_server('dummy', completion_list, { | ||||
|       resolve_result = { | ||||
|         label = 'hello', | ||||
|         command = { | ||||
|           arguments = { '1', '0' }, | ||||
|           command = 'dummy', | ||||
|           title = '', | ||||
|         }, | ||||
|       }, | ||||
|     }) | ||||
|     exec_lua(function() | ||||
|       _G.called = false | ||||
|       local client = assert(vim.lsp.get_client_by_id(client_id)) | ||||
|       client.commands.dummy = function() | ||||
|         _G.called = true | ||||
|       end | ||||
|     end) | ||||
|  | ||||
|     feed('ih') | ||||
|     trigger_at_pos({ 1, 1 }) | ||||
|  | ||||
|     local item = completion_list.items[1] | ||||
|     exec_lua(function() | ||||
|       vim.v.completed_item = { | ||||
|         user_data = { | ||||
|           nvim = { | ||||
|             lsp = { | ||||
|               client_id = client_id, | ||||
|               completion_item = item, | ||||
|             }, | ||||
|           }, | ||||
|         }, | ||||
|       } | ||||
|     end) | ||||
|  | ||||
|     feed('<C-x><C-o><C-y>') | ||||
|  | ||||
|     assert_matches(function(matches) | ||||
|       eq(1, #matches) | ||||
|       eq('hello', matches[1].word) | ||||
|       eq(true, exec_lua('return _G.called')) | ||||
|     end) | ||||
|   end) | ||||
|  | ||||
|   it('enable(…,{convert=fn}) custom word/abbr format', function() | ||||
|     create_server('dummy', { | ||||
|       isIncomplete = false, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user