diff --git a/book/src/generated/typable-cmd.md b/book/src/generated/typable-cmd.md index 219f6b95f..9912ec8f7 100644 --- a/book/src/generated/typable-cmd.md +++ b/book/src/generated/typable-cmd.md @@ -32,11 +32,9 @@ | `:cquit`, `:cq` | Quit with exit code (default 1). Accepts an optional integer exit code (:cq 2). | | `:cquit!`, `:cq!` | Force quit with exit code (default 1) ignoring unsaved changes. Accepts an optional integer exit code (:cq! 2). | | `:theme` | Change the editor theme (show current theme if no name specified). | -| `:yank-join` | Yank joined selections. A separator can be provided as first argument. Default value is newline. | +| `:yank-join`, `:yj` | Yank the selections joined with a separator | | `:clipboard-yank` | Yank main selection into system clipboard. | -| `:clipboard-yank-join` | Yank joined selections into system clipboard. A separator can be provided as first argument. Default value is newline. | | `:primary-clipboard-yank` | Yank main selection into system primary clipboard. | -| `:primary-clipboard-yank-join` | Yank joined selections into system primary clipboard. A separator can be provided as first argument. Default value is newline. | | `:clipboard-paste-after` | Paste system clipboard after selections. | | `:clipboard-paste-before` | Paste system clipboard before selections. | | `:clipboard-paste-replace` | Replace selections with content of system clipboard. | diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 200323e10..477b6f347 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -975,29 +975,23 @@ fn yank_joined(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> } let doc = doc!(cx.editor); - let default_sep = Cow::Borrowed(doc.line_ending.as_str()); - let separator = args.first().unwrap_or(&default_sep); - let register = cx - .editor - .selected_register - .unwrap_or(cx.editor.config().default_yank_register); + + let separator = args + .get_flag("separator") + .unwrap_or_else(|| doc.line_ending.as_str()); + + let register = args + .get_flag("register") + .map(|reg| { + reg.parse::() + .map_err(|_| anyhow!("Invalid register: {reg}")) + }) + .transpose()? + .or(cx.editor.selected_register) + .unwrap_or_else(|| cx.editor.config().default_yank_register); + yank_joined_impl(cx.editor, separator, register); - Ok(()) -} -fn yank_joined_to_clipboard( - cx: &mut compositor::Context, - args: Args, - event: PromptEvent, -) -> anyhow::Result<()> { - if event != PromptEvent::Validate { - return Ok(()); - } - - let doc = doc!(cx.editor); - let default_sep = Cow::Borrowed(doc.line_ending.as_str()); - let separator = args.first().unwrap_or(&default_sep); - yank_joined_impl(cx.editor, separator, '+'); Ok(()) } @@ -1014,22 +1008,6 @@ fn yank_main_selection_to_primary_clipboard( Ok(()) } -fn yank_joined_to_primary_clipboard( - cx: &mut compositor::Context, - args: Args, - event: PromptEvent, -) -> anyhow::Result<()> { - if event != PromptEvent::Validate { - return Ok(()); - } - - let doc = doc!(cx.editor); - let default_sep = Cow::Borrowed(doc.line_ending.as_str()); - let separator = args.first().unwrap_or(&default_sep); - yank_joined_impl(cx.editor, separator, '*'); - Ok(()) -} - fn paste_clipboard_after( cx: &mut compositor::Context, _args: Args, @@ -2939,12 +2917,26 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ }, TypableCommand { name: "yank-join", - aliases: &[], - doc: "Yank joined selections. A separator can be provided as first argument. Default value is newline.", + aliases: &["yj"], + doc: "Yank the selections joined with a separator", fun: yank_joined, completer: CommandCompleter::none(), signature: Signature { - positionals: (0, Some(1)), + positionals: (0, Some(0)), + flags: &[ + Flag { + name: "separator", + alias: Some('s'), + doc: "Separator to between joined selections [default: newline]", + completions: Some(&[]) + }, + Flag { + name: "register", + alias: Some('r'), + doc: "Yank into this register", + completions: Some(&[]) + } + ], ..Signature::DEFAULT }, }, @@ -2959,17 +2951,6 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ ..Signature::DEFAULT }, }, - TypableCommand { - name: "clipboard-yank-join", - aliases: &[], - doc: "Yank joined selections into system clipboard. A separator can be provided as first argument. Default value is newline.", // FIXME: current UI can't display long doc. - fun: yank_joined_to_clipboard, - completer: CommandCompleter::none(), - signature: Signature { - positionals: (0, Some(1)), - ..Signature::DEFAULT - }, - }, TypableCommand { name: "primary-clipboard-yank", aliases: &[], @@ -2981,17 +2962,6 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ ..Signature::DEFAULT }, }, - TypableCommand { - name: "primary-clipboard-yank-join", - aliases: &[], - doc: "Yank joined selections into system primary clipboard. A separator can be provided as first argument. Default value is newline.", // FIXME: current UI can't display long doc. - fun: yank_joined_to_primary_clipboard, - completer: CommandCompleter::none(), - signature: Signature { - positionals: (0, Some(1)), - ..Signature::DEFAULT - }, - }, TypableCommand { name: "clipboard-paste-after", aliases: &[], diff --git a/helix-term/tests/test/commands.rs b/helix-term/tests/test/commands.rs index 2af1a054f..512501873 100644 --- a/helix-term/tests/test/commands.rs +++ b/helix-term/tests/test/commands.rs @@ -5,6 +5,7 @@ use super::*; mod insert; mod movement; mod write; +mod yank_join; #[tokio::test(flavor = "multi_thread")] async fn search_selection_detect_word_boundaries_at_eof() -> anyhow::Result<()> { diff --git a/helix-term/tests/test/commands/yank_join.rs b/helix-term/tests/test/commands/yank_join.rs new file mode 100644 index 000000000..642ebead1 --- /dev/null +++ b/helix-term/tests/test/commands/yank_join.rs @@ -0,0 +1,69 @@ +use super::*; + +#[tokio::test(flavor = "multi_thread")] +async fn no_flags() -> anyhow::Result<()> { + test(( + indoc! {"\ + #[o|]#ne + #(t|)#wo + three" + }, + ":yank-joinp", + indoc! {"\ + o#[o + t|]#ne + t#(o + t|)#wo + three" + }, + )) + .await?; + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn separator_flag() -> anyhow::Result<()> { + test(( + indoc! {"\ + #[o|]#ne + #(t|)#wo + three" + }, + ":yank-join --separator xp", + indoc! {"\ + o#[oxt|]#ne + t#(oxt|)#wo + three" + }, + )) + .await?; + + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn register_flag() -> anyhow::Result<()> { + test(( + indoc! {"\ + #[o|]#ne + #(t|)#wo + three" + }, + // 1. Yank the two selections into register `x` + // 2. Move cursor down + right + // 3. Yank two other selections into the default register + // 4. Move cursor back up + left, to the original position + // 5. Pasting from register `x` will paste as if actions 2, 3 and 4 never occured + ":yank-join --register xjl:yank-joinkh\"xp", + indoc! {"\ + o#[o + t|]#ne + t#(o + t|)#wo + three" + }, + )) + .await?; + + Ok(()) +}