;; To enable in all Dired buffers, add this to your init file:
;;
;; (add-hook 'dired-mode-hook 'diff-hl-dired-mode)
+;;
+;; or
+;;
+;; (add-hook 'dired-mode-hook 'diff-hl-dired-mode-unless-remote)
+;;
+;; to do it only in local Dired buffers.
;;; Code:
(require 'diff-hl)
+(require 'dired)
(defvar diff-hl-dired-process-buffer nil)
"Face used to highlight changed files.")
(defface diff-hl-dired-unknown
- '((default :inherit diff-header))
+ '((default :inherit dired-ignored))
"Face used to highlight unregistered files.")
(defface diff-hl-dired-ignored
- '((default :inherit shadow))
+ '((default :inherit dired-ignored))
"Face used to highlight unregistered files.")
+(defcustom diff-hl-dired-extra-indicators t
+ "Non-nil to indicate ignored files."
+ :group 'diff-hl
+ :type 'boolean)
+
;;;###autoload
(define-minor-mode diff-hl-dired-mode
"Toggle VC diff highlighting on the side of a Dired window."
(with-current-buffer diff-hl-dired-process-buffer
(setq default-directory (expand-file-name def-dir))
(erase-buffer)
- (vc-call-backend
- backend 'dir-status def-dir
+ (diff-hl-dired-status-files
+ backend def-dir
+ (when diff-hl-dired-extra-indicators
+ (cl-loop for file in (directory-files def-dir)
+ unless (member file '("." ".." ".hg"))
+ collect file))
(lambda (entries &optional more-to-come)
(when (buffer-live-p buffer)
(with-current-buffer buffer
(dolist (entry entries)
- (cl-destructuring-bind (file state &rest) entry
+ (cl-destructuring-bind (file state &rest r) entry
+ ;; Work around http://debbugs.gnu.org/18605
+ (setq file (replace-regexp-in-string "\\` " "" file))
(let ((type (plist-get
'(edited change added insert removed delete
- unregistered unknown)
+ unregistered unknown ignored ignored)
state)))
(if (string-match "\\`\\([^/]+\\)/" file)
(let* ((dir (match-string 1 file))
(value (cdr (assoc dir dirs-alist))))
(unless (eq value type)
- (if (null value)
- (push (cons dir type) dirs-alist)
- (setcdr (assoc dir dirs-alist) 'change))))
+ (cond
+ ((eq type 'up-to-date))
+ ((null value)
+ (push (cons dir type) dirs-alist))
+ ((not (eq type 'ignored))
+ (setcdr (assoc dir dirs-alist) 'change)))))
(push (cons file type) files-alist)))))
(unless more-to-come
- (diff-hl-dired-highlight-items (append dirs-alist
- files-alist))
- (diff-hl-dired-update-ignores backend def-dir)))))
+ (diff-hl-dired-highlight-items
+ (append dirs-alist files-alist))))))
)))))
-(defun diff-hl-dired-update-ignores (backend def-dir)
- (let ((buffer (current-buffer))
- entries-alist)
- (with-current-buffer diff-hl-dired-process-buffer
- (erase-buffer)
- (vc-call-backend
- backend 'dir-status-files def-dir
- (cl-loop for file in (directory-files def-dir)
- unless (member file '("." ".."))
- collect file)
- nil
- (lambda (entries &optional more-to-come)
- (when (buffer-live-p buffer)
- (with-current-buffer buffer
- (dolist (entry entries)
- (cl-destructuring-bind (file state &rest) entry
- ;; Work around http://debbugs.gnu.org/18605
- (setq file (replace-regexp-in-string "\\` " "" file))
- (when (eq state 'ignored)
- (push (cons (directory-file-name file)
- 'ignored) entries-alist))))
- (unless more-to-come
- (diff-hl-dired-highlight-items entries-alist)))))
- ))))
+(defun diff-hl-dired-status-files (backend dir files update-function)
+ "Using version control BACKEND, return list of (FILE STATE EXTRA) entries
+for DIR containing FILES. Call UPDATE-FUNCTION as entries are added."
+ (if (version< "25" emacs-version)
+ (vc-call-backend backend 'dir-status-files dir files update-function)
+ (vc-call-backend backend 'dir-status-files dir files nil update-function)))
+
+(when (version< emacs-version "24.4.51.5")
+ ;; Work around http://debbugs.gnu.org/19386
+ (defadvice vc-git-dir-status-goto-stage (around
+ diff-hl-dired-skip-up-to-date
+ (stage files update-function)
+ activate)
+ (when (eq stage 'ls-files-up-to-date)
+ (setq stage 'diff-index))
+ ad-do-it))
(defun diff-hl-dired-highlight-items (alist)
"Highlight ALIST containing (FILE . TYPE) elements."
(defalias 'diff-hl-dired-clear 'diff-hl-remove-overlays)
+(defun diff-hl-dired-mode-unless-remote ()
+ (unless (file-remote-p default-directory)
+ (diff-hl-dired-mode)))
+
(provide 'diff-hl-dired)
;;; diff-hl-dired.el ends here