8

Is there a way to use avy or a similar in-buffer selection tool to quickly select a word or line to paste at the current point?

For the following buffer an example workflow for proposed functionality would be:

line 1 - reallyLongSymbol
line 2 - bravo
line 3 - <POINT_HERE>
  • At line 3, realize I want to paste reallyLongSymbol at the current point.
  • M-x avy-select-word-and-paste (made-up)
  • Press the key combo that corresponds to reallyLongSymbol
  • reallyLongSymbol is inserted at POINT.

The buffer is now as follows:

line 1 - reallyLongSymbol
line 2 - bravo
line 3 - reallyLongSymbol<POINT_HERE>

Ideally, this would work for other targets like lines and urls.

Drew
  • 75,699
  • 9
  • 109
  • 225
Joe
  • 1,312
  • 1
  • 8
  • 19

3 Answers3

7

avy already supports what you want. See avy-dispatch-alist.

However, the default actions are not enough. I have the following function in my config (here it copies a sexp, but you can change it to copy a line):

(defun my-avy-action-copy-and-yank (pt)
  "Copy and yank sexp starting on PT."
  (avy-action-copy pt)
  (yank))

Then assign a key to the function in avy-dispatch-alist. I use p here:

(setq avy-dispatch-alist '((?c . avy-action-copy)
                           (?k . avy-action-kill-move)
                           (?K . avy-action-kill-stay)
                           (?m . avy-action-mark)
                           (?p . my-avy-action-copy-and-yank)))

To use it: before you jump to reallyLongSymbol, first press p, then the letter combination for jumping to reallyLongSymbol. Note that you can't use p in avy-keys since it is now reserved for the my-avy-action-copy-and-yank.

This is a really awesome feature and you can easily add other actions you want.

Chakravarthy Raghunandan
  • 3,132
  • 2
  • 18
  • 42
cutejumper
  • 787
  • 5
  • 12
  • This is so cool. One tweak I made. `k` and `K` didn't seem to work so I used `x` and `X` which also matches the default binding. – Joe Oct 22 '16 at 06:03
  • @JoeS You're right. I changed some of the keys and I just copied part of the code from my config and I forgot to change them back when posting the answer. You just need to make sure the keys used in the `avy-dispatch-alist` don't overlap the `avy-keys`, which are used for selection. Anyway, glad it helps. – cutejumper Oct 22 '16 at 06:51
2

cute-jumpers answer is perfectly functional. If you want to bind the action to another key rather than use avy's internal dispatch process then the following adapted code works quite well:

(defun my-avy-paste-word (char)
  "Paste a word selected with avy."
  (interactive (list (read-char "char:" t)))
  (let ((avy-action #'avy-action-copy))
    (when (avy-jump (concat "\\b" (string char)))
      (yank))))
unhammer
  • 1,127
  • 8
  • 22
Att Righ
  • 725
  • 4
  • 14
0

for this example you can use dynamic abbrev.

type "r" "M-/"

If you want to use avy, then assuming you have avy-goto-char bound to something like M-p, then

"C-SPC"   # set-mark, to remember where we are
"M-p the_correct_character_from_overlay" # avy-goto-char, goto place
"C-SPC"   # set-mark, start the region to copy
"M-f"     # forward-word, or C-e if you want to select a line...
"M-w"     # copy-region-as-kill, to copy the region
"C-x C-SPC" # pop-global-mark, get back to where we were
"C-y"     # yank, paste in the stuff we copied.

I know it looks a bit long (9 key combinations) but they will soon flow off the fingers.

icarus
  • 1,904
  • 1
  • 10
  • 15