From b70b856c7d4b6b5f668e04990b288165353400f8 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Fri, 29 Sep 2023 12:25:37 -0700 Subject: [PATCH] Add support for the TextDocumentSyncKind LSP option (#3070) fixes https://github.com/zed-industries/community/issues/2098 Release Notes: - Fixed a bug in Zed's LSP implementation when using Next LS. --- crates/project/src/project.rs | 70 ++++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 17 deletions(-) diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index a551b985bf..94180bc023 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -2231,26 +2231,62 @@ impl Project { .get_mut(&buffer.remote_id()) .and_then(|m| m.get_mut(&language_server.server_id()))?; let previous_snapshot = buffer_snapshots.last()?; - let next_version = previous_snapshot.version + 1; - let content_changes = buffer - .edits_since::<(PointUtf16, usize)>(previous_snapshot.snapshot.version()) - .map(|edit| { - let edit_start = edit.new.start.0; - let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0); - let new_text = next_snapshot - .text_for_range(edit.new.start.1..edit.new.end.1) - .collect(); - lsp::TextDocumentContentChangeEvent { - range: Some(lsp::Range::new( - point_to_lsp(edit_start), - point_to_lsp(edit_end), - )), + let build_incremental_change = || { + buffer + .edits_since::<(PointUtf16, usize)>( + previous_snapshot.snapshot.version(), + ) + .map(|edit| { + let edit_start = edit.new.start.0; + let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0); + let new_text = next_snapshot + .text_for_range(edit.new.start.1..edit.new.end.1) + .collect(); + lsp::TextDocumentContentChangeEvent { + range: Some(lsp::Range::new( + point_to_lsp(edit_start), + point_to_lsp(edit_end), + )), + range_length: None, + text: new_text, + } + }) + .collect() + }; + + let document_sync_kind = language_server + .capabilities() + .text_document_sync + .as_ref() + .and_then(|sync| match sync { + lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind), + lsp::TextDocumentSyncCapability::Options(options) => options.change, + }); + + let content_changes: Vec<_> = match document_sync_kind { + Some(lsp::TextDocumentSyncKind::FULL) => { + vec![lsp::TextDocumentContentChangeEvent { + range: None, range_length: None, - text: new_text, + text: next_snapshot.text(), + }] + } + Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(), + _ => { + #[cfg(any(test, feature = "test-support"))] + { + build_incremental_change() } - }) - .collect(); + + #[cfg(not(any(test, feature = "test-support")))] + { + continue; + } + } + }; + + let next_version = previous_snapshot.version + 1; buffer_snapshots.push(LspBufferSnapshot { version: next_version,