+(defun stgit-advise-funlist (funlist)
+ "Add advice to the functions in FUNLIST so we can refresh the
+stgit buffers as the git status of files change."
+ (mapc (lambda (sym)
+ (when (fboundp sym)
+ (eval `(defadvice ,sym (after stgit-update-stgit-for-buffer)
+ (stgit-update-stgit-for-buffer t)))
+ (ad-activate sym)))
+ funlist))
+
+(defun stgit-advise ()
+ "Add advice to appropriate (non-stgit) git functions so we can
+refresh the stgit buffers as the git status of files change."
+ (mapc (lambda (arg)
+ (let ((feature (car arg))
+ (funlist (cdr arg)))
+ (if (featurep feature)
+ (stgit-advise-funlist funlist)
+ (add-to-list 'after-load-alist
+ `(,feature (stgit-advise-funlist
+ (quote ,funlist)))))))
+ ;; lists of (<feature> <function> <function> ...) to be advised
+ '((vc-git vc-git-rename-file vc-git-revert vc-git-register)
+ (git git-add-file git-checkout git-revert-file git-remove-file)
+ (dired dired-delete-file))))
+
+(defvar stgit-pending-refresh-buffers nil
+ "Alist of (cons `buffer' `refresh-index') of buffers that need
+to be refreshed. `refresh-index' is non-nil if both work tree
+and index need to be refreshed.")
+
+(defun stgit-run-pending-refreshs ()
+ "Run all pending stgit buffer updates as posted by `stgit-post-refresh'."
+ (let ((buffers stgit-pending-refresh-buffers)
+ (stgit-inhibit-messages t))
+ (setq stgit-pending-refresh-buffers nil)
+ (while buffers
+ (let* ((elem (car buffers))
+ (buffer (car elem))
+ (refresh-index (cdr elem)))
+ (when (buffer-name buffer)
+ (with-current-buffer buffer
+ (stgit-refresh-worktree)
+ (when refresh-index (stgit-refresh-index)))))
+ (setq buffers (cdr buffers)))))
+
+(defun stgit-post-refresh (buffer refresh-index)
+ "Update worktree status in BUFFER when Emacs becomes idle. If
+REFRESH-INDEX is non-nil, also update the index."
+ (unless stgit-pending-refresh-buffers
+ (run-with-idle-timer 0.1 nil 'stgit-run-pending-refreshs))
+ (let ((elem (assq buffer stgit-pending-refresh-buffers)))
+ (if elem
+ ;; if buffer is already present, set its refresh-index flag if
+ ;; necessary
+ (when refresh-index
+ (setcdr elem t))
+ ;; new entry
+ (setq stgit-pending-refresh-buffers
+ (cons (cons buffer refresh-index)
+ stgit-pending-refresh-buffers)))))
+
+(defun stgit-update-stgit-for-buffer (&optional refresh-index)
+ "When Emacs becomes idle, refresh worktree status in any
+`stgit-mode' buffer that shows the status of the current buffer.
+
+If REFRESH-INDEX is non-nil, also update the index."
+ (let* ((dir (cond ((derived-mode-p 'stgit-status-mode 'dired-mode)
+ default-directory)
+ (buffer-file-name
+ (file-name-directory
+ (expand-file-name buffer-file-name)))))
+ (gitdir (and dir (condition-case nil (git-get-top-dir dir)
+ (error nil))))