4

I was trying to add a custom functionality when using C-u before the "copying" command or kill-ring-save. So I jumped into the source code (pasted below for convenience) to examine what it originally does.

For brevity I will use the default binding M-w instead of M-x kill-ring-save.

It happens that doing C-u M-w sets the optional argument REGION to non-nil. From the function docstring, that would not just copy the text between BEG and END but also copy the region.

I did not understand that and so I tried out C-u M-w. But I saw no difference between M-w and C-u M-w.

Can someone please provide a way in which I can distinguish the behavior between the two?


Update

On closer inspection, I realized that actually C-u M-w and M-w will do the exact same thing.. because (prefix-numeric-value current-prefix-arg) will return 1 if no prefix arg is used, and will return 4 if C-u is used. In either case the REGION variable will be set to non-nil and the region-extract-function will be used.

So the core question is:

When does the REGION argument not get set to a non-nil value? Wouldn't prefix-numeric-value ALWAYS return something non-nil?


Source code of kill-ring-save

(defun kill-ring-save (beg end &optional region)
  "Save the region as if killed, but don't kill it.
In Transient Mark mode, deactivate the mark.
If `interprogram-cut-function' is non-nil, also save the text for a window
system cut and paste.

If you want to append the killed line to the last killed text,
use \\[append-next-kill] before \\[kill-ring-save].

The optional argument REGION if non-nil, indicates that we're not just copying
some text between BEG and END, but we're copying the region.

This command is similar to `copy-region-as-kill', except that it gives
visual feedback indicating the extent of the region being copied."
  ;; Pass mark first, then point, because the order matters when
  ;; calling `kill-append'.
  (interactive (list (mark) (point)
             (prefix-numeric-value current-prefix-arg)))
  (copy-region-as-kill beg end region)
  ;; This use of called-interactively-p is correct because the code it
  ;; controls just gives the user visual feedback.
  (if (called-interactively-p 'interactive)
      (indicate-copied-region)))
  • 1
    There's no difference unless you customize region-extract-function or filter-buffer-substring-function: by default filter-buffer-substring will be called in both cases. – abo-abo Aug 21 '15 at 16:14
  • @abo-abo Thanks! Can you please make that an answer. I see that as the delete var is set to 'delete (and not 'delete-only), region-extract-function simply ends up being a wrapper for filter-buffer-substring. – Kaushal Modi Aug 21 '15 at 16:21
  • @abo-abo I have updated my question.. I came to a realization that the REGION var would never be able to be nil.. – Kaushal Modi Aug 21 '15 at 17:02
  • 2
    I agree that the doc string is unclear - not helpful in this regard - in fact, horrible. It should say what it means by "we're copying the region". There is a precise meaning, and it is not at all conveyed by the existing doc string. I've filed Emacs bug #21315 for this. – Drew Aug 21 '15 at 17:21
  • Argument REGION is never nil interactively. It can be nil from Lisp. Again, the doc string is poor. – Drew Dec 4 '15 at 17:58

Your Answer

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

Browse other questions tagged or ask your own question.