Subject: Re: bug#34901: CUA cut/copy no longer work in keyboard macros (emacs25)

From: Eli Zaretskii <[email-masked]>
Date: Mon, 18 Mar 2019 18:50:39 +0200

> From: Ben Bridgwater <[email-masked]>
> Date: Sun, 17 Mar 2019 21:04:28 -0400
> 
> I just upgraded from emacs24 (Ubuntu 16.04) to emacs25 (Ubuntu 18.04), and have found that the CUA
> cut/copy (ctrl-x, ctrl-v) bindings no longer work in keyboard macros.

I believe you meant C-x and C-c, not C-v.

> The issue seems to be the CUA bindings since the underlying cut/copy functions (kill-region, kill-ring-save)
> still work correctly in macros when bound to other keys.

Yes.  Turns out CUA is another package that relied on undocumented
kludges to avoid recording the same key twice, when keys are pushed
back onto unread-command-events.  Aargh!

Stefan, what do you think about the patch below?  Other that that, I
don't see what we could do with this stuff.

--- lisp/emulation/cua-base.el~0	2019-01-09 11:13:23.000000000 +0200
+++ lisp/emulation/cua-base.el	2019-03-18 15:14:34.349105600 +0200
@@ -710,7 +710,8 @@
     ;; C-x binding after the first C-x C-x was rewritten to just C-x).
     (prefix-command-preserve-state)
     ;; Push the key back on the event queue
-    (setq unread-command-events (cons key unread-command-events))))
+    (setq unread-command-events (cons (cons 'no-record key)
+                                      unread-command-events))))
 
 (defun cua--prefix-override-handler ()
   "Start timer waiting for prefix key to be followed by another key.

--- src/keyboard.c~0	2019-03-03 06:47:29.000000000 +0200
+++ src/keyboard.c	2019-03-18 15:21:16.543163600 +0200
@@ -2360,7 +2360,14 @@ read_char (int commandflag, Lisp_Object 
       if (CONSP (c) && EQ (XCAR (c), Qt))
 	c = XCDR (c);
       else
-	reread = true;
+	{
+	  if (CONSP (c) && EQ (XCAR (c), Qno_record))
+	    {
+	      c = XCDR (c);
+	      recorded = true;
+	    }
+	  reread = true;
+	}
 
       /* Undo what read_char_x_menu_prompt did when it unread
 	 additional keys returned by Fx_popup_menu.  */
@@ -2741,7 +2748,14 @@ read_char (int commandflag, Lisp_Object 
       if (CONSP (c) && EQ (XCAR (c), Qt))
 	c = XCDR (c);
       else
-	reread = true;
+	{
+	  if (CONSP (c) && EQ (XCAR (c), Qno_record))
+	    {
+	      c = XCDR (c);
+	      recorded = true;
+	    }
+	  reread = true;
+	}
     }
 
   /* Read something from current KBOARD's side queue, if possible.  */
@@ -2803,6 +2817,11 @@ read_char (int commandflag, Lisp_Object 
 
       if (CONSP (c) && EQ (XCAR (c), Qt))
 	c = XCDR (c);
+      else if (CONSP (c) && EQ (XCAR (c), Qno_record))
+	{
+	  c = XCDR (c);
+	  recorded = true;
+	}
   }
 
  non_reread:
@@ -11192,6 +11211,7 @@ syms_of_keyboard (void)
 	Fput (var, Qevent_symbol_elements, list1 (var));
       }
   }
+  DEFSYM (Qno_record, "no-record");
 
   button_down_location = make_nil_vector (5);
   staticpro (&button_down_location);