Delay inserting and washing of big diffs.

* magit.el (magit-set-section-needs-refresh-on-show): New.
(magit-section-set-hidden): Call magit-refresh when a
'needs-refresh-on-show' section is shown.
(magit-show-level): Wrap it in magit-with-refresh.
(magit-wash-diff, magit-wash-diff-section): Factored washing and
section construction into seperate functions.
(magit-insert-diff, magit-wash-numstat-diffs,
magit-wash-numstat-diff): New.  Use magit-insert-diff for visible
sections or for small changes.
(magit-insert-unstaged-changes): Use a numstat diff instead of a full diff.
(magit-insert-staged-changes): Likewise.
This commit is contained in:
Marius Vollmer 2009-06-06 23:49:02 +03:00
parent 80f990f94e
commit fb7ede719c

214
magit.el
View file

@ -463,7 +463,8 @@ Many Magit faces inherit from this one by default."
;; parent and grand-parent, etc provide the context. ;; parent and grand-parent, etc provide the context.
(defstruct magit-section (defstruct magit-section
parent title beginning end children hidden type info) parent title beginning end children hidden type info
needs-refresh-on-show)
(defvar magit-top-section nil) (defvar magit-top-section nil)
(make-variable-buffer-local 'magit-top-section) (make-variable-buffer-local 'magit-top-section)
@ -513,6 +514,11 @@ Many Magit faces inherit from this one by default."
(defun magit-set-section-info (info &optional section) (defun magit-set-section-info (info &optional section)
(setf (magit-section-info (or section magit-top-section)) info)) (setf (magit-section-info (or section magit-top-section)) info))
(defun magit-set-section-needs-refresh-on-show (flag &optional section)
(setf (magit-section-needs-refresh-on-show
(or section magit-top-section))
flag))
(defmacro magit-create-buffer-sections (&rest body) (defmacro magit-create-buffer-sections (&rest body)
(declare (indent 0)) (declare (indent 0))
`(let ((inhibit-read-only t)) `(let ((inhibit-read-only t))
@ -695,16 +701,19 @@ Many Magit faces inherit from this one by default."
(defun magit-section-set-hidden (section hidden) (defun magit-section-set-hidden (section hidden)
(setf (magit-section-hidden section) hidden) (setf (magit-section-hidden section) hidden)
(let ((inhibit-read-only t) (if (and (not hidden)
(beg (save-excursion (magit-section-needs-refresh-on-show section))
(goto-char (magit-section-beginning section)) (magit-refresh)
(forward-line) (let ((inhibit-read-only t)
(point))) (beg (save-excursion
(end (magit-section-end section))) (goto-char (magit-section-beginning section))
(put-text-property beg end 'invisible hidden)) (forward-line)
(if (not hidden) (point)))
(dolist (c (magit-section-children section)) (end (magit-section-end section)))
(magit-section-set-hidden c (magit-section-hidden c))))) (put-text-property beg end 'invisible hidden))
(if (not hidden)
(dolist (c (magit-section-children section))
(magit-section-set-hidden c (magit-section-hidden c))))))
(defun magit-section-any-hidden (section) (defun magit-section-any-hidden (section)
(or (magit-section-hidden section) (or (magit-section-hidden section)
@ -791,10 +800,11 @@ Many Magit faces inherit from this one by default."
(magit-section-show-level c (1+ level) threshold nil))))) (magit-section-show-level c (1+ level) threshold nil)))))
(defun magit-show-level (level all) (defun magit-show-level (level all)
(if all (magit-with-refresh
(magit-section-show-level magit-top-section 0 level nil) (if all
(let ((path (reverse (magit-section-lineage (magit-current-section))))) (magit-section-show-level magit-top-section 0 level nil)
(magit-section-show-level (car path) 0 level (cdr path))))) (let ((path (reverse (magit-section-lineage (magit-current-section)))))
(magit-section-show-level (car path) 0 level (cdr path))))))
(defun magit-show-only-files () (defun magit-show-only-files ()
(interactive) (interactive)
@ -1456,71 +1466,71 @@ Please see the manual for a complete description of Magit.
(defvar magit-hide-diffs nil) (defvar magit-hide-diffs nil)
(defun magit-wash-diff () (defun magit-wash-diff-section ()
(cond ((looking-at "^\\* Unmerged path \\(.*\\)") (cond ((looking-at "^\\* Unmerged path \\(.*\\)")
(let ((file (match-string-no-properties 1))) (delete-region (point) (line-end-position))
(magit-with-section file 'diff (insert "\tUnmerged " file "\n")
(delete-region (point) (line-end-position)) (magit-set-section-info (list 'unmerged file nil))
(insert "\tUnmerged " file "\n")
(magit-set-section-info (list 'unmerged file nil))))
t) t)
((looking-at "^diff") ((looking-at "^diff")
(let ((magit-section-hidden-default magit-hide-diffs)) (let ((file (magit-diff-line-file))
(magit-with-section (magit-current-line) 'diff (end (save-excursion
(let ((file (magit-diff-line-file)) (forward-line) ;; skip over "diff" line
(end (save-excursion (if (search-forward-regexp "^diff\\|^@@" nil t)
(forward-line) ;; skip over "diff" line (goto-char (match-beginning 0))
(if (search-forward-regexp "^diff\\|^@@" nil t) (goto-char (point-max)))
(goto-char (match-beginning 0)) (point-marker))))
(goto-char (point-max))) (let* ((status (cond
(point-marker)))) ((looking-at "^diff --cc")
(let* ((status (cond 'unmerged)
((looking-at "^diff --cc") ((save-excursion
'unmerged) (search-forward-regexp "^new file" end t))
((save-excursion 'new)
(search-forward-regexp "^new file" end t)) ((save-excursion
'new) (search-forward-regexp "^new mode" end t))
((save-excursion 'mode)
(search-forward-regexp "^new mode" end t)) ((save-excursion
'mode) (search-forward-regexp "^deleted" end t))
((save-excursion 'deleted)
(search-forward-regexp "^deleted" end t)) ((save-excursion
'deleted) (search-forward-regexp "^rename" end t))
((save-excursion 'renamed)
(search-forward-regexp "^rename" end t)) (t
'renamed) 'modified)))
(t (file2 (cond
'modified))) ((save-excursion
(file2 (cond (search-forward-regexp "^rename from \\(.*\\)"
((save-excursion end t))
(search-forward-regexp "^rename from \\(.*\\)" (match-string-no-properties 1))))
end t)) (status-text (case status
(match-string-no-properties 1)))) ((unmerged)
(status-text (case status (format "Unmerged %s" file))
((unmerged) ((new)
(format "Unmerged %s" file)) (format "New %s" file))
((new) ((mode)
(format "New %s" file)) (format "New mode %s" file))
((mode) ((deleted)
(format "New mode %s" file)) (format "Deleted %s" file))
((deleted) ((renamed)
(format "Deleted %s" file)) (format "Renamed %s (from %s)"
((renamed) file file2))
(format "Renamed %s (from %s)" ((modified)
file file2)) (format "Modified %s" file))
((modified) (
(format "Modified %s" file)) (format "? %s" file)))))
( (magit-set-section-info (list status file file2))
(format "? %s" file))))) (insert "\t" status-text "\n")
(magit-set-section-info (list status file file2)) (goto-char end)
(insert "\t" status-text "\n") (let ((magit-section-hidden-default nil))
(goto-char end) (magit-wash-sequence #'magit-wash-hunk))))
(let ((magit-section-hidden-default nil)) t)
(magit-wash-sequence #'magit-wash-hunk))
t)))))
(t (t
nil))) nil)))
(defun magit-wash-diff ()
(magit-with-section (magit-current-line) 'diff
(magit-wash-section-diff)))
(defun magit-diff-item-kind (diff) (defun magit-diff-item-kind (diff)
(car (magit-section-info diff))) (car (magit-section-info diff)))
@ -1552,6 +1562,41 @@ Please see the manual for a complete description of Magit.
(t (t
nil))) nil)))
(defun magit-insert-diff (file)
(let ((cmd magit-git-executable)
(args (append magit-git-standard-options
(list "diff")
magit-diff-options
(list "--" file))))
(let ((p (point)))
(apply 'process-file cmd nil t nil args)
(if (not (eq (char-before) ?\n))
(insert "\n"))
(save-restriction
(narrow-to-region p (point))
(goto-char p)
(magit-wash-diff-section)
(goto-char (point-max))))))
(defun magit-wash-numstat-diffs ()
(magit-wash-sequence #'magit-wash-numstat-diff))
(defun magit-wash-numstat-diff ()
(if (looking-at "\\(^[0-9-]+\\)\t\\([0-9-]+\\)\t\\(.*\\)$")
(let ((added (string-to-number (match-string 1)))
(deleted (string-to-number (match-string 2)))
(file (match-string-no-properties 3)))
(magit-with-section file 'diff
(delete-region (point) (+ (line-end-position) 1))
(if (or (not (magit-section-hidden magit-top-section))
(< (+ added deleted) 20))
(magit-insert-diff file)
(magit-set-section-info (list 'modified file nil))
(magit-set-section-needs-refresh-on-show t)
(insert (format "\tModified %s (+%d -%d)\n" file added deleted))))
t)
nil))
(defun magit-hunk-item-diff (hunk) (defun magit-hunk-item-diff (hunk)
(let ((diff (magit-section-parent hunk))) (let ((diff (magit-section-parent hunk)))
(or (eq (magit-section-type diff) 'diff) (or (eq (magit-section-type diff) 'diff)
@ -1654,18 +1699,19 @@ Please see the manual for a complete description of Magit.
(defun magit-insert-unstaged-changes (title) (defun magit-insert-unstaged-changes (title)
(let ((magit-hide-diffs t)) (let ((magit-hide-diffs t))
(magit-git-section 'unstaged title 'magit-wash-diffs (let ((magit-diff-options '()))
"diff" (magit-diff-U-arg)))) (magit-git-section 'unstaged title 'magit-wash-numstat-diffs
"diff" "--numstat"))))
(defun magit-insert-staged-changes (no-commit) (defun magit-insert-staged-changes (no-commit)
(let ((magit-hide-diffs t)) (let ((magit-hide-diffs t)
(if no-commit (base (if no-commit
(let ((null-tree (magit-git-string "mktree </dev/null"))) (magit-git-string "mktree </dev/null")
(magit-git-section 'staged "Staged changes:" 'magit-wash-diffs "HEAD")))
"diff" "--cached" (magit-diff-U-arg) (let ((magit-diff-options '("--cached")))
null-tree)) (magit-git-section 'staged "Staged changes:" 'magit-wash-numstat-diffs
(magit-git-section 'staged "Staged changes:" 'magit-wash-diffs "diff" "--cached" "--numstat"
"diff" "--cached" (magit-diff-U-arg))))) base))))
;;; Logs and Commits ;;; Logs and Commits