Implement P as paste_before.

imgbot
Blaž Hrastnik 4 years ago
parent 31e6bcbeb4
commit 12961d657f

@ -1405,7 +1405,13 @@ pub fn yank(cx: &mut Context) {
cx.set_status(msg) cx.set_status(msg)
} }
pub fn paste(cx: &mut Context) { #[derive(Copy, Clone)]
enum Paste {
Before,
After,
}
fn _paste(doc: &mut Document, view: &View, action: Paste) -> Option<Transaction> {
// TODO: allow specifying reg // TODO: allow specifying reg
let reg = '"'; let reg = '"';
if let Some(values) = register::get(reg) { if let Some(values) = register::get(reg) {
@ -1416,10 +1422,34 @@ pub fn paste(cx: &mut Context) {
.unwrap(), .unwrap(),
); );
// TODO: if any of values ends \n it's linewise paste // if any of values ends \n it's linewise paste
// let linewise = values.iter().any(|value| value.ends_with('\n'));
// p => paste after
// P => paste before let mut values = values.into_iter().map(Tendril::from).chain(repeat);
// paste on the next line
// TODO: can simply take a range + modifier and compute the right pos without ifs
let text = doc.text();
let transaction =
Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
let pos = match (action, linewise) {
// paste linewise before
(Paste::Before, true) => text.line_to_char(text.char_to_line(range.from())),
// paste linewise after
(Paste::After, true) => text.line_to_char(text.char_to_line(range.to()) + 1),
// paste insert
(Paste::Before, false) => range.from(),
// paste append
(Paste::After, false) => range.to() + 1,
};
(pos, pos, Some(values.next().unwrap()))
});
return Some(transaction);
}
None
}
// alt-p => paste every yanked selection after selected text // alt-p => paste every yanked selection after selected text
// alt-P => paste every yanked selection before selected text // alt-P => paste every yanked selection before selected text
// R => replace selected text with yanked text // R => replace selected text with yanked text
@ -1430,26 +1460,19 @@ pub fn paste(cx: &mut Context) {
// replace => replace // replace => replace
// default insert // default insert
let linewise = values.iter().any(|value| value.ends_with('\n')); pub fn paste_after(cx: &mut Context) {
let (view, doc) = cx.current();
let mut values = values.into_iter().map(Tendril::from).chain(repeat); if let Some(transaction) = _paste(doc, view, Paste::After) {
doc.apply(&transaction, view.id);
doc.append_changes_to_history(view.id);
}
}
pub fn paste_before(cx: &mut Context) {
let (view, doc) = cx.current(); let (view, doc) = cx.current();
let transaction = if linewise { if let Some(transaction) = _paste(doc, view, Paste::Before) {
// paste on the next line
// TODO: can simply take a range + modifier and compute the right pos without ifs
let text = doc.text();
Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
let line_end = text.line_to_char(text.char_to_line(range.head) + 1);
(line_end, line_end, Some(values.next().unwrap()))
})
} else {
Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
(range.head + 1, range.head + 1, Some(values.next().unwrap()))
})
};
doc.apply(&transaction, view.id); doc.apply(&transaction, view.id);
doc.append_changes_to_history(view.id); doc.append_changes_to_history(view.id);
} }

@ -207,8 +207,9 @@ pub fn default() -> Keymaps {
key!('y') => commands::yank, key!('y') => commands::yank,
// yank_all // yank_all
key!('p') => commands::paste, key!('p') => commands::paste_after,
// paste_all // paste_all
shift!('P') => commands::paste_before,
key!('>') => commands::indent, key!('>') => commands::indent,
key!('<') => commands::unindent, key!('<') => commands::unindent,

Loading…
Cancel
Save