emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master a66a3b7: Improve robustness xterm event processing


From: Daniel Colascione
Subject: [Emacs-diffs] master a66a3b7: Improve robustness xterm event processing
Date: Sat, 9 Jun 2018 16:19:28 -0400 (EDT)

branch: master
commit a66a3b7f51792aa2a91c16ed9121d7e9efea4536
Author: Daniel Colascione <address@hidden>
Commit: Daniel Colascione <address@hidden>

    Improve robustness xterm event processing
    
    We used to treat the start of a focus-in, focus-out, and the start of
    a paste sequence as normal events bound in global-map, but this
    approach produces problems when we recognize events in the middle of
    actions that don't immediately dispatch to the command loop.
    
    Now we handle these events internally inside read-key, translating the
    focus events to nothing and paste-start into an xterm-paste event that
    neatly encapsulates the entire paste sequence.
    
    * lisp/term/xterm.el:
    (xterm-paste): Accept an event argument; insert text from event.
    (xterm-translate-focus-in,xterm-translate-focus-out)
    (xterm-translate-bracketed-paste): New functions.
    (xterm-handle-focus-in,xterm-handle-focus-out): Remove.
    (xterm-rxvt-function-map): Bind new translation functions.
---
 lisp/term/xterm.el | 52 ++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 36 insertions(+), 16 deletions(-)

diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el
index 06a9d44..a4321914 100644
--- a/lisp/term/xterm.el
+++ b/lisp/term/xterm.el
@@ -95,24 +95,41 @@ Return the pasted text as a string."
        (decode-coding-region (point-min) (point) (keyboard-coding-system)
                               t)))))
 
-(defun xterm-paste ()
+(defun xterm-paste (event)
   "Handle the start of a terminal paste operation."
-  (interactive)
-  (let* ((pasted-text (xterm--pasted-text))
+  (interactive "e")
+  (unless (eq (car-safe event) 'xterm-paste)
+    (error "xterm-paste must be found to xterm-paste event"))
+  (let* ((pasted-text (nth 1 event))
          (interprogram-paste-function (lambda () pasted-text)))
     (yank)))
 
+;; Put xterm-paste itself in global-map because, after translation,
+;; it's just a normal input event.
 (define-key global-map [xterm-paste] #'xterm-paste)
 
-(defun xterm-handle-focus-in ()
-  (interactive)
-  (handle-focus-in))
-(define-key global-map [xterm-focus-in] #'xterm-handle-focus-in)
+;; By returning an empty key sequence, these two functions perform the
+;; moral equivalent of the kind of transparent event processing done
+;; by read-event's handling of special-event-map, but inside
+;; read-key-sequence (which can recognize multi-character terminal
+;; notifications) instead of read-event (which can't).
 
-(defun xterm-handle-focus-out ()
-  (interactive)
-  (handle-focus-out))
-(define-key global-map [xterm-focus-out] #'xterm-handle-focus-out)
+(defun xterm-translate-focus-in (_prompt)
+  (handle-focus-in)
+  [])
+
+(defun xterm-translate-focus-out (_prompt)
+  (handle-focus-out)
+  [])
+
+;; Similarly, we want to transparently slurp the entirety of a
+;; bracketed paste and encapsulate it into a single event.  We used to
+;; just slurp up the bracketed paste content in the event handler, but
+;; this strategy can produce unexpected results in a caller manually
+;; looping on read-key and buffering input for later processing.
+
+(defun xterm-translate-bracketed-paste (_prompt)
+  (vector (list 'xterm-paste (xterm--pasted-text))))
 
 (defvar xterm-rxvt-function-map
   (let ((map (make-sparse-keymap)))
@@ -142,12 +159,15 @@ Return the pasted text as a string."
     (define-key map "\e[13~" [f3])
     (define-key map "\e[14~" [f4])
 
-    ;; Recognize the start of a bracketed paste sequence.  The handler
-    ;; internally recognizes the end.
-    (define-key map "\e[200~" [xterm-paste])
+    ;; Recognize the start of a bracketed paste sequence.
+    ;; The translation function internally recognizes the end.
+    (define-key map "\e[200~" #'xterm-translate-bracketed-paste)
 
-    (define-key map "\e[I" [xterm-focus-in])
-    (define-key map "\e[O" [xterm-focus-out])
+    ;; These translation functions actually call the focus handlers
+    ;; internally and return an empty sequence, causing us to go on to
+    ;; read the next event.
+    (define-key map "\e[I" #'xterm-translate-focus-in)
+    (define-key map "\e[O" #'xterm-translate-focus-out)
 
     map)
   "Keymap of escape sequences, shared between xterm and rxvt support.")



reply via email to

[Prev in Thread] Current Thread [Next in Thread]