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:
- [home] - any non-shifted cursor motion keys - [home]
- [home] - any shifted cursor motion keys - [home]
In emacs 24.4 and later versions, everything behaves as I expect:
- 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]
- 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:
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