aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--helix-term/src/commands.rs79
-rw-r--r--helix-term/src/keymap.rs3
2 files changed, 53 insertions, 29 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 0d5ffb9c..d8410352 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -1405,7 +1405,13 @@ pub fn yank(cx: &mut Context) {
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
let reg = '"';
if let Some(values) = register::get(reg) {
@@ -1416,40 +1422,57 @@ pub fn paste(cx: &mut Context) {
.unwrap(),
);
- // TODO: if any of values ends \n it's linewise paste
- //
- // p => paste after
- // P => paste before
- // alt-p => paste every yanked selection after selected text
- // alt-P => paste every yanked selection before selected text
- // R => replace selected text with yanked text
- // alt-R => replace selected text with every yanked text
- //
- // append => insert at next line
- // insert => insert at start of line
- // replace => replace
- // default insert
-
+ // if any of values ends \n it's linewise paste
let linewise = values.iter().any(|value| value.ends_with('\n'));
let mut values = values.into_iter().map(Tendril::from).chain(repeat);
- let (view, doc) = cx.current();
+ // 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 = if linewise {
- // 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 {
+ let transaction =
Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
- (range.head + 1, range.head + 1, Some(values.next().unwrap()))
- })
- };
+ 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 before selected text
+// R => replace selected text with yanked text
+// alt-R => replace selected text with every yanked text
+//
+// append => insert at next line
+// insert => insert at start of line
+// replace => replace
+// default insert
+
+pub fn paste_after(cx: &mut Context) {
+ let (view, doc) = cx.current();
+
+ 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();
+ if let Some(transaction) = _paste(doc, view, Paste::Before) {
doc.apply(&transaction, view.id);
doc.append_changes_to_history(view.id);
}
diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs
index eeecd08e..06b190aa 100644
--- a/helix-term/src/keymap.rs
+++ b/helix-term/src/keymap.rs
@@ -207,8 +207,9 @@ pub fn default() -> Keymaps {
key!('y') => commands::yank,
// yank_all
- key!('p') => commands::paste,
+ key!('p') => commands::paste_after,
// paste_all
+ shift!('P') => commands::paste_before,
key!('>') => commands::indent,
key!('<') => commands::unindent,