1

I would like to change C-y to not move the mark, but still be able to yank-pop. I looked at the source code and saw that the major change needed was to remove the (push-mark (point)) command:

(defun yank (&optional arg)
  "Reinsert (\"paste\") the last stretch of killed text.
More precisely, reinsert the most recent kill, which is the
stretch of killed text most recently killed OR yanked.  Put point
at the end, and set mark at the beginning without activating it.
With just \\[universal-argument] as argument, put point at beginning, and mark at end.
With argument N, reinsert the Nth most recent kill.

When this command inserts text into the buffer, it honors the
`yank-handled-properties' and `yank-excluded-properties'
variables, and the `yank-handler' text property.  See
`insert-for-yank-1' for details.

See also the command `yank-pop' (\\[yank-pop])."
  (interactive "*P")
  (setq yank-window-start (window-start))
  ;; If we don't get all the way thru, make last-command indicate that
  ;; for the following command.
  (setq this-command t)
  (push-mark (point))
  (insert-for-yank (current-kill (cond
                  ((listp arg) 0)
                  ((eq arg '-) -2)
                  (t (1- arg)))))
  (if (consp arg)
      ;; This is like exchange-point-and-mark, but doesn't activate the mark.
      ;; It is cleaner to avoid activation, even though the command
      ;; loop would deactivate the mark because we inserted text.
      (goto-char (prog1 (mark t)
           (set-marker (mark-marker) (point) (current-buffer)))))
  ;; If we do get all the way thru, make this-command indicate that.
  (if (eq this-command t)
      (setq this-command 'yank))
  nil)

But when I look at the source code for M-y, it relies on the mark to be able to function:

(defun yank-pop (&optional arg)
  "Replace just-yanked stretch of killed text with a different stretch.
This command is allowed only immediately after a `yank' or a `yank-pop'.
At such a time, the region contains a stretch of reinserted
previously-killed text.  `yank-pop' deletes that text and inserts in its
place a different stretch of killed text.

With no argument, the previous kill is inserted.
With argument N, insert the Nth previous kill.
If N is negative, this is a more recent kill.

The sequence of kills wraps around, so that after the oldest one
comes the newest one.

When this command inserts killed text into the buffer, it honors
`yank-excluded-properties' and `yank-handler' as described in the
doc string for `insert-for-yank-1', which see."
  (interactive "*p")
  (if (not (eq last-command 'yank))
      (error "Previous command was not a yank"))
  (setq this-command 'yank)
  (unless arg (setq arg 1))
  (let ((inhibit-read-only t)
    (before (< (point) (mark t))))
    (if before
    (funcall (or yank-undo-function 'delete-region) (point) (mark t))
      (funcall (or yank-undo-function 'delete-region) (mark t) (point)))
    (setq yank-undo-function nil)
    (set-marker (mark-marker) (point) (current-buffer))
    (insert-for-yank (current-kill arg))
    ;; Set the window start back where it was in the yank command,
    ;; if possible.
    (set-window-start (selected-window) yank-window-start t)
    (if before
    ;; This is like exchange-point-and-mark, but doesn't activate the mark.
    ;; It is cleaner to avoid activation, even though the command
    ;; loop would deactivate the mark because we inserted text.
    (goto-char (prog1 (mark t)
             (set-marker (mark-marker) (point) (current-buffer))))))
  nil)

So how do I still maintain full yank functionality without having yank (C-y) move my cursor?

3

You'll have to advise yank (to restore the mark after it, and to save the "other end" somewhere) and yank-pop (to fetch the other end from that "somewhere", move the mark to it, then run the original code, and after that, restore the mark again).

  • Yea I'm not even sure this is possible – Czipperz Jun 29 '15 at 3:14
  • 1
    @Czipperz -- Stefan is one of the lead developers/maintainers of Emacs . . . :) . . . emacswiki.org/emacs/StefanMonnier and iro.umontreal.ca/~monnier I would bet my lunch money that if Stefen says it is possible, then it is possible. – lawlist Jun 29 '15 at 3:25
  • @lawlist: Thanks for the vote of confidence. – Stefan Jun 29 '15 at 12:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.