From fc39bd54ac93dbebec3b4c16aa1fe995cd421c92 Mon Sep 17 00:00:00 2001 From: Philip Kaludercic Date: Sat, 19 Aug 2023 11:47:54 +0200 Subject: [PATCH] Add command to copy contents in a diff-mode buffer * lisp/vc/diff-mode.el (diff-mode-shared-map): Bind 'diff-kill-ring-save'. (diff-mode-map): Ensure the "w" binding does not get prefixed. (diff-kill-ring-save): Add new command * etc/NEWS: Mention 'diff-kill-ring-save'. --- etc/NEWS | 7 +++++++ lisp/vc/diff-mode.el | 24 +++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/etc/NEWS b/etc/NEWS index 6588299c532..9ce510e0f81 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -276,6 +276,13 @@ This allows changing which type of whitespace changes are ignored when regenerating hunks with 'diff-ignore-whitespace-hunk'. Defaults to the previously hard-coded "-b". +--- +*** New command 'diff-kill-ring-save'. +This command behaves like 'kill-ring-save', but removes change +indicators ("+", "-") from the beginning of a line. This is useful +when you wish to copy part of the contents of a diff, but not the diff +itself. + ** Ediff --- diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index d776375d681..342d2d8ce90 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -195,6 +195,7 @@ diff-mode-shared-map "RET" #'diff-goto-source "" #'diff-goto-source "W" #'widen + "w" #'diff-kill-ring-save "o" #'diff-goto-source ; other-window "A" #'diff-ediff-patch "r" #'diff-restrict-view @@ -207,7 +208,7 @@ diff-mode-map ;; We want to inherit most bindings from ;; `diff-mode-shared-map', but not all since they may hide ;; useful `M-' global bindings when editing. - (dolist (key '("A" "r" "R" "g" "q" "W" "z")) + (dolist (key '("A" "r" "R" "g" "q" "W" "w" "z")) (keymap-set map key nil)) map) ;; From compilation-minor-mode. @@ -2079,6 +2080,27 @@ diff-goto-source (goto-char (+ (car pos) (cdr src))) (when buffer (next-error-found buffer (current-buffer)))))) +(defun diff-kill-ring-save (beg end) + "Save contents of the region between BEG and END akin to `kill-ring-save'. +The contents of a region will not include diff indicators at the +beginning of each line." + (interactive (list (region-beginning) (region-end))) + (let ((at-bol (save-excursion (goto-char beg) (bolp))) + lines) + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + (while (not (eobp)) + (let ((line (thing-at-point 'line t))) + ;; In case the user has selected a region that begins + ;; mid-line, we should not chomp off the first character. + (if (and (null lines) (not at-bol)) + (push line lines) + (push (substring line 1) lines))) + (forward-line))) + (let ((region-extract-function + (lambda (_) (apply #'concat (nreverse lines))))) + (kill-ring-save beg end t)))) (defun diff-current-defun () "Find the name of function at point. -- 2.39.2