请问这段代码为什么不能正常工作

想法是在选中文本的两端插入成对的字符后继续保留当前的选区,但是现在执行后选区并不会被激活,在函数内添加 activate-mark 也没用,运行后手动执行下 activate-mark 才能看到选区。请问是什么原因呢?

(defun my-insert-pair (open close)
  (interactive (let ((open (char-to-string (read-char "open: ")))
                     (close (char-to-string (read-char "close: "))))
                 (list open close)))
  (when (region-active-p)
    (let ((beginning (region-beginning))
          (end (region-end)))
      (insert-pair nil open close)
      (push-mark (+ beginning (length open)) t t)
      (goto-char (+ end (length open))))))


挺奇怪的,执行完后用 eval-expression 执行 (activate-mark)(setq mark-active t) 都可以激活,放在函数里面就不行。

(setq mark-active t) 加上这个试试

看你这个描述,应该操控的是region才对,其他的好像都activate不了

貌似不行 = =!

啊…创建region有什么函数吗?我之前都是用 push-mark 创建选区的,比如下面的代码就可以正常工作

(defun my-select-word()
  (interactive)
  (when-let ((position (bounds-of-thing-at-point 'word)))
    (goto-char (cdr position))
    (push-mark (car position) t t)))

我找到原因了,修改后的代码如下:

(defun my-insert-pair (open close)
  (interactive (let ((open (char-to-string (read-char "open: ")))
                     (close (char-to-string (read-char "close: "))))
                 (list open close)))
  (when (region-active-p)
    (let ((beginning (region-beginning))
          (end (region-end))
          deactivate-mark)
      (insert-pair nil open close)
      (goto-char (+ end (length open)))
      (push-mark (+ beginning (length open)) t t))))

官方文档描述:

Variable: deactivate-mark

If an editor command sets this variable non-nil, then the editor command loop deactivates the mark after the command returns (if Transient Mark mode is enabled). All the primitives that change the buffer set deactivate-mark, to deactivate the mark when the command is finished. Setting this variable makes it buffer-local.

To write Lisp code that modifies the buffer without causing deactivation of the mark at the end of the command, bind deactivate-mark to nil around the code that does the modification. For example:

 (let (deactivate-mark)
     (insert " "))

User Option: transient-mark-mode

This variable, if non- nil , enables Transient Mark mode. In Transient Mark mode, every buffer-modifying primitive sets deactivate-mark . As a consequence, most commands that modify the buffer also deactivate the mark.

When Transient Mark mode is enabled and the mark is active, many commands that normally apply to the text near point instead apply to the region. Such commands should use the function use-region-p to test whether they should operate on the region. See The Region.

Lisp programs can set transient-mark-mode to non- nil , non- t values to enable Transient Mark mode temporarily. If the value is lambda , Transient Mark mode is automatically turned off after any action, such as buffer modification, that would normally deactivate the mark. If the value is (only . oldval) , then transient-mark-mode is set to the value oldval after any subsequent command that moves point and is not shift-translated (see shift-translation), or after any other action that would normally deactivate the mark.

函数传的是region,建议可以看下comment-region或者indent-region这种对region操作的函数源码看看实例

嗯嗯 感谢,我刚在文档找到问题了,和和编辑相关的操作需要设置下 deactivate-mark