Emacs 在瞬态标记模式下,如何在elisp中使区域瞬态

Emacs 在瞬态标记模式下,如何在elisp中使区域瞬态,emacs,elisp,Emacs,Elisp,我编写了一个elisp宏,在瞬态标记模式下保留该区域: (defmacro keep-region (command) "Wrap command in code that saves and restores the region" (letrec ((command-name (symbol-name command)) (advice-name (concat command-name "-keep-region"))) `(progn

我编写了一个elisp宏,在
瞬态标记模式下保留该区域:

(defmacro keep-region (command)
  "Wrap command in code that saves and restores the region"
  (letrec ((command-name (symbol-name command))
           (advice-name (concat command-name "-keep-region")))
    `(progn
       (defadvice ,command (around ,(intern advice-name))
         (let (deactivate-mark)
           (save-excursion
             ad-do-it)))
       (ad-activate (quote ,command)))))

(keep-region replace-string)
(keep-region replace-regexp)
(defmacro keep-region (command)
  "Wrap command in code that saves and restores the region"
  (letrec ((command-name (symbol-name command))
           (advice-name (concat command-name "-keep-region")))
    `(progn
       (defadvice ,command (around ,(intern advice-name))
         (let ((deactivate-mark nil)
               (transient-mark-mode transient-mark-mode))
           (save-excursion
             ad-do-it)))
       (ad-activate (quote ,command)))))
这将为使用
keep region
宏建议的命令保留区域;如果要在选定块中进行多个替换,这将非常有用

问题是,在运行使用此宏建议的命令后,区域将失去其瞬态特性;后续的移动命令扩展该区域,而不是取消选择该区域


如何以编程方式重新启用标记区域的瞬态?

C-h f瞬态标记模式

(defmacro keep-region (command)
  "Wrap command in code that saves and restores the region"
  (letrec ((command-name (symbol-name command))
           (advice-name (concat command-name "-keep-region")))
    `(progn
       (defadvice ,command (around ,(intern advice-name))
         (let (deactivate-mark)
           (save-excursion
             ad-do-it)))
       (ad-activate (quote ,command)))))

(keep-region replace-string)
(keep-region replace-regexp)
(defmacro keep-region (command)
  "Wrap command in code that saves and restores the region"
  (letrec ((command-name (symbol-name command))
           (advice-name (concat command-name "-keep-region")))
    `(progn
       (defadvice ,command (around ,(intern advice-name))
         (let ((deactivate-mark nil)
               (transient-mark-mode transient-mark-mode))
           (save-excursion
             ad-do-it)))
       (ad-activate (quote ,command)))))
瞬态标记模式是一种全局次要模式。如果启用,则 当标记处于活动状态时,区域将高亮显示。标志是 通过更改缓冲区,以及在某些其他 设置标记但其主要目的是 否则--例如,增量搜索

因此,
交换点后的
激活标记
,标记
应恢复标记的瞬态性质


不过,我不确定您为什么在这里使用
交换点和标记,以及为什么要调用它两次。在我看来,只要将
(point)
(mark)
保存在
中,让
之后绑定和恢复它们就会更容易
push-mark
pop-mark
也可能有帮助,因为后者会自动重新激活标记。

只需删除对
交换点和标记的调用即可。保存是通过
无效标记
let绑定完成的

问题是,在运行使用此宏建议的命令后,区域将失去其瞬态特性;后续的移动命令扩展该区域,而不是取消选择该区域

您更应该谈论“shift selected nature”:扩展区域的移动命令是以“正常”方式激活标记时发生的情况

换档选择状态存储在
瞬态标记模式
变量中,由不关心
停用标记
值的人员(
处理换档选择
?)修改。我们可以通过保存
瞬态标记模式的值来解决此问题:

(defmacro keep-region (command)
  "Wrap command in code that saves and restores the region"
  (letrec ((command-name (symbol-name command))
           (advice-name (concat command-name "-keep-region")))
    `(progn
       (defadvice ,command (around ,(intern advice-name))
         (let (deactivate-mark)
           (save-excursion
             ad-do-it)))
       (ad-activate (quote ,command)))))

(keep-region replace-string)
(keep-region replace-regexp)
(defmacro keep-region (command)
  "Wrap command in code that saves and restores the region"
  (letrec ((command-name (symbol-name command))
           (advice-name (concat command-name "-keep-region")))
    `(progn
       (defadvice ,command (around ,(intern advice-name))
         (let ((deactivate-mark nil)
               (transient-mark-mode transient-mark-mode))
           (save-excursion
             ad-do-it)))
       (ad-activate (quote ,command)))))

瞬态标记模式是“buffer.c”中定义的变量

Lisp程序可能会为该变量提供某些特殊值:

  • (仅.OLDVAL)
    临时启用瞬态标记模式。在任何后续的点运动命令之后 转换换档,或任何其他通常会停用的操作 标记(如缓冲区修改),值
    `“瞬态标记模式”设置为OLDVAL

您是对的,保存不依赖于交换点和标记,但删除后仍然存在相同的问题;所选区域仍然是非瞬态的。它是瞬态的。只是不一样的瞬间。您想要“在我进行非移位移动时消失的瞬态”,但
C-x C-x
仅提供“在下一个命令关闭或停用标记时消失的瞬态”。是的,我想要瞬态标记模式提供给您的瞬态。这就是我问题的全部要点:)我如何在elisp中为这个宏创建这样的选择?
保留区域
,我写的,我的问题中的一个。我在这个问题上增加了500个悬赏,如果这能提高它得到回答的概率,我会打两次电话给它,因为在编辑器中,我能找到的最简单的方法是在一个块操作(如替换)后重新选择。和
激活标记
不起作用,它仍然是非瞬态的,无论我是否调用
交换点和标记
.AIUI,
保存偏移
保存和恢复点和标记;不知道为什么明确地这样做会有帮助。另外,不知道如何直接设置点,特别是在所选文本的长度已从替换文本更改的情况下。FWIW,我在问题上添加了500悬赏,以防您能提供帮助。这看起来像是成功了!很好<代码>瞬态标记模式
看起来像是钥匙。