Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Emacs - notify when a file has been modified externally

How do I make emacs notify me about the fact that one or more visited files are changed from elsewhere? Here's how this functionality is implemented in Gedit:

gedit - notify about external changes

I've taken a look at the approaches explained in the "Revert Buffer" document at EmacsWiki and found sort of a workaround (modified a bit for my personal preference):

(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

That's great, but what I would like is to have an automatic solution. Maybe, some kind of noisy message inlined in a buffer (like in the screenshot). Maybe, even a modal dialog as implemented in Visual Studio (that's annoying, but it does the trick, after all). What would be your suggestions?

like image 810
Eugene Burmako Avatar asked Aug 11 '11 18:08

Eugene Burmako


1 Answers

Here's what I've been able to come up with - big thanks to the guys from EmacsWiki for hints. I created a callback that gets triggered every few seconds - it checks modtime and displays an annoying message if the file has been modified.

On the upside, the solution mostly works and notifies me about changes regardless of whether the buffer is modified or not. On the downside, it involves constant polling of current file for modtime, but my work scenarios can tolerate that.

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")))))))
like image 184
Eugene Burmako Avatar answered Sep 24 '22 15:09

Eugene Burmako