Skip to content

Commit

Permalink
fix: handling of insert into single line files without newlines
Browse files Browse the repository at this point in the history
  • Loading branch information
sminez committed Mar 5, 2025
1 parent ecf526e commit 348f313
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 3 deletions.
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ test:

.PHONY: watch-test
watch-test:
cargo nextest run --workspace
git ls-files | entr -ac cargo nextest run --workspace $(ARGS)

.PHONY: doc
Expand Down
34 changes: 32 additions & 2 deletions src/buffer/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,17 @@ impl GapBuffer {
) -> usize {
let mut to = usize::MAX;

if self.line_endings.is_empty() && char_idx == self.len_chars().saturating_sub(1) {
return if self.gap_end == self.cap {
self.gap_start.saturating_sub(1)
} else {
// SAFETY: we know that we have valid data at the end of the buffer as
// self.gap_end != self.cap, so decoding the final character is valid
let ch = unsafe { decode_char_ending_at(self.cap - 1, &self.data) };
self.cap - ch.len_utf8()
};
}

for (&b, &c) in self
.line_endings
.iter()
Expand All @@ -800,8 +811,10 @@ impl GapBuffer {
cur = chars.cur + byte_offset;
}

if cur > self.gap_start && cur < self.gap_end {
cur += self.gap()
let slice_enclosed_gap = self.gap_start >= byte_offset && self.gap_end <= to;
// Cur landed inside the gap or we counted over the gap while iterating the slice above
if cur > self.gap_start && (cur <= self.gap_end || slice_enclosed_gap) {
cur += self.gap();
}

cur
Expand Down Expand Up @@ -1733,4 +1746,21 @@ mod tests {
assert_eq!(gb.char(idx), ch);
}
}

#[test]
fn char_to_raw_byte_line_end_with_no_newlines() {
let mut gb =
GapBuffer::from("// does it need to be a doc comment? that is a long enough line to");
gb.move_gap_to(0);
assert_eq!(gb.char_to_raw_byte(65), 129);
gb.move_gap_to(10);
assert_eq!(gb.char_to_raw_byte(65), 129);
gb.move_gap_to(66);
assert_eq!(gb.char_to_raw_byte(65), 65);
gb.insert_char(66, '\n');
assert_eq!(
gb.to_string(),
"// does it need to be a doc comment? that is a long enough line to\n"
);
}
}
16 changes: 16 additions & 0 deletions src/buffer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1461,4 +1461,20 @@ pub(crate) mod tests {
b.handle_raw_input(Input::Return);
assert_eq!(b.txt.to_string(), " foo\n ");
}

#[test]
fn set_dot_eob_single_line_buffer() {
let mut b = Buffer::new_virtual(
0,
"test",
"// does it need to be a doc comment? that is a long enough line to",
);
b.set_dot(TextObject::BufferEnd, 1);
b.handle_raw_input(Input::Return);

assert_eq!(
b.txt.to_string(),
"// does it need to be a doc comment? that is a long enough line to\n"
);
}
}

0 comments on commit 348f313

Please sign in to comment.