@@ -1405,7 +1405,13 @@ pub fn yank(cx: &mut Context) {
1405 cx.set_status(msg)
1405 cx.set_status(msg)
1408−pub fn paste(cx: &mut Context) {
1408+#[derive(Copy, Clone)]
1414+fn _paste(doc: &mut Document, view: &View, action: Paste) -> Option<Transaction> {
1409 // TODO: allow specifying reg
1415 // TODO: allow specifying reg
1410 let reg = '"';
1416 let reg = '"';
1411 if let Some(values) = register::get(reg) {
1417 if let Some(values) = register::get(reg) {
@@ -1416,40 +1422,57 @@ pub fn paste(cx: &mut Context) {
1416 .unwrap(),
1422 .unwrap(),
1419− // TODO: if any of values ends \n it's linewise paste
1425+ // if any of values ends \n it's linewise paste
1421− // p => paste after
1422− // P => paste before
1423− // alt-p => paste every yanked selection after selected text
1424− // alt-P => paste every yanked selection before selected text
1425− // R => replace selected text with yanked text
1426− // alt-R => replace selected text with every yanked text
1428− // append => insert at next line
1429− // insert => insert at start of line
1430− // replace => replace
1433 let linewise = values.iter().any(|value| value.ends_with('\n'));
1426 let linewise = values.iter().any(|value| value.ends_with('\n'));
1435 let mut values = values.into_iter().map(Tendril::from).chain(repeat);
1428 let mut values = values.into_iter().map(Tendril::from).chain(repeat);
1437− let (view, doc) = cx.current();
1430+ // paste on the next line
1431+ // TODO: can simply take a range + modifier and compute the right pos without ifs
1432+ let text = doc.text();
1439− let transaction = if linewise {
1434+ let transaction =
1440− // paste on the next line
1441− // TODO: can simply take a range + modifier and compute the right pos without ifs
1442− let text = doc.text();
1443− Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
1444− let line_end = text.line_to_char(text.char_to_line(range.head) + 1);
1445− (line_end, line_end, Some(values.next().unwrap()))
1448 Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
1435 Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
1436+ let pos = match (action, linewise) {
1437+ // paste linewise before
1438+ (Paste::Before, true) => text.line_to_char(text.char_to_line(range.from())),
1439+ // paste linewise after
1440+ (Paste::After, true) => text.line_to_char(text.char_to_line(range.to()) + 1),
1442+ (Paste::Before, false) => range.from(),
1444+ (Paste::After, false) => range.to() + 1,
1449− (range.head + 1, range.head + 1, Some(values.next().unwrap()))
1446+ (pos, pos, Some(values.next().unwrap()))
1448+ return Some(transaction);
1453+// alt-p => paste every yanked selection after selected text
1454+// alt-P => paste every yanked selection before selected text
1455+// R => replace selected text with yanked text
1456+// alt-R => replace selected text with every yanked text
1458+// append => insert at next line
1459+// insert => insert at start of line
1460+// replace => replace
1463+pub fn paste_after(cx: &mut Context) {
1464+ let (view, doc) = cx.current();
1466+ if let Some(transaction) = _paste(doc, view, Paste::After) {
1467+ doc.apply(&transaction, view.id);
1468+ doc.append_changes_to_history(view.id);
1472+pub fn paste_before(cx: &mut Context) {
1473+ let (view, doc) = cx.current();
1475+ if let Some(transaction) = _paste(doc, view, Paste::Before) {
1453 doc.apply(&transaction, view.id);
1476 doc.apply(&transaction, view.id);
1454 doc.append_changes_to_history(view.id);
1477 doc.append_changes_to_history(view.id);