@@ -32,7 +32,6 @@ use helix_core::{
32 RopeReader, RopeSlice, Selection, SmallVec, Tendril, Transaction,
32 RopeReader, RopeSlice, Selection, SmallVec, Tendril, Transaction,
34use helix_view::{
34use helix_view::{
35− clipboard::ClipboardType,
36 document::{FormatterError, Mode, SCRATCH_BUFFER_NAME},
35 document::{FormatterError, Mode, SCRATCH_BUFFER_NAME},
37 editor::{Action, CompleteAction},
36 editor::{Action, CompleteAction},
38 info::Info,
37 info::Info,
@@ -3759,7 +3758,12 @@ fn commit_undo_checkpoint(cx: &mut Context) {
3759// Yank / Paste
3758// Yank / Paste
3761fn yank(cx: &mut Context) {
3760fn yank(cx: &mut Context) {
3761+ yank_impl(cx.editor, cx.register.unwrap_or('"'));
3762+ exit_select_mode(cx);
3765+fn yank_impl(editor: &mut Editor, register: char) {
3762− let (view, doc) = current!(cx.editor);
3766+ let (view, doc) = current!(editor);
3763 let text = doc.text().slice(..);
3767 let text = doc.text().slice(..);
3765 let values: Vec<String> = doc
3769 let values: Vec<String> = doc
@@ -3768,16 +3772,14 @@ fn yank(cx: &mut Context) {
3768 .map(Cow::into_owned)
3772 .map(Cow::into_owned)
3769 .collect();
3773 .collect();
3770 let selections = values.len();
3774 let selections = values.len();
3771− let register = cx.register.unwrap_or('"');
3773− match cx.editor.registers.write(register, values) {
3776+ match editor.registers.write(register, values) {
3774− Ok(_) => cx.editor.set_status(format!(
3777+ Ok(_) => editor.set_status(format!(
3775− "yanked {selections} selection(s) to register {register}",
3778+ "yanked {selections} selection{} to register {register}",
3779+ if selections == 1 { "" } else { "s" }
3777− Err(err) => cx.editor.set_error(err.to_string()),
3781+ Err(err) => editor.set_error(err.to_string()),
3780− exit_select_mode(cx);
3783fn yank_joined_impl(editor: &mut Editor, separator: &str, register: char) {
3785fn yank_joined_impl(editor: &mut Editor, separator: &str, register: char) {
@@ -3798,100 +3800,50 @@ fn yank_joined_impl(editor: &mut Editor, separator: &str, register: char) {
3799 match editor.registers.write(register, vec![joined]) {
3801 match editor.registers.write(register, vec![joined]) {
3800 Ok(_) => editor.set_status(format!(
3802 Ok(_) => editor.set_status(format!(
3801− "joined and yanked {selections} selection(s) to register {register}",
3803+ "joined and yanked {selections} selection{} to register {register}",
3804+ if selections == 1 { "" } else { "s" }
3803 Err(err) => editor.set_error(err.to_string()),
3806 Err(err) => editor.set_error(err.to_string()),
3807fn yank_joined(cx: &mut Context) {
3810fn yank_joined(cx: &mut Context) {
3808− let line_ending = doc!(cx.editor).line_ending;
3811+ let separator = doc!(cx.editor).line_ending.as_str();
3809− let register = cx.register.unwrap_or('"');
3812+ yank_joined_impl(cx.editor, separator, cx.register.unwrap_or('"'));
3810− yank_joined_impl(cx.editor, line_ending.as_str(), register);
3811 exit_select_mode(cx);
3813 exit_select_mode(cx);
3814−fn yank_joined_to_clipboard_impl(
3816+fn yank_joined_to_clipboard(cx: &mut Context) {
3815− editor: &mut Editor,
3817+ let line_ending = doc!(cx.editor).line_ending;
3816− separator: &str,
3818+ yank_joined_impl(cx.editor, line_ending.as_str(), '*');
3817− clipboard_type: ClipboardType,
3819+ exit_select_mode(cx);
3818−) -> anyhow::Result<()> {
3819− let (view, doc) = current!(editor);
3820− let text = doc.text().slice(..);
3822− let values: Vec<String> = doc
3823− .selection(view.id)
3825− .map(Cow::into_owned)
3828− let clipboard_text = match clipboard_type {
3829− ClipboardType::Clipboard => "system clipboard",
3830− ClipboardType::Selection => "primary clipboard",
3834− "joined and yanked {} selection(s) to {}",
3839− let joined = values.join(separator);
3842− .clipboard_provider
3843− .set_contents(joined, clipboard_type)
3844− .context("Couldn't set system clipboard content")?;
3846− editor.set_status(msg);
3851−fn yank_joined_to_clipboard(cx: &mut Context) {
3822+fn yank_joined_to_primary_clipboard(cx: &mut Context) {
3852 let line_ending = doc!(cx.editor).line_ending;
3823 let line_ending = doc!(cx.editor).line_ending;
3854− yank_joined_to_clipboard_impl(cx.editor, line_ending.as_str(), ClipboardType::Clipboard);
3824+ yank_joined_impl(cx.editor, line_ending.as_str(), '+');
3855 exit_select_mode(cx);
3825 exit_select_mode(cx);
3858−fn yank_main_selection_to_clipboard_impl(
3859− editor: &mut Editor,
3828+fn yank_primary_selection_impl(editor: &mut Editor, register: char) {
3860− clipboard_type: ClipboardType,
3861−) -> anyhow::Result<()> {
3862 let (view, doc) = current!(editor);
3829 let (view, doc) = current!(editor);
3863 let text = doc.text().slice(..);
3830 let text = doc.text().slice(..);
3865− let message_text = match clipboard_type {
3866− ClipboardType::Clipboard => "yanked main selection to system clipboard",
3867− ClipboardType::Selection => "yanked main selection to primary clipboard",
3870− let value = doc.selection(view.id).primary().fragment(text);
3832+ let selection = doc.selection(view.id).primary().fragment(text).to_string();
3872− if let Err(e) = editor
3834+ match editor.registers.write(register, vec![selection]) {
3873− .clipboard_provider
3835+ Ok(_) => editor.set_status(format!("yanked primary selection to register {register}",)),
3874− .set_contents(value.into_owned(), clipboard_type)
3836+ Err(err) => editor.set_error(err.to_string()),
3876− bail!("Couldn't set system clipboard content: {}", e);
3879− editor.set_status(message_text);
3883fn yank_main_selection_to_clipboard(cx: &mut Context) {
3840fn yank_main_selection_to_clipboard(cx: &mut Context) {
3884− let _ = yank_main_selection_to_clipboard_impl(cx.editor, ClipboardType::Clipboard);
3841+ yank_primary_selection_impl(cx.editor, '*');
3885−}
3842+ exit_select_mode(cx);
3887−fn yank_joined_to_primary_clipboard(cx: &mut Context) {
3888− let line_ending = doc!(cx.editor).line_ending;
3890− yank_joined_to_clipboard_impl(cx.editor, line_ending.as_str(), ClipboardType::Selection);
3893fn yank_main_selection_to_primary_clipboard(cx: &mut Context) {
3845fn yank_main_selection_to_primary_clipboard(cx: &mut Context) {
3894− let _ = yank_main_selection_to_clipboard_impl(cx.editor, ClipboardType::Selection);
3846+ yank_primary_selection_impl(cx.editor, '+');
3895 exit_select_mode(cx);
3847 exit_select_mode(cx);
@@ -3991,68 +3943,34 @@ pub(crate) fn paste_bracketed_value(cx: &mut Context, contents: String) {
3991 paste_impl(&[contents], doc, view, paste, count, cx.editor.mode);
3943 paste_impl(&[contents], doc, view, paste, count, cx.editor.mode);
3994−fn paste_clipboard_impl(
3995− editor: &mut Editor,
3997− clipboard_type: ClipboardType,
3999−) -> anyhow::Result<()> {
4000− let (view, doc) = current!(editor);
4001− match editor.clipboard_provider.get_contents(clipboard_type) {
4003− paste_impl(&[contents], doc, view, action, count, editor.mode);
4006− Err(e) => Err(e.context("Couldn't get system clipboard contents")),
4010fn paste_clipboard_after(cx: &mut Context) {
3946fn paste_clipboard_after(cx: &mut Context) {
4011− let _ = paste_clipboard_impl(
4013− Paste::After,
3947+ paste(cx.editor, '*', Paste::After, cx.count());
4014− ClipboardType::Clipboard,
4019fn paste_clipboard_before(cx: &mut Context) {
3950fn paste_clipboard_before(cx: &mut Context) {
4020− let _ = paste_clipboard_impl(
4022− Paste::Before,
3951+ paste(cx.editor, '*', Paste::Before, cx.count());
4023− ClipboardType::Clipboard,
4028fn paste_primary_clipboard_after(cx: &mut Context) {
3954fn paste_primary_clipboard_after(cx: &mut Context) {
4029− let _ = paste_clipboard_impl(
4031− Paste::After,
3955+ paste(cx.editor, '+', Paste::After, cx.count());
4032− ClipboardType::Selection,
4037fn paste_primary_clipboard_before(cx: &mut Context) {
3958fn paste_primary_clipboard_before(cx: &mut Context) {
4038− let _ = paste_clipboard_impl(
4040− Paste::Before,
3959+ paste(cx.editor, '+', Paste::Before, cx.count());
4041− ClipboardType::Selection,
4046fn replace_with_yanked(cx: &mut Context) {
3962fn replace_with_yanked(cx: &mut Context) {
4047− let count = cx.count();
4048− let reg_name = cx.register.unwrap_or('"');
3963+ replace_with_yanked_impl(cx.editor, cx.register.unwrap_or('"'), cx.count());
3964+ exit_select_mode(cx);
3967+fn replace_with_yanked_impl(editor: &mut Editor, register: char, count: usize) {
4050− let Some(values) = cx.editor.registers
3968+ let Some(values) = editor.registers
4051− .read(reg_name, cx.editor)
3969+ .read(register, editor)
4052 .filter(|values| values.len() > 0) else { return };
3970 .filter(|values| values.len() > 0) else { return };
4053 let values: Vec<_> = values.map(|value| value.to_string()).collect();
3971 let values: Vec<_> = values.map(|value| value.to_string()).collect();
4055− let (view, doc) = current!(cx.editor);
3973+ let (view, doc) = current!(editor);
4056 let repeat = std::iter::repeat(
3974 let repeat = std::iter::repeat(
@@ -4073,62 +3991,40 @@ fn replace_with_yanked(cx: &mut Context) {
4075 doc.apply(&transaction, view.id);
3993 doc.apply(&transaction, view.id);
4076− exit_select_mode(cx);
4079−fn replace_selections_with_clipboard_impl(
4081− clipboard_type: ClipboardType,
4082−) -> anyhow::Result<()> {
4083− let count = cx.count();
4084− let (view, doc) = current!(cx.editor);
4086− match cx.editor.clipboard_provider.get_contents(clipboard_type) {
4088− let selection = doc.selection(view.id);
4089− let transaction = Transaction::change_by_selection(doc.text(), selection, |range| {
4093− Some(contents.repeat(count).as_str().into()),
4097− doc.apply(&transaction, view.id);
4098− doc.append_changes_to_history(view);
4100− Err(e) => return Err(e.context("Couldn't get system clipboard contents")),
4103− exit_select_mode(cx);
4107fn replace_selections_with_clipboard(cx: &mut Context) {
3996fn replace_selections_with_clipboard(cx: &mut Context) {
4108− let _ = replace_selections_with_clipboard_impl(cx, ClipboardType::Clipboard);
3997+ replace_with_yanked_impl(cx.editor, '*', cx.count());
4111fn replace_selections_with_primary_clipboard(cx: &mut Context) {
4000fn replace_selections_with_primary_clipboard(cx: &mut Context) {
4112− let _ = replace_selections_with_clipboard_impl(cx, ClipboardType::Selection);
4001+ replace_with_yanked_impl(cx.editor, '+', cx.count());
4115−fn paste(cx: &mut Context, pos: Paste) {
4004+fn paste(editor: &mut Editor, register: char, pos: Paste, count: usize) {
4116− let count = cx.count();
4117− let reg_name = cx.register.unwrap_or('"');
4119− let Some(values) = cx.editor.registers.read(reg_name, cx.editor) else { return };
4005+ let Some(values) = editor.registers.read(register, editor) else { return };
4120 let values: Vec<_> = values.map(|value| value.to_string()).collect();
4006 let values: Vec<_> = values.map(|value| value.to_string()).collect();
4122− let (view, doc) = current!(cx.editor);
4008+ let (view, doc) = current!(editor);
4123− paste_impl(&values, doc, view, pos, count, cx.editor.mode);
4009+ paste_impl(&values, doc, view, pos, count, editor.mode);
4126fn paste_after(cx: &mut Context) {
4012fn paste_after(cx: &mut Context) {
4015+ cx.register.unwrap_or('"'),
4127− paste(cx, Paste::After)
4016+ Paste::After,
4130fn paste_before(cx: &mut Context) {
4021fn paste_before(cx: &mut Context) {
4024+ cx.register.unwrap_or('"'),
4131− paste(cx, Paste::Before)
4025+ Paste::Before,
4134fn get_lines(doc: &Document, view_id: ViewId) -> Vec<usize> {
4030fn get_lines(doc: &Document, view_id: ViewId) -> Vec<usize> {
@@ -4885,7 +4781,12 @@ fn insert_register(cx: &mut Context) {
4885 if let Some(ch) = event.char() {
4781 if let Some(ch) = event.char() {
4886 cx.editor.autoinfo = None;
4782 cx.editor.autoinfo = None;
4887 cx.register = Some(ch);
4783 cx.register = Some(ch);
4786+ cx.register.unwrap_or('"'),
4888− paste(cx, Paste::Cursor);
4787+ Paste::Cursor,