Subject: bug#49253: 27.2; Emacs non-responsive when pasting into terminal-mode

From: Jared Finder <[email-masked]>
Date: Mon, 11 Dec 2023 14:13:24 -0800

On 2023-12-11 08:10, Matt Bisson wrote:
> TL;DR: It works!

Thank you for the testing!

Eli, I think the fully correct definition for term--xterm-paste is the 
following, which has additional error checking:

(defun term--xterm-paste (event)
   "Insert the text pasted in an XTerm bracketed paste operation."
   (interactive "e")
   (unless (eq (car-safe event) 'xterm-paste)
     (error "term--xterm-paste must be found to xterm-paste event"))
   (let ((str (nth 1 event)))
     (unless (stringp str)
       (error "term--xterm-paste provided event does not contain paste 
text"))
     (term-send-raw-string str)))

>> I don't think this is the right approach.
> 
> Totally! :)  The patch was definitely not a serious suggestion of what
> should be submitted, but just a demonstration that the interplay
> between the two functions is causing the issue, and it can be solved
> by touching only that.  I haven't built up the knowledge of how these
> events function like you have, and was hoping you'd teach me a bit in
> response, and you did!

No worries!  I hope I didn't come across as judgemental here. :)  If you 
want a bit more detail around the architecture here, read on (Eli, 
please correct if I get anything wrong):

In Emacs, in addition to the local and global keymaps, there are also 
translation keymaps. 
(https://www.gnu.org/software/emacs/manual/html_node/elisp/Translation-Keymaps.html) 
  The docs are accurate but a bit hard to understand without concrete 
examples.  So let me provide an example for each of the translation 
keymaps.  There are three of them:

1. input-decode-map.  This exists to translate terminal escape sequences 
into the their proper events.  That can be for keys (like the PF1 key 
mentioned in the docs) but it also an be for mouse clicks or the xterm 
paste operation.

EXAMPLE:
This bug!  In this bug, input-decode-map is what translates the 
character sequence "ESC [ 2 0 0 ~ PASTED TEXT HERE ESC [ 2 0 1 ~"  into 
a single <xterm-paste> event, (xterm-paste "PASTED TEXT HERE").  It does 
this by mapping "ESC [ 2 0 0 ~" to a function that reads until 
encountering the "ESC [ 2 0 1 ~" sequence and returns that new event.

2. (local-)function-key-map.  This exists to rename keys to more 
preferred names that allow keybindings to be shared.  The docs say "the 
remapping only applies if the original key sequence would otherwise not 
have any binding", this is to allow you to use the native keynames on 
your keyboard if you do want to distinguish.

EXAMPLE:
Many keyboards have a separate keypad number area.  These keys get their 
own events, e.g. "<kp-0>" for the zero character on the keypad.  Emacs 
uses function-key-map to translate "<kp-0>" into "0", so pressing the 
keypad 0 acts the same as the number row 0.  If you wanted to map the 
keypad numbers to a different set of commands, you can still do so with 
the original "<kp-0>" key.  If you do so, that also implicitly overrides 
this translation.

3. key-translation-map.  I've never actually used this directly so I'm 
not entirely clear on its intent.  The docs make it sound like it is 
intended for changing keyboard layouts.  Which explains why I have never 
used it -- I generally use OSes that allow keyboard layout translating 
natively.

EXAMPLE:
Based on my guess above, key-translation-map would let me map between 
QWERTY and Dvorak inside Emacs.  This would be nice if I was running 
directly in a Linux terminal and did not have permission to run "sudo 
loadkeys".

As a final note, notice that all three of these examples involve 
changing a key into a different key.  None of them are for binding 
commands.  Commands being bound to a key always is the job of the local 
and global keymaps.

I hope these examples help you understand the setup here!

   -- MJF