8

Having copied the 3x3 rectangular region containing a's, how can I yank/paste that content at the desired point without slicing into the following text? The following is the behavior for:

  • M-w (kill-ring-save), M-y (kill-ring-save)
  • (copy-rectangle-as-kill), C-x r y (yank-rectangle)

(all using C-x SPC (rectangle-mark-mode))

aaa
aaa
aaa

Insert
here ->aaa
Here isaaa some text after 
the yanaaak point.

I would like to figure out how to yank, so that this is the result.

Insert
here ->aaa
aaa
aaa
Here is some text after 
the yank point.

I'll admit that I've been yanking rectangles at the bottom of buffers and then doing a normal region kill for some time now...

ebpa
  • 7,319
  • 26
  • 53

2 Answers2

3

Removing yank-handler text property from just killed text should do the trick, since this will make yank use normal insert instead of rectangle-mark-mode's own insert function.

(defun kill-ring-save--strip (orig-fun &rest args)
  (let ((rtv (apply orig-fun args)))
    (if rectangle-mark-mode
        (let ((killed (car kill-ring)))
          (remove-text-properties 0 (length killed) '(yank-handler nil) killed)
          (setcar kill-ring killed)))
    rtv))

(advice-add 'kill-ring-save :around #'kill-ring-save--strip)
xuchunyang
  • 14,302
  • 1
  • 18
  • 39
  • Perfect! `yank-rectangle` still behaves as expected :-) – ebpa Jan 14 '16 at 22:54
  • When I put this in .emacs and restart, upon the first M-w (kill-ring-save) I get the error "Symbol’s value as variable is void: rectangle-mark-mode". Also, although I can get the error to go away by entering and leaving rectangle-mark-mode, it seems that the new code removes the visual confirmation I am used to getting when I do M-w, which highlights the mark briefly so that I can see the extent of what I copied. – Metamorphic Jul 24 '18 at 21:25
  • I am wondering if someone can post an answer which doesn't depend on C-x SPC (rectangle-mark-mode), for instance I would like a function that I can bind to a special key so that when I do C-x r M-w (copy-rectangle-as-kill), then I can use the new binding to paste the copied rectangle as normal text. Is this easy to write? – Metamorphic Jul 24 '18 at 21:26
  • @Metamorphic have a look at my simple solution, maybe this helps? – jue Dec 01 '18 at 09:17
3

Another solution without advising functions and just adding another function to bind to any key:

(defun my-insert-rectangle-push-lines ()
  "Yank a rectangle as if it was an ordinary kill."
  (interactive "*")
  (when (and (use-region-p) (delete-selection-mode))
    (delete-region (region-beginning) (region-end)))
  (save-restriction
    (narrow-to-region (point) (mark))
    (yank-rectangle)))

(global-set-key (kbd "C-x r C-y") #'my-insert-rectangle-push-lines)

You can operate with rectangles and normal kill-ring as usual. Also you are able to yank a previously killed rectangle with C-x r C-y.

This works by narrowing the buffer to the current line (or region). Then yanking the rectangle and extending the region in a similar way like yanking to the end of the buffer. Afterwards widen the buffer back to normal.

jue
  • 4,476
  • 8
  • 20