I have a better way of doing this because I don't like putting unnecessary things in the post-command-hook
. Then, they are run every time you run a command. I defined the following function that only takes buffers controlled by a vc backend and refreshes all of them. Then I just set this to a keybinding in ibuffer-mode-map. I use a prefix key for all my commands in ibuffer, which is set to h
but just change the keybinding for jj/ibuffer-vc-refresh-state
. Also, I set it to run in an ibuffer-mode-hook, but if you have a ton of buffers open this might cause a bit of a lag.
(eval-after-load "ibuffer-vc"
'(progn
(defun jj/vc-refresh-state-all-buffers ()
"Refresh all vc buffer statuses by calling `vc-refresh-state` on each one if it has an associated vc backend."
(interactive)
(dolist (buf (buffer-list))
(let ((file-name (with-current-buffer buf
(file-truename (or buffer-file-name
default-directory)))))
(when (ibuffer-vc--include-file-p file-name)
(let ((backend (ibuffer-vc--deduce-backend file-name)))
(when backend
(with-current-buffer buf (vc-refresh-state))
))))))
(defun jj/ibuffer-vc-refresh-state ()
(interactive)
(jj/vc-refresh-state-all-buffers)
(ibuffer-redisplay))
))
(add-hook 'ibuffer-mode-hook 'jj/ibuffer-vc-refresh-state)
(define-prefix-command 'ibuffer-h-prefix-map)
(define-key ibuffer-mode-map (kbd "h") 'ibuffer-h-prefix-map)
(define-key ibuffer-h-prefix-map (kbd "h") 'describe-mode)
(define-key ibuffer-h-prefix-map (kbd "r") 'jj/ibuffer-vc-refresh-state)
))
Also, if you use use-package then the below is my setup:
(use-package ibuffer
:bind (
:map ibuffer-mode-map
:prefix-map ibuffer-h-prefix-map
:prefix "h"
("h" . describe-mode)
("g" . ibuffer-clear-filter-groups)
("r" . ibuffer-clear-filter-groups)))
(use-package ibuffer-vc
:bind (:map ibuffer-h-prefix-map
("v" . ibuffer-vc-set-filter-groups-by-vc-root)
("V" . jj/ibuffer-vc-refresh-state))
:config
(defun jj/vc-refresh-state-all-buffers ()
"Refresh all vc buffer statuses by calling `vc-refresh-state` on each one if it has an associated vc backend. Uses functions from `ibuffer-vc`, so decouple these functions if you need to use this without loading ibuffer-vc."
(interactive)
(dolist (buf (buffer-list))
(let ((file-name (with-current-buffer buf
(file-truename (or buffer-file-name
default-directory)))))
(when (ibuffer-vc--include-file-p file-name)
(let ((backend (ibuffer-vc--deduce-backend file-name)))
(when backend
(with-current-buffer buf (vc-refresh-state))
))))))
(defun jj/ibuffer-vc-refresh-state ()
"Refresh all vc buffer statuses and redisplay to update the current status in ibuffer."
(interactive)
(jj/vc-refresh-state-all-buffers)
(ibuffer-redisplay))
(add-hook 'ibuffer-mode-hook 'jj/ibuffer-vc-refresh-state)
)
force-mode-line-update
would have some effect but it didn't change anything.