diff options
| author | Sean Whitton | 2024-09-30 21:08:38 +0800 |
|---|---|---|
| committer | Sean Whitton | 2024-10-01 08:56:59 +0800 |
| commit | b64f69f6dcc08e5aeea0464f6d8b560ed7002d36 (patch) | |
| tree | a76e63f2abbc3790af79d090ebf3b3c703165b03 | |
| parent | f95d4208b6bcfbbf95c956d8a66faa92aa5e4965 (diff) | |
| download | emacs-b64f69f6dcc08e5aeea0464f6d8b560ed7002d36.tar.gz emacs-b64f69f6dcc08e5aeea0464f6d8b560ed7002d36.zip | |
New command diff-delete-other-hunks
* lisp/vc/diff-mode.el (diff-delete-other-hunks): New
command (bug#73387).
(diff-mode-map): Bind the new command to C-c RET n.
(diff-mode-menu): New entry for the new command.
(vc-next-action): Stop, and warn, if the user attempts to commit
a patch from a narrowed buffer (bug#73387).
* doc/emacs/files.texi (Diff Mode):
* etc/NEWS: Document the new command.
| -rw-r--r-- | doc/emacs/files.texi | 5 | ||||
| -rw-r--r-- | etc/NEWS | 7 | ||||
| -rw-r--r-- | lisp/vc/diff-mode.el | 34 | ||||
| -rw-r--r-- | lisp/vc/vc.el | 11 |
4 files changed, 57 insertions, 0 deletions
diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index a3a8c854aa6..67a1a3be3ff 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi | |||
| @@ -1703,6 +1703,11 @@ confirm you really want to revert and kill the hunk. You can customize | |||
| 1703 | Apply all the hunks in the buffer (@code{diff-apply-buffer}). If the | 1703 | Apply all the hunks in the buffer (@code{diff-apply-buffer}). If the |
| 1704 | diffs were applied successfully, save the changed buffers. | 1704 | diffs were applied successfully, save the changed buffers. |
| 1705 | 1705 | ||
| 1706 | @findex diff-delete-other-hunks | ||
| 1707 | @item C-c @key{RET} n | ||
| 1708 | Delete all hunks other than the current hunk. If the region is active, | ||
| 1709 | then delete all hunks that the region does not overlap. | ||
| 1710 | |||
| 1706 | @findex diff-refine-hunk | 1711 | @findex diff-refine-hunk |
| 1707 | @item C-c C-b | 1712 | @item C-c C-b |
| 1708 | Highlight the changes of the hunk at point with a finer granularity | 1713 | Highlight the changes of the hunk at point with a finer granularity |
| @@ -382,6 +382,13 @@ Previously, 'diff-file-prev' and 'diff-hunk-prev' would move when point | |||
| 382 | is after the corresponding file or hunk header, but not when inside it. | 382 | is after the corresponding file or hunk header, but not when inside it. |
| 383 | Now they will always move to the start of the current header. | 383 | Now they will always move to the start of the current header. |
| 384 | 384 | ||
| 385 | +++ | ||
| 386 | *** New command 'diff-delete-other-hunks' bound to C-c RET n. | ||
| 387 | This command deletes all hunks other than the current hunk. It is | ||
| 388 | useful to prepare a *vc-diff* buffer for committing a single hunk. | ||
| 389 | When the region is active, it deletes all hunks that the region does not | ||
| 390 | overlap. | ||
| 391 | |||
| 385 | ** php-ts-mode | 392 | ** php-ts-mode |
| 386 | 393 | ||
| 387 | --- | 394 | --- |
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index 25c6238765d..948d89c579e 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el | |||
| @@ -220,6 +220,7 @@ The default \"-b\" means to ignore whitespace-only changes, | |||
| 220 | "C-c C-a" #'diff-apply-hunk | 220 | "C-c C-a" #'diff-apply-hunk |
| 221 | "C-c M-r" #'diff-revert-and-kill-hunk | 221 | "C-c M-r" #'diff-revert-and-kill-hunk |
| 222 | "C-c C-m a" #'diff-apply-buffer | 222 | "C-c C-m a" #'diff-apply-buffer |
| 223 | "C-c C-m n" #'diff-delete-other-hunks | ||
| 223 | "C-c C-e" #'diff-ediff-patch | 224 | "C-c C-e" #'diff-ediff-patch |
| 224 | "C-c C-n" #'diff-restrict-view | 225 | "C-c C-n" #'diff-restrict-view |
| 225 | "C-c C-s" #'diff-split-hunk | 226 | "C-c C-s" #'diff-split-hunk |
| @@ -278,6 +279,8 @@ The default \"-b\" means to ignore whitespace-only changes, | |||
| 278 | :help "Kill current hunk"] | 279 | :help "Kill current hunk"] |
| 279 | ["Kill current file's hunks" diff-file-kill | 280 | ["Kill current file's hunks" diff-file-kill |
| 280 | :help "Kill all current file's hunks"] | 281 | :help "Kill all current file's hunks"] |
| 282 | ["Delete other hunks" diff-delete-other-hunks | ||
| 283 | :help "Delete hunks other than the current hunk"] | ||
| 281 | "-----" | 284 | "-----" |
| 282 | ["Previous Hunk" diff-hunk-prev | 285 | ["Previous Hunk" diff-hunk-prev |
| 283 | :help "Go to the previous count'th hunk"] | 286 | :help "Go to the previous count'th hunk"] |
| @@ -814,6 +817,37 @@ If the prefix ARG is given, restrict the view to the current file instead." | |||
| 814 | (goto-char (car bounds)) | 817 | (goto-char (car bounds)) |
| 815 | (ignore-errors (diff-beginning-of-hunk t))))) | 818 | (ignore-errors (diff-beginning-of-hunk t))))) |
| 816 | 819 | ||
| 820 | ;; This is not `diff-kill-other-hunks' because we might need to make | ||
| 821 | ;; copies of file headers in order to ensure the new kill ring entry | ||
| 822 | ;; would be a patch with the same meaning. That is not implemented | ||
| 823 | ;; because it does not seem like it would be useful. | ||
| 824 | (defun diff-delete-other-hunks (&optional beg end) | ||
| 825 | "Delete all hunks other than the current hunk. | ||
| 826 | Interactively, if the region is active, then delete all hunks that the | ||
| 827 | region does not overlap. When called from Lisp, the optional arguments | ||
| 828 | BEG and END specify the region of hunks not to delete." | ||
| 829 | (interactive (list (use-region-beginning) (use-region-end))) | ||
| 830 | (when (buffer-narrowed-p) | ||
| 831 | (user-error "Command is not safe in a narrowed buffer")) | ||
| 832 | (let ((inhibit-read-only t)) | ||
| 833 | (save-excursion | ||
| 834 | (cond ((xor beg end) | ||
| 835 | (error "Require exactly zero or two arguments")) | ||
| 836 | (beg | ||
| 837 | (goto-char beg) | ||
| 838 | (setq beg (car (diff-bounds-of-hunk))) | ||
| 839 | (goto-char end) | ||
| 840 | (setq end (cadr (diff-bounds-of-hunk)))) | ||
| 841 | (t | ||
| 842 | (pcase-setq `(,beg ,end) (diff-bounds-of-hunk)))) | ||
| 843 | (delete-region end (point-max)) | ||
| 844 | (goto-char beg) | ||
| 845 | (diff-beginning-of-file) | ||
| 846 | (diff-hunk-next) | ||
| 847 | (delete-region (point) beg) | ||
| 848 | (diff-beginning-of-file-and-junk) | ||
| 849 | (delete-region (point-min) (point))))) | ||
| 850 | |||
| 817 | (defun diff-beginning-of-file-and-junk () | 851 | (defun diff-beginning-of-file-and-junk () |
| 818 | "Go to the beginning of file-related diff-info. | 852 | "Go to the beginning of file-related diff-info. |
| 819 | This is like `diff-beginning-of-file' except it tries to skip back over leading | 853 | This is like `diff-beginning-of-file' except it tries to skip back over leading |
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 597a1622f5a..fce98d091bf 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el | |||
| @@ -1302,6 +1302,17 @@ from which to check out the file(s)." | |||
| 1302 | ;; Fileset comes from a diff-mode buffer, see | 1302 | ;; Fileset comes from a diff-mode buffer, see |
| 1303 | ;; 'diff-vc-deduce-fileset', and the buffer is the patch to apply. | 1303 | ;; 'diff-vc-deduce-fileset', and the buffer is the patch to apply. |
| 1304 | ((eq model 'patch) | 1304 | ((eq model 'patch) |
| 1305 | (when (buffer-narrowed-p) | ||
| 1306 | ;; If user used `diff-restrict-view' then we may not have the | ||
| 1307 | ;; file header, and the commit will not succeed (bug#73387). | ||
| 1308 | (user-error "Cannot commit patch when narrowed; consider %s" | ||
| 1309 | (mapconcat (lambda (c) | ||
| 1310 | (key-description | ||
| 1311 | (where-is-internal c nil t))) | ||
| 1312 | '(widen | ||
| 1313 | diff-delete-other-hunks | ||
| 1314 | vc-next-action) | ||
| 1315 | " "))) | ||
| 1305 | (vc-checkin files backend nil nil nil (buffer-string))) | 1316 | (vc-checkin files backend nil nil nil (buffer-string))) |
| 1306 | ((or (null state) (eq state 'unregistered)) | 1317 | ((or (null state) (eq state 'unregistered)) |
| 1307 | (cond (verbose | 1318 | (cond (verbose |