简体   繁体   中英

Interaction between transient-mark-mode and cua-mode?

I'm writing some custom functions to move the point in specific ways, and I'm running into issues to manage the mark & region properly. For illustration purposes, here are a few lines of codes which don't do much really, they merely bind the [home] key to a custom function that checks if the mark is already active or not - if not it temporarily enables transient-mark and sets the mark. In all cases it then calls 'beginning-of-line' as you expect.

(defmacro setq-local (var val)
  (list 'set (list 'make-local-variable (list 'quote var)) val))

(defun my-beginning-of-line ()
  (interactive)

 (message "entering my-beginning-of-line: transient-mark-mode = %s" transient-mark-mode)

  ; Straight from "handle-shift-selection" in emacs 25.2
 (unless (and mark-active (eq (car-safe transient-mark-mode) 'only))
    (setq-local transient-mark-mode (cons 'only (unless (eq transient-mark-mode 'lambda) transient-mark-mode)))
    (push-mark nil nil t))

  (beginning-of-line)

  (message "exiting my-beginning-of-line: transient-mark-mode = %s\n" transient-mark-mode))

(global-set-key   [home]           'my-beginning-of-line)

So now let's consider two scenarios:

  1. [home] - any non-shifted cursor motion keys - [home]
  2. [home] - any shifted cursor motion keys - [home]

In emacs 24.4 and later versions, everything behaves as I expect:

  1. The first occurence of [home] temporarily enables transient-mark (transient-mark-mode = (only . OLDVAL). The mark is then deactivated by any unshifted cursor motion command, and transient-mark-mode is restored to OLDVAL as can be observed in the subsequent invocation of [home]
  2. The difference is that the shifted cursor motion keys leave the mark active and transient-mark temporarily enabled. On the last occurence of [home] it can still be observed that transient-mark-mode = (only . OLDVAL) when entering my custom function

Now, in emacs 24.3 and earlier versions, I still get the same behaviour when cua-mode is disabled. But when cua-mode is enabled, something that I don't understand is going on in scenario #2. In this case there seems to be some interaction, and that something (CUA ?) deactivates the mark and restores transient-mark-mode to OLDVAL. Can anyone explain what happens, and possibly even better, how to write my custom function so that it has the desired behaviour in all circumstances ? (emacs 24 or 25, cua-mode enabled or not)

I believe I have the beginning of an answer. There are two problems apparently.

The first one has to do with the implementation of cua--post-command-handler-1 in emacs 24.3 and earlier, which contains this:

  ;; Disable transient-mark-mode if rectangle active in current buffer.
  (if (not (window-minibuffer-p (selected-window)))
      (setq transient-mark-mode (and (not cua--rectangle)
                     (if cua-highlight-region-shift-only
                     (not cua--explicit-region-start)
                       t))))

The second problem is general to 'cua-mode': when enabled it seems to change 'shift-select-mode' to 'nil' (in emacs 24.3 and earlier). Manually forcing 'shift-select-mode' to t after enabling cua-mode does not seem to be a viable option though, as the usual shift-selection (without my custom [home] involved at all) is completely screwed up in this case.

Although I can vaguely understand why things don't work, I am still totally unclear how to write custom functions in my .emacs that can work with versions 24.3 as well as 24.4

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM