Skip to content

Commit ef221ab

Browse files
authored
Prevent a panic when uncommenting a line with only a comment token (#5933)
Open a new document `test.rs` and type the following: `di//<esc><C-c>` The margin calculation pushes the range out of bounds for the comment marker when there are no characters (newline) after it. thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Char range out of bounds: char range 0..3, Rope/RopeSlice char length 2', ropey-1.6.0/src/rope.rs:546:37 The debug build catches the error in the transaction: thread 'main' panicked at 'attempt to subtract with overflow', helix-core/src/transaction.rs:503:26
1 parent a4751db commit ef221ab

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

helix-core/src/comment.rs

+14-3
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ fn find_line_comment(
4545

4646
// determine margin of 0 or 1 for uncommenting; if any comment token is not followed by a space,
4747
// a margin of 0 is used for all lines.
48-
if matches!(line_slice.get_char(pos + token_len), Some(c) if c != ' ') {
48+
if !matches!(line_slice.get_char(pos + token_len), Some(c) if c == ' ') {
4949
margin = 0;
5050
}
5151

@@ -108,8 +108,8 @@ mod test {
108108
let text = doc.slice(..);
109109

110110
let res = find_line_comment("//", text, 0..3);
111-
// (commented = true, to_change = [line 0, line 2], min = col 2, margin = 1)
112-
assert_eq!(res, (false, vec![0, 2], 2, 1));
111+
// (commented = true, to_change = [line 0, line 2], min = col 2, margin = 0)
112+
assert_eq!(res, (false, vec![0, 2], 2, 0));
113113

114114
// comment
115115
let transaction = toggle_line_comments(&doc, &selection, None);
@@ -136,6 +136,17 @@ mod test {
136136
assert_eq!(doc, " 1\n\n 2\n 3");
137137
assert!(selection.len() == 1); // to ignore the selection unused warning
138138

139+
// 0 margin comments, with no space
140+
doc = Rope::from("//");
141+
// reset the selection.
142+
selection = Selection::single(0, doc.len_chars() - 1);
143+
144+
let transaction = toggle_line_comments(&doc, &selection, None);
145+
transaction.apply(&mut doc);
146+
selection = selection.map(transaction.changes());
147+
assert_eq!(doc, "");
148+
assert!(selection.len() == 1); // to ignore the selection unused warning
149+
139150
// TODO: account for uncommenting with uneven comment indentation
140151
}
141152
}

0 commit comments

Comments
 (0)