Search code examples
emacselisp

Should `copy-region-as-kill` be modified to include `(setq transient-mark-mode nil)`?


When using the post-command-hook following copy-region-as-kill and the post-command-hook includes a test for region-active-p, that test returns positive because transient-mark-mode has not yet been returned to nil.

Is the post-command-hook designed to act upon what was in existence before this-command was executed, or should the post-command-hook be looking at the world as if this-command has already run its course?


EDIT:  My apologies for not specifying that I am using the latest version of Emacs Trunk. Here is the current function that performs the test:

(defun region-active-p ()
  (and transient-mark-mode mark-active (mark)))

Here is the message from M-x emacs-version:

GNU Emacs 24.4.50.1 (x86_64-apple-darwin10.8.0,
  NS appkit-1038.36 Version 10.6.8 (Build 10K549)) of 2014-06-01 on MP.local 

Here is an example of the active region that hypothetically may need to be copied using copy-region-as-kill, and tested for while the post-command-hook is running. [That way, the new overlays can be placed with calculations assuming there is no active region.] In the context of this example, I need the test to return nil when this-command equals copy-region-as-kill and one way to accomplish that goal is to modify copy-region-as-kill to include (setq transient-mark-mode nil) at the tail end of the function. However, I hesitate to modify a staple function like copy-region-as-kill. [It wouldn't make much sense (in my opinion) to include conditions that state if region-active-p and this-command equals copy-region-as-kill, then pretend the region isn't active.]

Example
(source: lawlist.com)


Solution

  • INITIAL DRAFT (June 4, 2014):  After looking at the documentation and the helpful comments and answers in this thread, I'm strongly leaning in favor of a new test specifically designed to be used inside the post-command-hook. This will avoid modifying the core / staple functions of kill-region, copy-region-as-kill, and yank. Since the new function will be included in my own library for the minor-mode, there is no reason why I can't base some of the basic calculations on said function. The function entitled deactivate-mark in simple.el uses (setq mark-active nil) and (setq transient-mark-mode nil), so there is no reason why I can't use them also in my own custom function.

    • Special thanks to @Andreas Röhler, @event_jr, and @Stefan -- greatly appreciated!

    EDIT (June 5, 2014):  Revised initial draft to merely test conditions, rather than setting either of the variables (mark-active or transient-mark-mode) to nil.

    (defun lawlist-region-active-p ()
    "Custom test to determine whether the region is presently active; AND,
    whether the region will be active when the `post-command-hook` finishes."
      (cond
        ((memq this-command '(
            self-insert-command
            delete-backward-char
            delete-forward-char
            kill-region
            delete-region
            copy-region-as-kill
            yank
            kill-word
            lawlist-copy-selected-region
            lawlist-kill-word
            lawlist-yank ))
          nil)
        ((and transient-mark-mode mark-active (mark)))))
    
    (defun test-lawlist-region-active-p ()
      (cond
        ((lawlist-region-active-p)
          (message "ACTIVE region."))
        ((not (lawlist-region-active-p))
          (message "NOT active region."))))
    
    (add-hook 'post-command-hook 'test-lawlist-region-active-p)