aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--helix-term/src/commands.rs20
-rw-r--r--helix-term/tests/test/commands.rs46
2 files changed, 56 insertions, 10 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index cd053266..e557977a 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -4391,10 +4391,9 @@ fn join_selections_impl(cx: &mut Context, select_space: bool) {
use movement::skip_while;
let (view, doc) = current!(cx.editor);
let text = doc.text();
- let slice = doc.text().slice(..);
+ let slice = text.slice(..);
let mut changes = Vec::new();
- let fragment = Tendril::from(" ");
for selection in doc.selection(view.id) {
let (start, mut end) = selection.line_range(slice);
@@ -4410,9 +4409,13 @@ fn join_selections_impl(cx: &mut Context, select_space: bool) {
let mut end = text.line_to_char(line + 1);
end = skip_while(slice, end, |ch| matches!(ch, ' ' | '\t')).unwrap_or(end);
- // need to skip from start, not end
- let change = (start, end, Some(fragment.clone()));
- changes.push(change);
+ let separator = if end == line_end_char_index(&slice, line + 1) {
+ // the joining line contains only space-characters => don't include a whitespace when joining
+ None
+ } else {
+ Some(Tendril::from(" "))
+ };
+ changes.push((start, end, separator));
}
}
@@ -4424,9 +4427,6 @@ fn join_selections_impl(cx: &mut Context, select_space: bool) {
changes.sort_unstable_by_key(|(from, _to, _text)| *from);
changes.dedup();
- // TODO: joining multiple empty lines should be replaced by a single space.
- // need to merge change ranges that touch
-
// select inserted spaces
let transaction = if select_space {
let ranges: SmallVec<_> = changes
@@ -4438,9 +4438,9 @@ fn join_selections_impl(cx: &mut Context, select_space: bool) {
})
.collect();
let selection = Selection::new(ranges, 0);
- Transaction::change(doc.text(), changes.into_iter()).with_selection(selection)
+ Transaction::change(text, changes.into_iter()).with_selection(selection)
} else {
- Transaction::change(doc.text(), changes.into_iter())
+ Transaction::change(text, changes.into_iter())
};
doc.apply(&transaction, view.id);
diff --git a/helix-term/tests/test/commands.rs b/helix-term/tests/test/commands.rs
index b3e13551..e52b142c 100644
--- a/helix-term/tests/test/commands.rs
+++ b/helix-term/tests/test/commands.rs
@@ -480,3 +480,49 @@ fn bar() {#(\n|)#\
Ok(())
}
+
+#[tokio::test(flavor = "multi_thread")]
+async fn test_join_selections() -> anyhow::Result<()> {
+ // normal join
+ test((
+ platform_line(indoc! {"\
+ #[a|]#bc
+ def
+ "}),
+ "J",
+ platform_line(indoc! {"\
+ #[a|]#bc def
+ "}),
+ ))
+ .await?;
+
+ // join with empty line
+ test((
+ platform_line(indoc! {"\
+ #[a|]#bc
+
+ def
+ "}),
+ "JJ",
+ platform_line(indoc! {"\
+ #[a|]#bc def
+ "}),
+ ))
+ .await?;
+
+ // join with additional space in non-empty line
+ test((
+ platform_line(indoc! {"\
+ #[a|]#bc
+
+ def
+ "}),
+ "JJ",
+ platform_line(indoc! {"\
+ #[a|]#bc def
+ "}),
+ ))
+ .await?;
+
+ Ok(())
+}