diff options
| author | Tino Calancha | 2017-01-21 11:54:55 +0900 |
|---|---|---|
| committer | Tino Calancha | 2017-01-21 11:54:55 +0900 |
| commit | e5e42cefd7f2eb47d2c8660a7a317e8b08d36a82 (patch) | |
| tree | dd7bfb464bba6f0a0bf3cef6e96d7813b8f776b8 | |
| parent | 1508b538fd8f8c2e00aadcea42ac36013fad02e3 (diff) | |
| download | emacs-e5e42cefd7f2eb47d2c8660a7a317e8b08d36a82.tar.gz emacs-e5e42cefd7f2eb47d2c8660a7a317e8b08d36a82.zip | |
diff-hunk-kill independent of point inside headers
Make diff-apply-hunk and diff-hunk-kill independent of the point
position in a diff header (Bug#17544).
This change allows to apply hunks in order. It also makes possible to
press M-k repeatedly to kill hunks in the order they appear in the buffer.
See discussion on #Bug25105.
* lisp/vc/diff-mode.el (diff-file-junk-re):
Move definition before it's used.
(diff--at-diff-header-p): New predicate; return non-nil when point
is inside a hunk header, a file header, or within a line
matching diff-file-junk-re.
(diff-beginning-of-hunk): Use it.
Check if the point is inside a diff header, in the middle of a hunk,
or before the first hunk.
(diff-apply-hunk): Call diff-beginning-of-hunk with non-nil arg
before apply the hunk.
(diff-hunk-kill, diff-file-kill):
Call diff-beginning-of-hunk with non-nil arg after kill the hunks.
(diff-post-command-hook): Call diff-beginning-of-hunk with non-nil argument.
| -rw-r--r-- | lisp/vc/diff-mode.el | 67 |
1 files changed, 49 insertions, 18 deletions
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index 4e878c404cd..b7ad8e8ebd8 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el | |||
| @@ -498,22 +498,55 @@ See http://lists.gnu.org/archive/html/emacs-devel/2007-11/msg01990.html") | |||
| 498 | ;; The return value is used by easy-mmode-define-navigation. | 498 | ;; The return value is used by easy-mmode-define-navigation. |
| 499 | (goto-char (or end (point-max))))) | 499 | (goto-char (or end (point-max))))) |
| 500 | 500 | ||
| 501 | ;; "index ", "old mode", "new mode", "new file mode" and | ||
| 502 | ;; "deleted file mode" are output by git-diff. | ||
| 503 | (defconst diff-file-junk-re | ||
| 504 | "diff \\|index \\|\\(?:deleted file\\|new\\(?: file\\)?\\|old\\) mode\\|=== modified file") | ||
| 505 | |||
| 506 | ;; If point is in a diff header, then return beginning | ||
| 507 | ;; of hunk position otherwise return nil. | ||
| 508 | (defun diff--at-diff-header-p () | ||
| 509 | "Return non-nil if point is inside a diff header." | ||
| 510 | (let ((regexp-hunk diff-hunk-header-re) | ||
| 511 | (regexp-file diff-file-header-re) | ||
| 512 | (regexp-junk diff-file-junk-re) | ||
| 513 | (orig (point))) | ||
| 514 | (catch 'headerp | ||
| 515 | (save-excursion | ||
| 516 | (forward-line 0) | ||
| 517 | (when (looking-at regexp-hunk) ; Hunk header. | ||
| 518 | (throw 'headerp (point))) | ||
| 519 | (forward-line -1) | ||
| 520 | (when (re-search-forward regexp-file (point-at-eol 4) t) ; File header. | ||
| 521 | (forward-line 0) | ||
| 522 | (throw 'headerp (point))) | ||
| 523 | (goto-char orig) | ||
| 524 | (forward-line 0) | ||
| 525 | (when (looking-at regexp-junk) ; Git diff junk. | ||
| 526 | (while (and (looking-at regexp-junk) | ||
| 527 | (not (bobp))) | ||
| 528 | (forward-line -1)) | ||
| 529 | (re-search-forward regexp-file nil t) | ||
| 530 | (forward-line 0) | ||
| 531 | (throw 'headerp (point)))) nil))) | ||
| 532 | |||
| 501 | (defun diff-beginning-of-hunk (&optional try-harder) | 533 | (defun diff-beginning-of-hunk (&optional try-harder) |
| 502 | "Move back to the previous hunk beginning, and return its position. | 534 | "Move back to the previous hunk beginning, and return its position. |
| 503 | If point is in a file header rather than a hunk, advance to the | 535 | If point is in a file header rather than a hunk, advance to the |
| 504 | next hunk if TRY-HARDER is non-nil; otherwise signal an error." | 536 | next hunk if TRY-HARDER is non-nil; otherwise signal an error." |
| 505 | (beginning-of-line) | 537 | (beginning-of-line) |
| 506 | (if (looking-at diff-hunk-header-re) | 538 | (if (looking-at diff-hunk-header-re) ; At hunk header. |
| 507 | (point) | 539 | (point) |
| 508 | (forward-line 1) | 540 | (let ((pos (diff--at-diff-header-p)) |
| 509 | (condition-case () | 541 | (regexp diff-hunk-header-re)) |
| 510 | (re-search-backward diff-hunk-header-re) | 542 | (cond (pos ; At junk diff header. |
| 511 | (error | 543 | (if try-harder |
| 512 | (unless try-harder | 544 | (goto-char pos) |
| 513 | (error "Can't find the beginning of the hunk")) | 545 | (error "Can't find the beginning of the hunk"))) |
| 514 | (diff-beginning-of-file-and-junk) | 546 | ((re-search-backward regexp nil t)) ; In the middle of a hunk. |
| 515 | (diff-hunk-next) | 547 | ((re-search-forward regexp nil t) ; At first hunk header. |
| 516 | (point))))) | 548 | (forward-line 0)) |
| 549 | (t (error "Can't find the beginning of the hunk")))))) | ||
| 517 | 550 | ||
| 518 | (defun diff-unified-hunk-p () | 551 | (defun diff-unified-hunk-p () |
| 519 | (save-excursion | 552 | (save-excursion |
| @@ -632,12 +665,8 @@ If the prefix ARG is given, restrict the view to the current file instead." | |||
| 632 | hunk-bounds)) | 665 | hunk-bounds)) |
| 633 | (inhibit-read-only t)) | 666 | (inhibit-read-only t)) |
| 634 | (apply 'kill-region bounds) | 667 | (apply 'kill-region bounds) |
| 635 | (goto-char (car bounds)))) | 668 | (goto-char (car bounds)) |
| 636 | 669 | (diff-beginning-of-hunk t))) | |
| 637 | ;; "index ", "old mode", "new mode", "new file mode" and | ||
| 638 | ;; "deleted file mode" are output by git-diff. | ||
| 639 | (defconst diff-file-junk-re | ||
| 640 | "diff \\|index \\|\\(?:deleted file\\|new\\(?: file\\)?\\|old\\) mode\\|=== modified file") | ||
| 641 | 670 | ||
| 642 | (defun diff-beginning-of-file-and-junk () | 671 | (defun diff-beginning-of-file-and-junk () |
| 643 | "Go to the beginning of file-related diff-info. | 672 | "Go to the beginning of file-related diff-info. |
| @@ -690,7 +719,8 @@ data such as \"Index: ...\" and such." | |||
| 690 | "Kill current file's hunks." | 719 | "Kill current file's hunks." |
| 691 | (interactive) | 720 | (interactive) |
| 692 | (let ((inhibit-read-only t)) | 721 | (let ((inhibit-read-only t)) |
| 693 | (apply 'kill-region (diff-bounds-of-file)))) | 722 | (apply 'kill-region (diff-bounds-of-file))) |
| 723 | (diff-beginning-of-hunk t)) | ||
| 694 | 724 | ||
| 695 | (defun diff-kill-junk () | 725 | (defun diff-kill-junk () |
| 696 | "Kill spurious empty diffs." | 726 | "Kill spurious empty diffs." |
| @@ -1274,7 +1304,7 @@ See `after-change-functions' for the meaning of BEG, END and LEN." | |||
| 1274 | ;; it's safer not to do it on big changes, e.g. when yanking a big | 1304 | ;; it's safer not to do it on big changes, e.g. when yanking a big |
| 1275 | ;; diff, or when the user edits the header, since we might then | 1305 | ;; diff, or when the user edits the header, since we might then |
| 1276 | ;; screw up perfectly correct values. --Stef | 1306 | ;; screw up perfectly correct values. --Stef |
| 1277 | (diff-beginning-of-hunk) | 1307 | (diff-beginning-of-hunk t) |
| 1278 | (let* ((style (if (looking-at "\\*\\*\\*") 'context)) | 1308 | (let* ((style (if (looking-at "\\*\\*\\*") 'context)) |
| 1279 | (start (line-beginning-position (if (eq style 'context) 3 2))) | 1309 | (start (line-beginning-position (if (eq style 'context) 3 2))) |
| 1280 | (mid (if (eq style 'context) | 1310 | (mid (if (eq style 'context) |
| @@ -1738,6 +1768,7 @@ the value of this variable when given an appropriate prefix argument). | |||
| 1738 | 1768 | ||
| 1739 | With a prefix argument, REVERSE the hunk." | 1769 | With a prefix argument, REVERSE the hunk." |
| 1740 | (interactive "P") | 1770 | (interactive "P") |
| 1771 | (diff-beginning-of-hunk t) | ||
| 1741 | (pcase-let ((`(,buf ,line-offset ,pos ,old ,new ,switched) | 1772 | (pcase-let ((`(,buf ,line-offset ,pos ,old ,new ,switched) |
| 1742 | ;; Sometimes we'd like to have the following behavior: if | 1773 | ;; Sometimes we'd like to have the following behavior: if |
| 1743 | ;; REVERSE go to the new file, otherwise go to the old. | 1774 | ;; REVERSE go to the new file, otherwise go to the old. |