Skip to content

Fix replacement edit range computation#12171

Merged
dhruvmanila merged 1 commit intomainfrom
dhruv/fix-replacement
Jul 4, 2024
Merged

Fix replacement edit range computation#12171
dhruvmanila merged 1 commit intomainfrom
dhruv/fix-replacement

Conversation

@dhruvmanila
Copy link
Copy Markdown
Member

Summary

This PR fixes various bugs for computing the replacement range between the original and modified source for the language server.

  1. When finding the end offset of the source and modified range, we should apply zip on the reversed iterator. The bug was that it was reversing the already zipped iterator. The problem here is that the length of both slices aren't going to be the same unless the source wasn't modified at all. Refer to the Rust playground where you can see this in action.
  2. Skip the first line when computing the start offset because the first line start value will always be 0 and the default value of the source / modified range start is also 0. So, comparing 0 and 0 is not useful which means we can skip the first value.
  3. While iterating in the reverse direction, we should only stop if the line start is strictly less than the source start i.e., we should use < instead of <=.

fixes: #12128

Test Plan

Add test cases where the text is being inserted, deleted, and replaced between the original and new source code, validate the replacement ranges.

@dhruvmanila dhruvmanila added the bug Something isn't working label Jul 3, 2024
Comment on lines +24 to +25
.zip(modified_line_starts.iter().copied())
.skip(1)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipping the first line start i.e., change (2)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it guaranteed that source_line_starts[0] == TextSize::new(0)?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes:

impl LineIndex {
/// Builds the [`LineIndex`] from the source text of a file.
pub fn from_source_text(text: &str) -> Self {
let mut line_starts: Vec<TextSize> = Vec::with_capacity(text.len() / 88);
line_starts.push(TextSize::default());

Comment on lines -38 to +43
for (old_line_start, new_line_start) in line_iter.by_ref() {
if old_line_start <= source_start
|| new_line_start <= replaced_start
|| source[TextRange::new(old_line_start, source_end)]
!= modified[TextRange::new(new_line_start, replaced_end)]
for (source_line_start, modified_line_start) in source_line_starts
.iter()
.rev()
.copied()
.zip(modified_line_starts.iter().rev().copied())
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The zip and rev bug u.e., change (1)

Comment on lines -38 to +46
for (old_line_start, new_line_start) in line_iter.by_ref() {
if old_line_start <= source_start
|| new_line_start <= replaced_start
|| source[TextRange::new(old_line_start, source_end)]
!= modified[TextRange::new(new_line_start, replaced_end)]
for (source_line_start, modified_line_start) in source_line_starts
.iter()
.rev()
.copied()
.zip(modified_line_starts.iter().rev().copied())
{
if source_line_start < source_start
|| modified_line_start < modified_start
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switching from <= to < i.e., change (3)

@MichaReiser MichaReiser added the server Related to the LSP server label Jul 3, 2024
Comment on lines +24 to +25
.zip(modified_line_starts.iter().copied())
.skip(1)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it guaranteed that source_line_starts[0] == TextSize::new(0)?

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jul 3, 2024

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

@dhruvmanila dhruvmanila merged commit d870720 into main Jul 4, 2024
@dhruvmanila dhruvmanila deleted the dhruv/fix-replacement branch July 4, 2024 03:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working server Related to the LSP server

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cursor jumps to bottom of file when auto-formatting on save

2 participants