aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTino Calancha2017-01-21 11:54:38 +0900
committerTino Calancha2017-01-21 11:54:38 +0900
commit1508b538fd8f8c2e00aadcea42ac36013fad02e3 (patch)
tree5d151c617b299ced19824626bd26b7c21a25ce70
parent82a5e4dc889ecbfa35374616fe9c5edfa23f4504 (diff)
downloademacs-1508b538fd8f8c2e00aadcea42ac36013fad02e3.tar.gz
emacs-1508b538fd8f8c2e00aadcea42ac36013fad02e3.zip
; Revert "Improve diff-mode navigation/manipulation"
This reverts commit 2c8a7e50d24daf19ea7d86f1cfeaa98a41c56085. This change causes regressions: https://lists.gnu.org/archive/html/emacs-devel/2016-11/msg00738.html The following related commits are reverted as well: 61c6a10e3110490dadac4577cc540053341ff25c a283d655db88cdcc8cb53d8e2578e1cdf751c84b 6b6abe0dba6a9a2e5f78aac3814421886e7a184f e5ef59b87da5c2ddfa22f7342efe29b3eea6ed97 73349822cbd6e50526eda9c75453584d73dfca83 Fixes: debbugs:25105, 25400.
-rw-r--r--lisp/vc/diff-mode.el174
1 files changed, 34 insertions, 140 deletions
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index b50b4a254f4..4e878c404cd 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -551,124 +551,26 @@ next hunk if TRY-HARDER is non-nil; otherwise signal an error."
551 551
552;; Define diff-{hunk,file}-{prev,next} 552;; Define diff-{hunk,file}-{prev,next}
553(easy-mmode-define-navigation 553(easy-mmode-define-navigation
554 diff--internal-hunk diff-hunk-header-re "hunk" diff-end-of-hunk diff-restrict-view) 554 diff-hunk diff-hunk-header-re "hunk" diff-end-of-hunk diff-restrict-view
555 (when diff-auto-refine-mode
556 (unless (prog1 diff--auto-refine-data
557 (setq diff--auto-refine-data
558 (cons (current-buffer) (point-marker))))
559 (run-at-time 0.0 nil
560 (lambda ()
561 (when diff--auto-refine-data
562 (let ((buffer (car diff--auto-refine-data))
563 (point (cdr diff--auto-refine-data)))
564 (setq diff--auto-refine-data nil)
565 (with-local-quit
566 (when (buffer-live-p buffer)
567 (with-current-buffer buffer
568 (save-excursion
569 (goto-char point)
570 (diff-refine-hunk))))))))))))
555 571
556(easy-mmode-define-navigation 572(easy-mmode-define-navigation
557 diff--internal-file diff-file-header-re "file" diff-end-of-file) 573 diff-file diff-file-header-re "file" diff-end-of-file)
558
559(defun diff--wrap-navigation (skip-hunk-start
560 what orig
561 header-re goto-start-func count)
562 "Wrap diff-{hunk,file}-{next,prev} for more intuitive behavior.
563Override the default diff-{hunk,file}-{next,prev} implementation
564by skipping any lines that are associated with this hunk/file but
565precede the hunk-start marker. For instance, a diff file could
566contain
567
568diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
569index 923de9a..6b1c24f 100644
570--- a/lisp/vc/diff-mode.el
571+++ b/lisp/vc/diff-mode.el
572@@ -590,6 +590,22 @@
573.......
574
575If a point is on 'index', then the point is considered to be in
576this first hunk. Move the point to the @@... marker before
577executing the default diff-hunk-next/prev implementation to move
578to the NEXT marker."
579 (if (not skip-hunk-start)
580 (funcall orig count)
581
582 (let ((start (point)))
583 (funcall goto-start-func)
584
585 ;; Trap the error.
586 (condition-case nil
587 (funcall orig count)
588 (error nil))
589
590 (when (not (looking-at header-re))
591 (goto-char start)
592 (user-error (format "No %s" what)))
593
594 ;; We successfully moved to the next/prev hunk/file. Apply the
595 ;; auto-refinement if needed
596 (when diff-auto-refine-mode
597 (unless (prog1 diff--auto-refine-data
598 (setq diff--auto-refine-data
599 (cons (current-buffer) (point-marker))))
600 (run-at-time 0.0 nil
601 (lambda ()
602 (when diff--auto-refine-data
603 (let ((buffer (car diff--auto-refine-data))
604 (point (cdr diff--auto-refine-data)))
605 (setq diff--auto-refine-data nil)
606 (with-local-quit
607 (when (buffer-live-p buffer)
608 (with-current-buffer buffer
609 (save-excursion
610 (goto-char point)
611 (diff-refine-hunk))))))))))))))
612
613;; These functions all take a skip-hunk-start argument which controls
614;; whether we skip pre-hunk-start text or not. In interactive uses we
615;; always want to do this, but the simple behavior is still necessary
616;; to, for example, avoid an infinite loop:
617;;
618;; diff-hunk-next calls
619;; diff--wrap-navigation calls
620;; diff-bounds-of-hunk calls
621;; diff-beginning-of-hunk calls
622;; diff-hunk-next
623;;
624;; Here the outer diff-hunk-next has skip-hunk-start set to t, but the
625;; inner one does not, which breaks the loop.
626(defun diff-hunk-prev (&optional count skip-hunk-start)
627 "Go to the previous COUNT'th hunk."
628 (interactive (list (prefix-numeric-value current-prefix-arg) t))
629 (diff--wrap-navigation
630 skip-hunk-start
631 "prev hunk"
632 'diff--internal-hunk-prev
633 diff-hunk-header-re
634 (lambda () (goto-char (car (diff-bounds-of-hunk))))
635 count))
636
637(defun diff-hunk-next (&optional count skip-hunk-start)
638 "Go to the next COUNT'th hunk."
639 (interactive (list (prefix-numeric-value current-prefix-arg) t))
640 (diff--wrap-navigation
641 skip-hunk-start
642 "next hunk"
643 'diff--internal-hunk-next
644 diff-hunk-header-re
645 (lambda () (goto-char (car (diff-bounds-of-hunk))))
646 count))
647
648(defun diff-file-prev (&optional count skip-hunk-start)
649 "Go to the previous COUNT'th file."
650 (interactive (list (prefix-numeric-value current-prefix-arg) t))
651 (diff--wrap-navigation
652 skip-hunk-start
653 "prev file"
654 'diff--internal-file-prev
655 diff-file-header-re
656 (lambda () (goto-char (car (diff-bounds-of-file))) (diff--internal-hunk-next))
657 count))
658
659(defun diff-file-next (&optional count skip-hunk-start)
660 "Go to the next COUNT'th file."
661 (interactive (list (prefix-numeric-value current-prefix-arg) t))
662 (diff--wrap-navigation
663 skip-hunk-start
664 "next file"
665 'diff--internal-file-next
666 diff-file-header-re
667 (lambda () (goto-char (car (diff-bounds-of-file))) (diff--internal-hunk-next))
668 count))
669
670
671
672 574
673(defun diff-bounds-of-hunk () 575(defun diff-bounds-of-hunk ()
674 "Return the bounds of the diff hunk at point. 576 "Return the bounds of the diff hunk at point.
@@ -679,13 +581,12 @@ point is in a file header, return the bounds of the next hunk."
679 (let ((pos (point)) 581 (let ((pos (point))
680 (beg (diff-beginning-of-hunk t)) 582 (beg (diff-beginning-of-hunk t))
681 (end (diff-end-of-hunk))) 583 (end (diff-end-of-hunk)))
682 (cond ((> end pos) 584 (cond ((>= end pos)
683 (list beg end)) 585 (list beg end))
684 ;; If this hunk ends above POS, consider the next hunk. 586 ;; If this hunk ends above POS, consider the next hunk.
685 ((re-search-forward diff-hunk-header-re nil t) 587 ((re-search-forward diff-hunk-header-re nil t)
686 (list (match-beginning 0) (diff-end-of-hunk))) 588 (list (match-beginning 0) (diff-end-of-hunk)))
687 ;; There's no next hunk, so just take the one we have. 589 (t (error "No hunk found"))))))
688 (t (list beg end))))))
689 590
690(defun diff-bounds-of-file () 591(defun diff-bounds-of-file ()
691 "Return the bounds of the file segment at point. 592 "Return the bounds of the file segment at point.
@@ -771,7 +672,7 @@ data such as \"Index: ...\" and such."
771 (setq prevfile nextfile)) 672 (setq prevfile nextfile))
772 (if (and previndex (numberp prevfile) (< previndex prevfile)) 673 (if (and previndex (numberp prevfile) (< previndex prevfile))
773 (setq prevfile previndex)) 674 (setq prevfile previndex))
774 (if (numberp prevfile) 675 (if (and (numberp prevfile) (<= prevfile start))
775 (progn 676 (progn
776 (goto-char prevfile) 677 (goto-char prevfile)
777 ;; Now skip backward over the leading junk we may have before the 678 ;; Now skip backward over the leading junk we may have before the
@@ -1764,9 +1665,8 @@ SRC and DST are the two variants of text as returned by `diff-hunk-text'.
1764SWITCHED is non-nil if the patch is already applied. 1665SWITCHED is non-nil if the patch is already applied.
1765NOPROMPT, if non-nil, means not to prompt the user." 1666NOPROMPT, if non-nil, means not to prompt the user."
1766 (save-excursion 1667 (save-excursion
1767 (let* ((hunk-bounds (diff-bounds-of-hunk)) 1668 (let* ((other (diff-xor other-file diff-jump-to-old-file))
1768 (other (diff-xor other-file diff-jump-to-old-file)) 1669 (char-offset (- (point) (diff-beginning-of-hunk t)))
1769 (char-offset (- (point) (goto-char (car hunk-bounds))))
1770 ;; Check that the hunk is well-formed. Otherwise diff-mode and 1670 ;; Check that the hunk is well-formed. Otherwise diff-mode and
1771 ;; the user may disagree on what constitutes the hunk 1671 ;; the user may disagree on what constitutes the hunk
1772 ;; (e.g. because an empty line truncates the hunk mid-course), 1672 ;; (e.g. because an empty line truncates the hunk mid-course),
@@ -1775,7 +1675,7 @@ NOPROMPT, if non-nil, means not to prompt the user."
1775 ;; Suppress check when NOPROMPT is non-nil (Bug#3033). 1675 ;; Suppress check when NOPROMPT is non-nil (Bug#3033).
1776 (_ (unless noprompt (diff-sanity-check-hunk))) 1676 (_ (unless noprompt (diff-sanity-check-hunk)))
1777 (hunk (buffer-substring 1677 (hunk (buffer-substring
1778 (point) (cadr hunk-bounds))) 1678 (point) (save-excursion (diff-end-of-hunk) (point))))
1779 (old (diff-hunk-text hunk reverse char-offset)) 1679 (old (diff-hunk-text hunk reverse char-offset))
1780 (new (diff-hunk-text hunk (not reverse) char-offset)) 1680 (new (diff-hunk-text hunk (not reverse) char-offset))
1781 ;; Find the location specification. 1681 ;; Find the location specification.
@@ -1883,15 +1783,8 @@ With a prefix argument, REVERSE the hunk."
1883 ;; Display BUF in a window 1783 ;; Display BUF in a window
1884 (set-window-point (display-buffer buf) (+ (car pos) (cdr new))) 1784 (set-window-point (display-buffer buf) (+ (car pos) (cdr new)))
1885 (diff-hunk-status-msg line-offset (diff-xor switched reverse) nil) 1785 (diff-hunk-status-msg line-offset (diff-xor switched reverse) nil)
1886
1887 ;; Advance to the next hunk with skip-hunk-start set to t
1888 ;; because we want the behavior of moving to the next logical
1889 ;; hunk, not the original behavior where were would sometimes
1890 ;; stay on the current hunk. This is the behavior we get when
1891 ;; navigating through hunks interactively, and we want it when
1892 ;; applying hunks too (see http://debbugs.gnu.org/17544).
1893 (when diff-advance-after-apply-hunk 1786 (when diff-advance-after-apply-hunk
1894 (diff-hunk-next nil t)))))) 1787 (diff-hunk-next))))))
1895 1788
1896 1789
1897(defun diff-test-hunk (&optional reverse) 1790(defun diff-test-hunk (&optional reverse)
@@ -1972,15 +1865,14 @@ For use in `add-log-current-defun-function'."
1972(defun diff-ignore-whitespace-hunk () 1865(defun diff-ignore-whitespace-hunk ()
1973 "Re-diff the current hunk, ignoring whitespace differences." 1866 "Re-diff the current hunk, ignoring whitespace differences."
1974 (interactive) 1867 (interactive)
1975 (let* ((hunk-bounds (diff-bounds-of-hunk)) 1868 (let* ((char-offset (- (point) (diff-beginning-of-hunk t)))
1976 (char-offset (- (point) (goto-char (car hunk-bounds))))
1977 (opts (pcase (char-after) (?@ "-bu") (?* "-bc") (_ "-b"))) 1869 (opts (pcase (char-after) (?@ "-bu") (?* "-bc") (_ "-b")))
1978 (line-nb (and (or (looking-at "[^0-9]+\\([0-9]+\\)") 1870 (line-nb (and (or (looking-at "[^0-9]+\\([0-9]+\\)")
1979 (error "Can't find line number")) 1871 (error "Can't find line number"))
1980 (string-to-number (match-string 1)))) 1872 (string-to-number (match-string 1))))
1981 (inhibit-read-only t) 1873 (inhibit-read-only t)
1982 (hunk (delete-and-extract-region 1874 (hunk (delete-and-extract-region
1983 (point) (cadr hunk-bounds))) 1875 (point) (save-excursion (diff-end-of-hunk) (point))))
1984 (lead (make-string (1- line-nb) ?\n)) ;Line nums start at 1. 1876 (lead (make-string (1- line-nb) ?\n)) ;Line nums start at 1.
1985 (file1 (make-temp-file "diff1")) 1877 (file1 (make-temp-file "diff1"))
1986 (file2 (make-temp-file "diff2")) 1878 (file2 (make-temp-file "diff2"))
@@ -2076,14 +1968,16 @@ Return new point, if it was moved."
2076 (interactive) 1968 (interactive)
2077 (require 'smerge-mode) 1969 (require 'smerge-mode)
2078 (save-excursion 1970 (save-excursion
2079 (let* ((hunk-bounds (diff-bounds-of-hunk)) 1971 (diff-beginning-of-hunk t)
2080 (style (progn (goto-char (car hunk-bounds)) 1972 (let* ((start (point))
2081 (diff-hunk-style))) ;Skips the hunk header as well. 1973 (style (diff-hunk-style)) ;Skips the hunk header as well.
2082 (beg (point)) 1974 (beg (point))
2083 (end (cadr hunk-bounds))
2084 (props-c '((diff-mode . fine) (face diff-refine-changed))) 1975 (props-c '((diff-mode . fine) (face diff-refine-changed)))
2085 (props-r '((diff-mode . fine) (face diff-refine-removed))) 1976 (props-r '((diff-mode . fine) (face diff-refine-removed)))
2086 (props-a '((diff-mode . fine) (face diff-refine-added)))) 1977 (props-a '((diff-mode . fine) (face diff-refine-added)))
1978 ;; Be careful to go back to `start' so diff-end-of-hunk gets
1979 ;; to read the hunk header's line info.
1980 (end (progn (goto-char start) (diff-end-of-hunk) (point))))
2087 1981
2088 (remove-overlays beg end 'diff-mode 'fine) 1982 (remove-overlays beg end 'diff-mode 'fine)
2089 1983