From b9933fdaaa052a90f98f7d710de8bcf12faeed0c Mon Sep 17 00:00:00 2001 From: Martin Huschenbett Date: Sat, 30 Dec 2023 19:21:35 +0100 Subject: [PATCH] minor: Simplify implementation of apply_document_changes While reading through the code base, I stumbled across a piece of code that I found hard to read despite its simple purpose. This is my attempt at making the code easier to understand for future readers. I won't be offended if this is too minor and not worth your time. --- crates/rust-analyzer/src/lsp/utils.rs | 35 +++++++++------------------ 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/crates/rust-analyzer/src/lsp/utils.rs b/crates/rust-analyzer/src/lsp/utils.rs index b388b317599a..a4417e4d4a14 100644 --- a/crates/rust-analyzer/src/lsp/utils.rs +++ b/crates/rust-analyzer/src/lsp/utils.rs @@ -171,30 +171,19 @@ pub(crate) fn apply_document_changes( file_contents: impl FnOnce() -> String, mut content_changes: Vec, ) -> String { - // Skip to the last full document change, as it invalidates all previous changes anyways. - let mut start = content_changes - .iter() - .rev() - .position(|change| change.range.is_none()) - .map(|idx| content_changes.len() - idx - 1) - .unwrap_or(0); - - let mut text: String = match content_changes.get_mut(start) { - // peek at the first content change as an optimization - Some(lsp_types::TextDocumentContentChangeEvent { range: None, text, .. }) => { - let text = mem::take(text); - start += 1; - - // The only change is a full document update - if start == content_changes.len() { - return text; + // If at least one of the changes is a full document change, use the last + // of them as the starting point and ignore all previous changes. + let (mut text, content_changes) = + match content_changes.iter().rposition(|change| change.range.is_none()) { + Some(idx) => { + let text = mem::take(&mut content_changes[idx].text); + (text, &content_changes[idx + 1..]) } - text - } - Some(_) => file_contents(), - // we received no content changes - None => return file_contents(), - }; + None => (file_contents(), &content_changes[..]), + }; + if content_changes.is_empty() { + return text; + } let mut line_index = LineIndex { // the index will be overwritten in the bottom loop's first iteration