on master help sign in
Fix the infinite loop when copying the cursor to the top of the file (#5888)

Example: ``` test testitem ``` Select line 2 with x, then type Alt-C; Helix will go into an infinite loop. The saturating_sub keeps the head_row and anchor_row pinned at 0, and a selection is never made since the first line is too short.

commit9d73a0d1128f8237eef2d4bf475496d4db081df2 authorMike Trinkala <trink@acm.org> dateThu 9 Feb 2023, 06:28 (4 years ago) parent7ebcf4e
2 files changed+68
helix-term/src/commands.rs+4 helix-term/tests/test/commands.rs+64
helix-term/src/commands.rs+4
@@ -1617,6 +1617,10 @@ fn copy_selection_on_line(cx: &mut Context, direction: Direction) {
16171617 sels += 1;
16181618 }
16191619
1620+ if anchor_row == 0 && head_row == 0 {
1621+ break;
1622+ }
1623+
16201624 i += 1;
16211625 }
16221626 }
helix-term/tests/test/commands.rs+64
@@ -132,6 +132,70 @@ async fn test_selection_duplication() -> anyhow::Result<()> {
132132 .as_str(),
133133 ))
134134 .await?;
135+
136+ // Copy the selection to previous line, skipping the first line in the file
137+ test((
138+ platform_line(indoc! {"\
139+ test
140+ #[testitem|]#
141+ "})
142+ .as_str(),
143+ "<A-C>",
144+ platform_line(indoc! {"\
145+ test
146+ #[testitem|]#
147+ "})
148+ .as_str(),
149+ ))
150+ .await?;
151+
152+ // Copy the selection to previous line, including the first line in the file
153+ test((
154+ platform_line(indoc! {"\
155+ test
156+ #[test|]#
157+ "})
158+ .as_str(),
159+ "<A-C>",
160+ platform_line(indoc! {"\
161+ #[test|]#
162+ #(test|)#
163+ "})
164+ .as_str(),
165+ ))
166+ .await?;
167+
168+ // Copy the selection to next line, skipping the last line in the file
169+ test((
170+ platform_line(indoc! {"\
171+ #[testitem|]#
172+ test
173+ "})
174+ .as_str(),
175+ "C",
176+ platform_line(indoc! {"\
177+ #[testitem|]#
178+ test
179+ "})
180+ .as_str(),
181+ ))
182+ .await?;
183+
184+ // Copy the selection to next line, including the last line in the file
185+ test((
186+ platform_line(indoc! {"\
187+ #[test|]#
188+ test
189+ "})
190+ .as_str(),
191+ "C",
192+ platform_line(indoc! {"\
193+ #(test|)#
194+ #[test|]#
195+ "})
196+ .as_str(),
197+ ))
198+ .await?;
135199 Ok(())
136200}
137201