From 22abe5ea6cd922657a9671ed6e1adfc48d3deeb0 Mon Sep 17 00:00:00 2001 From: Alexander Wang <98280966+AlexanderWangY@users.noreply.github.com> Date: Fri, 13 Feb 2026 04:36:51 -0500 Subject: [PATCH] Preserve new line on exchanges (x) with empty hold spaces. (#259) * fix: remove newline swap in exchange and swap content only * fix: support non empty hold spaces and newline appended hold spaces * nit: period in comment * nit: useless comment removal * chore: clarify newline swap logic for `x` --- src/sed/processor.rs | 6 +++++- tests/by-util/test_sed.rs | 11 +++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/sed/processor.rs b/src/sed/processor.rs index a2d33e0..070c815 100644 --- a/src/sed/processor.rs +++ b/src/sed/processor.rs @@ -631,8 +631,12 @@ fn process_file( 'x' => { // Exchange the contents of the pattern and hold spaces. let (pat_content, pat_has_newline) = pattern.fields_mut()?; + + // Swap newline if hold space is logically non-empty. + if !context.hold.content.is_empty() || context.hold.has_newline { + std::mem::swap(pat_has_newline, &mut context.hold.has_newline); + } std::mem::swap(pat_content, &mut context.hold.content); - std::mem::swap(pat_has_newline, &mut context.hold.has_newline); } 'y' => { let trans = extract_variant!(command, Transliteration); diff --git a/tests/by-util/test_sed.rs b/tests/by-util/test_sed.rs index 9091dc9..0d43957 100644 --- a/tests/by-util/test_sed.rs +++ b/tests/by-util/test_sed.rs @@ -1195,3 +1195,14 @@ fn test_print_command_adds_newline() { .succeeds() .stdout_is("foo\nfoo"); } + +//////////////////////////////////////////////////////////// +// Test for issue #254: Missing newline in exchanged output with `2x` +#[test] +fn test_exchange_command_adds_newline() { + new_ucmd!() + .args(&["2x"]) + .pipe_in("a\nb\nc\n") + .succeeds() + .stdout_is("a\n\nc\n"); +}