mirror of https://github.com/helix-editor/helix
Add paste_after_all and paste_before_all
parent
25a57e4920
commit
9bb9ce8e77
|
@ -488,6 +488,8 @@ impl MappableCommand {
|
||||||
replace_with_yanked, "Replace with yanked text",
|
replace_with_yanked, "Replace with yanked text",
|
||||||
replace_selections_with_clipboard, "Replace selections by clipboard content",
|
replace_selections_with_clipboard, "Replace selections by clipboard content",
|
||||||
replace_selections_with_primary_clipboard, "Replace selections by primary clipboard",
|
replace_selections_with_primary_clipboard, "Replace selections by primary clipboard",
|
||||||
|
paste_after_all, "Paste all after selection",
|
||||||
|
paste_before_all, "Paste all before selection",
|
||||||
paste_after, "Paste after selection",
|
paste_after, "Paste after selection",
|
||||||
paste_before, "Paste before selection",
|
paste_before, "Paste before selection",
|
||||||
paste_clipboard_after, "Paste clipboard after selections",
|
paste_clipboard_after, "Paste clipboard after selections",
|
||||||
|
@ -4669,7 +4671,7 @@ fn paste_impl(
|
||||||
map_value(values.last().unwrap()),
|
map_value(values.last().unwrap()),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut values = values.iter().map(|value| map_value(value)).chain(repeat);
|
let mut values_iter = values.iter().map(|value| map_value(value)).chain(repeat);
|
||||||
|
|
||||||
let text = doc.text();
|
let text = doc.text();
|
||||||
let selection = doc.selection(view.id);
|
let selection = doc.selection(view.id);
|
||||||
|
@ -4677,6 +4679,15 @@ fn paste_impl(
|
||||||
let mut offset = 0;
|
let mut offset = 0;
|
||||||
let mut ranges = SmallVec::with_capacity(selection.len());
|
let mut ranges = SmallVec::with_capacity(selection.len());
|
||||||
|
|
||||||
|
// Precompute the combined tendril value if we will be doing a PasteType::All
|
||||||
|
let combined_tendril_value = match paste_type {
|
||||||
|
PasteType::All => Some(values.iter().fold(Tendril::default(), |mut acc, v| {
|
||||||
|
acc = acc + v;
|
||||||
|
acc
|
||||||
|
})),
|
||||||
|
PasteType::Default => None,
|
||||||
|
};
|
||||||
|
|
||||||
let mut transaction = Transaction::change_by_selection(text, selection, |range| {
|
let mut transaction = Transaction::change_by_selection(text, selection, |range| {
|
||||||
let pos = match (action, linewise) {
|
let pos = match (action, linewise) {
|
||||||
// paste linewise before
|
// paste linewise before
|
||||||
|
@ -4694,7 +4705,24 @@ fn paste_impl(
|
||||||
(Paste::Cursor, _) => range.cursor(text.slice(..)),
|
(Paste::Cursor, _) => range.cursor(text.slice(..)),
|
||||||
};
|
};
|
||||||
|
|
||||||
let value = values.next();
|
let value = match paste_type {
|
||||||
|
PasteType::All => {
|
||||||
|
// Iterate over every value and add its range
|
||||||
|
for value in values {
|
||||||
|
let value_len = value.chars().count();
|
||||||
|
let anchor = offset + pos;
|
||||||
|
|
||||||
|
let new_range =
|
||||||
|
Range::new(anchor, anchor + value_len).with_direction(range.direction());
|
||||||
|
ranges.push(new_range);
|
||||||
|
offset += value_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the precomputed tendril value
|
||||||
|
combined_tendril_value.clone()
|
||||||
|
}
|
||||||
|
PasteType::Default => {
|
||||||
|
let value: Option<Tendril> = values_iter.next();
|
||||||
|
|
||||||
let value_len = value
|
let value_len = value
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -4702,9 +4730,13 @@ fn paste_impl(
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let anchor = offset + pos;
|
let anchor = offset + pos;
|
||||||
|
|
||||||
let new_range = Range::new(anchor, anchor + value_len).with_direction(range.direction());
|
let new_range =
|
||||||
|
Range::new(anchor, anchor + value_len).with_direction(range.direction());
|
||||||
ranges.push(new_range);
|
ranges.push(new_range);
|
||||||
offset += value_len;
|
offset += value_len;
|
||||||
|
value
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
(pos, pos, value)
|
(pos, pos, value)
|
||||||
});
|
});
|
||||||
|
@ -4737,22 +4769,34 @@ pub(crate) fn paste_bracketed_value(cx: &mut Context, contents: String) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paste_clipboard_after(cx: &mut Context) {
|
fn paste_clipboard_after(cx: &mut Context) {
|
||||||
paste(cx.editor, '+', Paste::After, cx.count());
|
paste(cx.editor, '+', Paste::After, cx.count(), PasteType::Default);
|
||||||
exit_select_mode(cx);
|
exit_select_mode(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paste_clipboard_before(cx: &mut Context) {
|
fn paste_clipboard_before(cx: &mut Context) {
|
||||||
paste(cx.editor, '+', Paste::Before, cx.count());
|
paste(
|
||||||
|
cx.editor,
|
||||||
|
'+',
|
||||||
|
Paste::Before,
|
||||||
|
cx.count(),
|
||||||
|
PasteType::Default,
|
||||||
|
);
|
||||||
exit_select_mode(cx);
|
exit_select_mode(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paste_primary_clipboard_after(cx: &mut Context) {
|
fn paste_primary_clipboard_after(cx: &mut Context) {
|
||||||
paste(cx.editor, '*', Paste::After, cx.count());
|
paste(cx.editor, '*', Paste::After, cx.count(), PasteType::Default);
|
||||||
exit_select_mode(cx);
|
exit_select_mode(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paste_primary_clipboard_before(cx: &mut Context) {
|
fn paste_primary_clipboard_before(cx: &mut Context) {
|
||||||
paste(cx.editor, '*', Paste::Before, cx.count());
|
paste(
|
||||||
|
cx.editor,
|
||||||
|
'*',
|
||||||
|
Paste::Before,
|
||||||
|
cx.count(),
|
||||||
|
PasteType::Default,
|
||||||
|
);
|
||||||
exit_select_mode(cx);
|
exit_select_mode(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4829,6 +4873,28 @@ fn paste(editor: &mut Editor, register: char, pos: Paste, count: usize, paste_ty
|
||||||
paste_impl(&values, doc, view, pos, count, editor.mode, paste_type);
|
paste_impl(&values, doc, view, pos, count, editor.mode, paste_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn paste_after_all(cx: &mut Context) {
|
||||||
|
paste(
|
||||||
|
cx,
|
||||||
|
cx.register
|
||||||
|
.unwrap_or(cx.editor.config().default_yank_register),
|
||||||
|
Paste::After,
|
||||||
|
PasteType::All,
|
||||||
|
);
|
||||||
|
exit_select_mode(cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn paste_before_all(cx: &mut Context) {
|
||||||
|
paste(
|
||||||
|
cx,
|
||||||
|
cx.register
|
||||||
|
.unwrap_or(cx.editor.config().default_yank_register),
|
||||||
|
Paste::Before,
|
||||||
|
PasteType::All,
|
||||||
|
);
|
||||||
|
exit_select_mode(cx);
|
||||||
|
}
|
||||||
|
|
||||||
fn paste_after(cx: &mut Context) {
|
fn paste_after(cx: &mut Context) {
|
||||||
paste(
|
paste(
|
||||||
cx.editor,
|
cx.editor,
|
||||||
|
|
|
@ -152,8 +152,10 @@ pub fn default() -> HashMap<Mode, KeyTrie> {
|
||||||
"y" => yank,
|
"y" => yank,
|
||||||
// yank_all
|
// yank_all
|
||||||
"p" => paste_after,
|
"p" => paste_after,
|
||||||
// paste_all
|
// TODO: This is a terrible mapping, but "A-p" coincides with "select_prev_sibling"
|
||||||
|
"C-p" => paste_after_all,
|
||||||
"P" => paste_before,
|
"P" => paste_before,
|
||||||
|
"A-P" => paste_before_all,
|
||||||
|
|
||||||
"Q" => record_macro,
|
"Q" => record_macro,
|
||||||
"q" => replay_macro,
|
"q" => replay_macro,
|
||||||
|
|
Loading…
Reference in New Issue