Emacs - 当文件在外部被修改时通知

5
我该如何让emacs通知我当前打开的一个或多个文件已经被其他程序修改?下面是Gedit实现这一功能的方法:

gedit - notify about external changes

我已经查看了EmacsWiki上"Revert Buffer"文档中解释的方法,并找到了一种解决方法(根据我的个人喜好进行了修改):

(global-set-key (kbd "<f5>") (lambda ()
  (interactive)
  (if (string= (buffer-name) ecb-directories-buffer-name)
    (refresh-ecb)
    (if (buffer-modified-p)
      (revert-buffer) ; ask for confirmation
      (revert-buffer t t))))) ; don't ask for confirmation - it's unnecessary, since the buffer hasn't been modified

很好,但我希望有自动化的解决方案。也许是一些嵌入缓冲区的嘈杂信息(就像屏幕截图中的那样)。甚至可以像Visual Studio中实现的模态对话框一样(虽然很烦人,但毕竟它起到了作用)。你有什么建议?


2
Emacs不会在缓冲区在Emacs之外被修改时弹出一个问题警告吗?这不够吵吗? - Tom
是的,它确实会响应,但只有在缓冲区不脏的情况下,而且只有当我开始输入时才会响应,但不会立即响应当我切换到该缓冲区。 - Eugene Burmako
如果可能的话,请更新该图片。 - Mirzhan Irkegulov
嘿,我刚才在清理我的g+账户,不小心把所有图片都设为私有,没有删除它们。所以只需要简单的权限修复就行了。现在你可以访问吗? - Eugene Burmako
图片已经损坏了。如果我没记错,操作系统可以让你上传图片。请使用该功能,而不是不可靠的外部主机。 - phils
2个回答

4
这是我能想到的 - 非常感谢EmacsWiki的提示。我创建了一个回调函数,每隔几秒钟触发一次 - 它检查修改时间并显示一个烦人的消息,如果文件已被修改。
好处是,解决方案大多数情况下都有效,并且无论缓冲区是否被修改都会通知我更改。缺点是,它涉及对当前文件的修改时间进行不断轮询,但我的工作场景可以容忍这种情况。

emacs notify external changes

;(global-auto-revert-mode 1)
(defun ask-user-about-supersession-threat (fn) "blatantly ignore files that changed on disk")
(run-with-timer 0 2 'my-check-external-modifications)
(add-hook 'after-save-hook 'my-check-external-modifications)
(add-hook 'after-revert-hook 'my-check-external-modifications)

(defun my-load-external-modifications ()
  (interactive)
  (if (string= (buffer-name) ecb-directories-buffer-name)
    (refresh-ecb)
    (if (buffer-modified-p)
      (revert-buffer) ; ask for confirmation
      (revert-buffer t t)) ; don't ask for confirmation - it's unnecessary, since the buffer hasn't been modified
    (my-check-external-modifications))) 

(defun my-overwrite-external-modifications ()
  (interactive)
  (clear-visited-file-modtime)
  (set-buffer-modified-p (current-buffer))
  (save-buffer)
  (my-check-external-modifications))

(defun my-check-external-modifications ()
  (if (verify-visited-file-modtime (current-buffer))
    (progn
      (global-set-key (kbd "<f5>") 'my-load-external-modifications)
      (global-set-key (kbd "C-s") 'save-buffer)
      (setq header-line-format tabbar-header-line-format))
    (progn
      (global-set-key (kbd "<f5>") 'my-load-external-modifications)
      (global-set-key (kbd "C-s") 'my-overwrite-external-modifications)
      (setq header-line-format (format "%s. Press F5 to load external changes, C-s to overwrite them"
        (propertize "This file has been changed externally" 'face '(:foreground "#f00")))))))

你提到了阅读有关还原的维基百科,但我想在这里也提一下:在许多情况下,auto-revert-mode或global-auto-revert-mode是一个好的解决方案。该模式可以通过auto-revert-mode-interval和auto-revert-mode-hook变量进行修改。我知道你考虑过这种方法,因为你的代码示例在顶部注释掉了global-auto-revert-mode,但这可能对其他人有用。 - R. P. Dillon
可能是因为我的代码引用了 ECB,而你可能没有安装。此外,你的 Emacs 版本和我的版本(我的是 23.2.1)可能存在差异。最后,在 Emacs 中调试东西有两个我知道的选项:1)使用 --debug-init 运行 Emacs 来调试 .emacs 中的错误,2)在你的 .emacs 中放置 (setq stack-trace-on-error t) 或 (setq debug-on-error t) 来调试运行时错误。 - Eugene Burmako

2
如果您希望对脏缓冲区进行警告,那么可以建议使用 switch-to-buffer,这样当您切换到一个缓冲区并且它已被修改时,它会检查文件是否被修改,如果是,则可以像未修改的缓冲区一样提供还原选项。请保留HTML标记。

哇,谢谢!我一直在寻找类似于switch-to-buffer-hook的东西,但是没有任何运气。创建一个advice绝对是一个好方法! - Eugene Burmako

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接