save-excursion所保存的mark的状态和当前的位置只能在save-excursion内部使用吗,有没有可能被其它外部elisp函数调用

Elisp日课:save-excursion 晦涩的命名却趁手的应用 中看到save-excursion这个函数感觉超级有用。感谢 @Action @DogLooksGood 等人的分享

我将其用于在光标处插入文本之后回到光标原位置处,最近用上了elisp的websocket来插入文本,逻辑是emacs作为ws客户端,向ws服务端发数据,服务端处理完成把结果以org文本的形式发回emacs,emacs在buffer中insert

相比我原先用http来请求数据,websocket的这个过程是异步的,然后我就发现save-excursion这个函数没有效果了。

ws请求发起时我在emacs中移动了光标到其它位置,ws请求收到结果时save-excursion不能让我回到光标原位置处。

回到开头的问题: save-excursion所保存的mark的状态和当前的位置只能在save-excursion内部使用吗,有没有可能被其它外部elisp函数调用

如果你的目的仅仅是回到原来的位置, 而且 save-excursion 不管用, 我自己会直接记下最初的 (point), 比如 (setq original-pt (point)), 然后想要回到最初位置时 (goto-char original-pt) 即可

试了一下,这样可行

(progn 
  ;;记下当前位置  收到服务端发回的org文本时先执行(goto-char orgcms-point)
  (setq orgcms-point (point))
  (orgcms-ws-send "发送到服务端的文本")  )

不过这样在光标移到了其它窗口去的情况下回不来,要光标去了其它窗口也能回到原来位置,似乎只有把当前文件名也记下来

-  (setq orgcms-point (point))
+  (setq orgcms-marker (point-marker))

问题解决

(setq orgcms-buffer (current-buffer))
(setq orgcms-point (point))
(orgcms-ws-send "发送到服务端的文本")

当收到服务器端发回的消息时,先执行

(with-current-buffer orgcms-buffer
   (goto-char orgcms-point)
    ;;……
)

这样并不切换到原位置缓冲区,即能回到原位置操作又无论我当前光标在任何位置做什么事都不会被打断

用 overlay,内容改了之后 point 不一定就还是想要的位置。