我正在编写一些自定义函数来以特定方式移动点,并且我遇到了正确管理标记和区域的问题。出于说明目的,这里有几行代码实际上并没有多大作用,它们只是将 [home] 键绑定到一个自定义函数,该函数检查标记是否已经激活 - 如果没有,它会暂时启用瞬态标记并设置标记。在所有情况下,它都会按照您的预期调用“行首”。
(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)
所以现在让我们考虑两种情况:
- [home] - 任何非移动光标移动键 - [home]
- [home] - 任何移动的光标移动键 - [home]
在 emacs 24.4 及更高版本中,一切都按我的预期运行:
- [home] 的第一次出现暂时启用瞬态标记(瞬态标记模式=(仅 .OLDVAL)。然后标记被任何未移动的光标移动命令停用,瞬态标记模式恢复为 OLDVAL在随后调用 [home] 时观察到
- 不同之处在于移动的光标移动键使标记处于活动状态,而瞬态标记暂时启用。在最后一次出现 [home] 时,在进入我的自定义函数时仍然可以观察到 transient-mark-mode = (only .OLDVAL)
现在,在 emacs 24.3 和更早的版本中,当 cua-mode 被禁用时,我仍然会得到相同的行为。但是当启用 cua-mode 时,在场景 #2 中会发生一些我不明白的事情。在这种情况下,似乎存在一些交互,并且某些东西(CUA ?)会停用标记并将瞬态标记模式恢复为 OLDVAL。谁能解释发生了什么,甚至可能更好,如何编写我的自定义函数,使其在所有情况下都具有所需的行为?(emacs 24 或 25,是否启用 cua 模式)