aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTino Calancha2017-02-02 22:27:33 +0900
committerTino Calancha2017-02-02 22:27:33 +0900
commita362b56b51f49963dbb63cd318967bca9b9fef74 (patch)
tree3583aa5b18eeed72ad80bbe85726ad8174945c2e
parent01d87bf846b478dea0bfe824678e76089f5af2c7 (diff)
downloademacs-a362b56b51f49963dbb63cd318967bca9b9fef74.tar.gz
emacs-a362b56b51f49963dbb63cd318967bca9b9fef74.zip
Check if there are hunks before kill or refine a hunk
* lisp/vc/diff-mode.el (diff--some-hunks-p): New predicate. (diff-hunk-kill, diff-file-kill, diff-refine-hunk): Use it (Bug#25571).
-rw-r--r--lisp/vc/diff-mode.el159
1 files changed, 85 insertions, 74 deletions
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index a7ac53953dd..31c33e6a720 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -650,28 +650,36 @@ If the prefix ARG is given, restrict the view to the current file instead."
650 (if arg (diff-bounds-of-file) (diff-bounds-of-hunk))) 650 (if arg (diff-bounds-of-file) (diff-bounds-of-hunk)))
651 (set (make-local-variable 'diff-narrowed-to) (if arg 'file 'hunk))) 651 (set (make-local-variable 'diff-narrowed-to) (if arg 'file 'hunk)))
652 652
653(defun diff--some-hunks-p ()
654 (save-excursion
655 (goto-char (point-min))
656 (re-search-forward diff-hunk-header-re nil t)))
657
653(defun diff-hunk-kill () 658(defun diff-hunk-kill ()
654 "Kill the hunk at point." 659 "Kill the hunk at point."
655 (interactive) 660 (interactive)
656 (let* ((hunk-bounds (diff-bounds-of-hunk)) 661 (if (not (diff--some-hunks-p))
657 (file-bounds (ignore-errors (diff-bounds-of-file))) 662 (error "No hunks")
658 ;; If the current hunk is the only one for its file, kill the 663 (diff-beginning-of-hunk t)
659 ;; file header too. 664 (let* ((hunk-bounds (diff-bounds-of-hunk))
660 (bounds (if (and file-bounds 665 (file-bounds (ignore-errors (diff-bounds-of-file)))
661 (progn (goto-char (car file-bounds)) 666 ;; If the current hunk is the only one for its file, kill the
662 (= (progn (diff-hunk-next) (point)) 667 ;; file header too.
663 (car hunk-bounds))) 668 (bounds (if (and file-bounds
664 (progn (goto-char (cadr hunk-bounds)) 669 (progn (goto-char (car file-bounds))
665 ;; bzr puts a newline after the last hunk. 670 (= (progn (diff-hunk-next) (point))
666 (while (looking-at "^\n") 671 (car hunk-bounds)))
667 (forward-char 1)) 672 (progn (goto-char (cadr hunk-bounds))
668 (= (point) (cadr file-bounds)))) 673 ;; bzr puts a newline after the last hunk.
669 file-bounds 674 (while (looking-at "^\n")
670 hunk-bounds)) 675 (forward-char 1))
671 (inhibit-read-only t)) 676 (= (point) (cadr file-bounds))))
672 (apply 'kill-region bounds) 677 file-bounds
673 (goto-char (car bounds)) 678 hunk-bounds))
674 (ignore-errors (diff-beginning-of-hunk t)))) 679 (inhibit-read-only t))
680 (apply 'kill-region bounds)
681 (goto-char (car bounds))
682 (ignore-errors (diff-beginning-of-hunk t)))))
675 683
676(defun diff-beginning-of-file-and-junk () 684(defun diff-beginning-of-file-and-junk ()
677 "Go to the beginning of file-related diff-info. 685 "Go to the beginning of file-related diff-info.
@@ -723,10 +731,12 @@ data such as \"Index: ...\" and such."
723(defun diff-file-kill () 731(defun diff-file-kill ()
724 "Kill current file's hunks." 732 "Kill current file's hunks."
725 (interactive) 733 (interactive)
726 (diff-beginning-of-hunk t) 734 (if (not (diff--some-hunks-p))
727 (let ((inhibit-read-only t)) 735 (error "No hunks")
728 (apply 'kill-region (diff-bounds-of-file))) 736 (diff-beginning-of-hunk t)
729 (ignore-errors (diff-beginning-of-hunk t))) 737 (let ((inhibit-read-only t))
738 (apply 'kill-region (diff-bounds-of-file)))
739 (ignore-errors (diff-beginning-of-hunk t))))
730 740
731(defun diff-kill-junk () 741(defun diff-kill-junk ()
732 "Kill spurious empty diffs." 742 "Kill spurious empty diffs."
@@ -2009,57 +2019,58 @@ Return new point, if it was moved."
2009 "Highlight changes of hunk at point at a finer granularity." 2019 "Highlight changes of hunk at point at a finer granularity."
2010 (interactive) 2020 (interactive)
2011 (require 'smerge-mode) 2021 (require 'smerge-mode)
2012 (save-excursion 2022 (when (diff--some-hunks-p)
2013 (diff-beginning-of-hunk t) 2023 (save-excursion
2014 (let* ((start (point)) 2024 (diff-beginning-of-hunk t)
2015 (style (diff-hunk-style)) ;Skips the hunk header as well. 2025 (let* ((start (point))
2016 (beg (point)) 2026 (style (diff-hunk-style)) ;Skips the hunk header as well.
2017 (props-c '((diff-mode . fine) (face diff-refine-changed))) 2027 (beg (point))
2018 (props-r '((diff-mode . fine) (face diff-refine-removed))) 2028 (props-c '((diff-mode . fine) (face diff-refine-changed)))
2019 (props-a '((diff-mode . fine) (face diff-refine-added))) 2029 (props-r '((diff-mode . fine) (face diff-refine-removed)))
2020 ;; Be careful to go back to `start' so diff-end-of-hunk gets 2030 (props-a '((diff-mode . fine) (face diff-refine-added)))
2021 ;; to read the hunk header's line info. 2031 ;; Be careful to go back to `start' so diff-end-of-hunk gets
2022 (end (progn (goto-char start) (diff-end-of-hunk) (point)))) 2032 ;; to read the hunk header's line info.
2023 2033 (end (progn (goto-char start) (diff-end-of-hunk) (point))))
2024 (remove-overlays beg end 'diff-mode 'fine) 2034
2025 2035 (remove-overlays beg end 'diff-mode 'fine)
2026 (goto-char beg) 2036
2027 (pcase style 2037 (goto-char beg)
2028 (`unified 2038 (pcase style
2029 (while (re-search-forward "^-" end t) 2039 (`unified
2030 (let ((beg-del (progn (beginning-of-line) (point))) 2040 (while (re-search-forward "^-" end t)
2031 beg-add end-add) 2041 (let ((beg-del (progn (beginning-of-line) (point)))
2032 (when (and (diff--forward-while-leading-char ?- end) 2042 beg-add end-add)
2033 ;; Allow for "\ No newline at end of file". 2043 (when (and (diff--forward-while-leading-char ?- end)
2034 (progn (diff--forward-while-leading-char ?\\ end) 2044 ;; Allow for "\ No newline at end of file".
2035 (setq beg-add (point))) 2045 (progn (diff--forward-while-leading-char ?\\ end)
2036 (diff--forward-while-leading-char ?+ end) 2046 (setq beg-add (point)))
2037 (progn (diff--forward-while-leading-char ?\\ end) 2047 (diff--forward-while-leading-char ?+ end)
2038 (setq end-add (point)))) 2048 (progn (diff--forward-while-leading-char ?\\ end)
2039 (smerge-refine-subst beg-del beg-add beg-add end-add 2049 (setq end-add (point))))
2040 nil 'diff-refine-preproc props-r props-a))))) 2050 (smerge-refine-subst beg-del beg-add beg-add end-add
2041 (`context 2051 nil 'diff-refine-preproc props-r props-a)))))
2042 (let* ((middle (save-excursion (re-search-forward "^---"))) 2052 (`context
2043 (other middle)) 2053 (let* ((middle (save-excursion (re-search-forward "^---")))
2044 (while (re-search-forward "^\\(?:!.*\n\\)+" middle t) 2054 (other middle))
2045 (smerge-refine-subst (match-beginning 0) (match-end 0) 2055 (while (re-search-forward "^\\(?:!.*\n\\)+" middle t)
2046 (save-excursion 2056 (smerge-refine-subst (match-beginning 0) (match-end 0)
2047 (goto-char other) 2057 (save-excursion
2048 (re-search-forward "^\\(?:!.*\n\\)+" end) 2058 (goto-char other)
2049 (setq other (match-end 0)) 2059 (re-search-forward "^\\(?:!.*\n\\)+" end)
2050 (match-beginning 0)) 2060 (setq other (match-end 0))
2051 other 2061 (match-beginning 0))
2052 (if diff-use-changed-face props-c) 2062 other
2053 'diff-refine-preproc 2063 (if diff-use-changed-face props-c)
2054 (unless diff-use-changed-face props-r) 2064 'diff-refine-preproc
2055 (unless diff-use-changed-face props-a))))) 2065 (unless diff-use-changed-face props-r)
2056 (_ ;; Normal diffs. 2066 (unless diff-use-changed-face props-a)))))
2057 (let ((beg1 (1+ (point)))) 2067 (_ ;; Normal diffs.
2058 (when (re-search-forward "^---.*\n" end t) 2068 (let ((beg1 (1+ (point))))
2059 ;; It's a combined add&remove, so there's something to do. 2069 (when (re-search-forward "^---.*\n" end t)
2060 (smerge-refine-subst beg1 (match-beginning 0) 2070 ;; It's a combined add&remove, so there's something to do.
2061 (match-end 0) end 2071 (smerge-refine-subst beg1 (match-beginning 0)
2062 nil 'diff-refine-preproc props-r props-a)))))))) 2072 (match-end 0) end
2073 nil 'diff-refine-preproc props-r props-a)))))))))
2063 2074
2064(defun diff-undo (&optional arg) 2075(defun diff-undo (&optional arg)
2065 "Perform `undo', ignoring the buffer's read-only status." 2076 "Perform `undo', ignoring the buffer's read-only status."