有没有在dired-mode显示git仓库当前分支或其它信息的办法?

能够自动检测当前目录是否为git仓库,如果是的话,显示当前分支的名字或者其它信息?

这儿有个同样的问题,可惜没有得到解答:

可能有点难度,vc-mode 这个变量可以提供一个 buffer 的版本控制信息,但是 vc-mode 在 dired-mode buffer 里的值是nil。

1 个赞

可以参考 https://github.com/syohex/emacs-dired-k 里边利用git输出的信息

自己维护一个mode line 变量,在非git 仓库内不显示,手动绑定magit / vc 的接口更新。

做一个简单的尝试,只关心分支名称

;;; * 1. 得到分支名称
;; 
;; ~/.emacs.d $ git symbolic-ref HEAD
;; refs/heads/maste

(defun dired-git-mode-get-branch ()
  "返回分支名, 如果不在 Git 项目中返回 nil."
  (with-temp-buffer
    (and (zerop (call-process "git" nil t nil "symbolic-ref" "HEAD"))
         (goto-char (point-min))
         (re-search-forward "^\\(?:refs/heads/\\)?\\(.+\\)$" nil t)
         (match-string 1))))

(dired-git-mode-get-branch)
;; => nil

(let ((default-directory user-emacs-directory))
  (dired-git-mode-get-branch))
;; => "master"

;;; * 2. 写个 Minor Mode,利用它的 Lighter 来显示分支名称

(defvar-local dired-git-mode-string nil)

(defun dired-git-mode-string-update ()
  (let ((branch (dired-git-mode-get-branch)))
    (when branch
      (setq dired-git-mode-string (concat " " branch)))))

(define-minor-mode dired-git-mode
  "显示 Git 信息."
  :lighter dired-git-mode-string
  (unless (eq major-mode 'dired-mode)
    (error "Dired Git Mode 只能用在 Dired 中"))
  (when dired-git-mode
    (dired-git-mode-string-update)))


;;; * 3. 进入 Dired 时自动启动 `dired-git-mode'

(add-hook 'dired-mode-hook #'dired-git-mode)

;;; * 4. 在 Dired 中按下 g 时刷新

;; XXX 有更好的办法?
(define-advice dired-revert (:after (&rest _) dired-git-mode-string-update)
  (dired-git-mode-string-update))

(vc-git–symbolic-ref dired-directory)