Skip to content

Commit

Permalink
Add yank_joined command (helix-editor#7195)
Browse files Browse the repository at this point in the history
Resolves issue helix-editor#6888 by adding a command to join all selections and yank
them to the specified register. The typed command takes an argument as
the separator to use when joining the selections.
  • Loading branch information
spectre256 authored and Schuyler Mortimer committed Jul 10, 2024
1 parent 67d1b27 commit bca9fbb
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
1 change: 1 addition & 0 deletions book/src/generated/typable-cmd.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
| `: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. |
| `: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. |
Expand Down
33 changes: 33 additions & 0 deletions helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ impl MappableCommand {
later, "Move forward in history",
commit_undo_checkpoint, "Commit changes to new checkpoint",
yank, "Yank selection",
yank_joined, "Join and yank selections",
yank_joined_to_clipboard, "Join and yank selections to clipboard",
yank_main_selection_to_clipboard, "Yank main selection to clipboard",
yank_joined_to_primary_clipboard, "Join and yank selections to primary clipboard",
Expand Down Expand Up @@ -3728,6 +3729,38 @@ fn yank(cx: &mut Context) {
exit_select_mode(cx);
}

fn yank_joined_impl(editor: &mut Editor, separator: &str, register: char) {
let (view, doc) = current!(editor);
let text = doc.text().slice(..);

let selection = doc.selection(view.id);
let joined = selection
.fragments(text)
.fold(String::new(), |mut acc, fragment| {
if !acc.is_empty() {
acc.push_str(separator);
}
acc.push_str(&fragment);
acc
});

let msg = format!(
"joined and yanked {} selection(s) to register {}",
selection.len(),
register,
);

editor.registers.write(register, vec![joined]);
editor.set_status(msg);
}

fn yank_joined(cx: &mut Context) {
let line_ending = doc!(cx.editor).line_ending;
let register = cx.register.unwrap_or('"');
yank_joined_impl(cx.editor, line_ending.as_str(), register);
exit_select_mode(cx);
}

fn yank_joined_to_clipboard_impl(
editor: &mut Editor,
separator: &str,
Expand Down
26 changes: 26 additions & 0 deletions helix-term/src/commands/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,25 @@ fn yank_main_selection_to_clipboard(
yank_main_selection_to_clipboard_impl(cx.editor, ClipboardType::Clipboard)
}

fn yank_joined(
cx: &mut compositor::Context,
args: &[Cow<str>],
event: PromptEvent,
) -> anyhow::Result<()> {
if event != PromptEvent::Validate {
return Ok(());
}

ensure!(args.len() <= 1, ":yank-join takes at most 1 argument");

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('"');
yank_joined_impl(cx.editor, separator, register);
Ok(())
}

fn yank_joined_to_clipboard(
cx: &mut compositor::Context,
args: &[Cow<str>],
Expand Down Expand Up @@ -2474,6 +2493,13 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
fun: theme,
signature: CommandSignature::positional(&[completers::theme]),
},
TypableCommand {
name: "yank-join",
aliases: &[],
doc: "Yank joined selections. A separator can be provided as first argument. Default value is newline.",
fun: yank_joined,
signature: CommandSignature::none(),
},
TypableCommand {
name: "clipboard-yank",
aliases: &[],
Expand Down

0 comments on commit bca9fbb

Please sign in to comment.