diff options
| author | Tino Calancha | 2017-02-02 22:27:33 +0900 |
|---|---|---|
| committer | Tino Calancha | 2017-02-02 22:27:33 +0900 |
| commit | a362b56b51f49963dbb63cd318967bca9b9fef74 (patch) | |
| tree | 3583aa5b18eeed72ad80bbe85726ad8174945c2e | |
| parent | 01d87bf846b478dea0bfe824678e76089f5af2c7 (diff) | |
| download | emacs-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.el | 159 |
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." |