mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	fix(lsp): handle textDocumentSync.save bool capability (#18332)
Follow up to https://github.com/neovim/neovim/pull/17814
This commit is contained in:
		 Mathias Fußenegger
					Mathias Fußenegger
				
			
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			 GitHub
						GitHub
					
				
			
						parent
						
							cc27540560
						
					
				
				
					commit
					0344736aa6
				
			| @@ -1208,10 +1208,11 @@ function lsp._text_document_did_save_handler(bufnr) | |||||||
|   bufnr = resolve_bufnr(bufnr) |   bufnr = resolve_bufnr(bufnr) | ||||||
|   local uri = vim.uri_from_bufnr(bufnr) |   local uri = vim.uri_from_bufnr(bufnr) | ||||||
|   local text = once(buf_get_full_text) |   local text = once(buf_get_full_text) | ||||||
|   for_each_buffer_client(bufnr, function(client, _client_id) |   for_each_buffer_client(bufnr, function(client) | ||||||
|     if vim.tbl_get(client.server_capabilities, "textDocumentSync", "save") then |     local save_capability = vim.tbl_get(client.server_capabilities, "textDocumentSync", "save") | ||||||
|  |     if save_capability then | ||||||
|       local included_text |       local included_text | ||||||
|       if vim.tbl_get(client.server_capabilities, "textDocumentSync", "save", "includeText") then |       if type(save_capability) == "table" and save_capability.includeText then | ||||||
|         included_text = text(bufnr) |         included_text = text(bufnr) | ||||||
|       end |       end | ||||||
|       client.notify('textDocument/didSave', { |       client.notify('textDocument/didSave', { | ||||||
|   | |||||||
| @@ -28,7 +28,10 @@ local function assert_eq(a, b, ...) | |||||||
|   if not vim.deep_equal(a, b) then |   if not vim.deep_equal(a, b) then | ||||||
|     error(message_parts(": ", |     error(message_parts(": ", | ||||||
|       ..., "assert_eq failed", |       ..., "assert_eq failed", | ||||||
|       string.format("left == %q, right == %q", vim.inspect(a), vim.inspect(b)) |       string.format("left == %q, right == %q", | ||||||
|  |         table.concat(vim.split(vim.inspect(a), "\n"), ""), | ||||||
|  |         table.concat(vim.split(vim.inspect(b), "\n"), "") | ||||||
|  |       ) | ||||||
|     )) |     )) | ||||||
|   end |   end | ||||||
| end | end | ||||||
| @@ -245,6 +248,51 @@ function tests.basic_check_capabilities() | |||||||
|   } |   } | ||||||
| end | end | ||||||
|  |  | ||||||
|  | function tests.text_document_sync_save_bool() | ||||||
|  |   skeleton { | ||||||
|  |     on_init = function() | ||||||
|  |       return { | ||||||
|  |         capabilities = { | ||||||
|  |           textDocumentSync = { | ||||||
|  |             save = true | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     end; | ||||||
|  |     body = function() | ||||||
|  |       notify('start') | ||||||
|  |       expect_notification('textDocument/didSave', {textDocument = { uri = "file://" }}) | ||||||
|  |       notify('shutdown') | ||||||
|  |     end; | ||||||
|  |   } | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function tests.text_document_sync_save_includeText() | ||||||
|  |   skeleton { | ||||||
|  |     on_init = function() | ||||||
|  |       return { | ||||||
|  |         capabilities = { | ||||||
|  |           textDocumentSync = { | ||||||
|  |             save = { | ||||||
|  |               includeText = true | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     end; | ||||||
|  |     body = function() | ||||||
|  |       notify('start') | ||||||
|  |       expect_notification('textDocument/didSave', { | ||||||
|  |         textDocument = { | ||||||
|  |           uri = "file://" | ||||||
|  |         }, | ||||||
|  |         text = "help me\n" | ||||||
|  |       }) | ||||||
|  |       notify('shutdown') | ||||||
|  |     end; | ||||||
|  |   } | ||||||
|  | end | ||||||
|  |  | ||||||
| function tests.capabilities_for_client_supports_method() | function tests.capabilities_for_client_supports_method() | ||||||
|   skeleton { |   skeleton { | ||||||
|     on_init = function(params) |     on_init = function(params) | ||||||
|   | |||||||
| @@ -421,6 +421,67 @@ describe('LSP', function() | |||||||
|       } |       } | ||||||
|     end) |     end) | ||||||
|  |  | ||||||
|  |     it('_text_document_did_save_handler sends didSave with bool textDocumentSync.save', function() | ||||||
|  |       local expected_handlers = { | ||||||
|  |         {NIL, {}, {method="shutdown", client_id=1}}; | ||||||
|  |         {NIL, {}, {method="start", client_id=1}}; | ||||||
|  |       } | ||||||
|  |       local client | ||||||
|  |       test_rpc_server { | ||||||
|  |         test_name = "text_document_sync_save_bool"; | ||||||
|  |         on_init = function(c) | ||||||
|  |           client = c | ||||||
|  |         end; | ||||||
|  |         on_exit = function(code, signal) | ||||||
|  |           eq(0, code, "exit code", fake_lsp_logfile) | ||||||
|  |           eq(0, signal, "exit signal", fake_lsp_logfile) | ||||||
|  |         end; | ||||||
|  |         on_handler = function(err, result, ctx) | ||||||
|  |           eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler") | ||||||
|  |           if ctx.method == "start" then | ||||||
|  |             exec_lua([=[ | ||||||
|  |               BUFFER = vim.api.nvim_get_current_buf() | ||||||
|  |               lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID) | ||||||
|  |               lsp._text_document_did_save_handler(BUFFER) | ||||||
|  |             ]=]) | ||||||
|  |           else | ||||||
|  |             client.stop() | ||||||
|  |           end | ||||||
|  |         end; | ||||||
|  |       } | ||||||
|  |     end) | ||||||
|  |  | ||||||
|  |     it('_text_document_did_save_handler sends didSave including text if server capability is set', function() | ||||||
|  |       local expected_handlers = { | ||||||
|  |         {NIL, {}, {method="shutdown", client_id=1}}; | ||||||
|  |         {NIL, {}, {method="start", client_id=1}}; | ||||||
|  |       } | ||||||
|  |       local client | ||||||
|  |       test_rpc_server { | ||||||
|  |         test_name = "text_document_sync_save_includeText"; | ||||||
|  |         on_init = function(c) | ||||||
|  |           client = c | ||||||
|  |         end; | ||||||
|  |         on_exit = function(code, signal) | ||||||
|  |           eq(0, code, "exit code", fake_lsp_logfile) | ||||||
|  |           eq(0, signal, "exit signal", fake_lsp_logfile) | ||||||
|  |         end; | ||||||
|  |         on_handler = function(err, result, ctx) | ||||||
|  |           eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler") | ||||||
|  |           if ctx.method == "start" then | ||||||
|  |             exec_lua([=[ | ||||||
|  |               BUFFER = vim.api.nvim_get_current_buf() | ||||||
|  |               vim.api.nvim_buf_set_lines(BUFFER, 0, -1, true, {"help me"}) | ||||||
|  |               lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID) | ||||||
|  |               lsp._text_document_did_save_handler(BUFFER) | ||||||
|  |             ]=]) | ||||||
|  |           else | ||||||
|  |             client.stop() | ||||||
|  |           end | ||||||
|  |         end; | ||||||
|  |       } | ||||||
|  |     end) | ||||||
|  |  | ||||||
|     it('client.supports_methods() should validate capabilities', function() |     it('client.supports_methods() should validate capabilities', function() | ||||||
|       local expected_handlers = { |       local expected_handlers = { | ||||||
|         {NIL, {}, {method="shutdown", client_id=1}}; |         {NIL, {}, {method="shutdown", client_id=1}}; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user