Subject: bug#65511: [PATCH] copy-next-command-output suggestion

From: Jeremy Bryant <[email-masked]>
Date: Thu, 24 Aug 2023 22:46:28 +0100

Hello, Emacs maintainers.

The command copy-next-command-output copies the output of the next
command, and having used it for several months, I would like to suggest
this for Emacs core.  It doesn't appear to be part of Emacs.  I
typically bind this C-c u.

This code was provided by Stefan on this list or emacs-devel, so the
author should be changed accordingly (I haven't modified Stefan's code,
just used it).

Thoughts welcome as this is my first patch suggestion.  It could also be
put in a package in ELPA.  I have signed the paperwork.

Thanks in advance

Jeremy

>From 4b797454bbf09556bfb23cbd01cae3e424da29d7 Mon Sep 17 00:00:00 2001
From: Jeremy Bryant <[email-masked]>
Date: Thu, 24 Aug 2023 22:42:29 +0100
Subject: [PATCH] Add output of next command to the kill ring

---
 lisp/misc.el | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/lisp/misc.el b/lisp/misc.el
index e8b38fad42e..5bd3c720206 100644
--- a/lisp/misc.el
+++ b/lisp/misc.el
@@ -327,6 +327,53 @@ list-dynamic-libraries
   (display-buffer buffer)
   nil)
 
+(defun copy-next-command-output ()
+  "Prefix command to add the output of the next command to the `kill-ring`."
+  (interactive)
+  (let ((md (minibuffer-depth))
+        (marker (with-current-buffer "*Messages*"
+                  (point-max-marker))))
+    (cl-labels ((pre ()
+                  (unless (> (minibuffer-depth) md)
+                    (add-hook 'post-command-hook #'post)
+                    (prepare)))
+                (prepare ()
+                  (with-current-buffer "*Messages*"
+                    (move-marker marker (point-max))))
+                (preserve ()
+                  (unless (> (minibuffer-depth) md)
+                    (remove-hook 'post-command-hook #'post)
+                    (add-hook 'pre-command-hook #'pre)))
+                (echo ()
+                  (unless (> (minibuffer-depth) md)
+                    "[copy-output]"))
+                (post ()
+                  (if (> (minibuffer-depth) md)
+                      ;; Prepare, in case there's no pre-command-hook before
+                      ;; the next post-command-hook.  E.g. in the case of
+                      ;; execute-extended-command.
+                      (prepare)
+                    (remove-hook 'pre-command-hook #'pre)
+                    (remove-hook 'post-command-hook #'post)
+                    (remove-hook 'prefix-command-preserve-state-hook
+                                 #'preserve)
+                    (remove-hook 'prefix-command-echo-keystrokes-functions
+                                 #'echo)
+                    (prefix-command-update)
+                    (with-current-buffer (marker-buffer marker)
+                      (when (< marker (point-max))
+                        (kill-new (buffer-substring marker (point-max)))))
+                    (set-marker marker nil))))
+      (add-hook 'prefix-command-preserve-state-hook #'preserve)
+      (add-hook 'prefix-command-echo-keystrokes-functions #'echo)
+      ;; (message "BEFORE: prefix-arg=%S current-prefix-arg=%S"
+      ;;          prefix-arg current-prefix-arg)
+      (prefix-command-preserve-state)
+      ;; (message "AFTER: prefix-arg=%S current-prefix-arg=%S"
+      ;;          prefix-arg current-prefix-arg)
+      )))
+
+
 (provide 'misc)
 
 ;;; misc.el ends here
-- 
2.40.1