emacs-diffs
[Top][All Lists]
Advanced

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

master eab9bdf79f5: More robust control sequence handling in LLDB output


From: Mattias Engdegård
Subject: master eab9bdf79f5: More robust control sequence handling in LLDB output (bug#66604)
Date: Mon, 23 Oct 2023 13:13:44 -0400 (EDT)

branch: master
commit eab9bdf79f5b0e9cafe84b88f9fd44d607fff509
Author: Mattias Engdegård <mattiase@acm.org>
Commit: Mattias Engdegård <mattiase@acm.org>

    More robust control sequence handling in LLDB output (bug#66604)
    
    * lisp/progmodes/gud.el (gud-lldb-marker-filter):
    Slightly more elaborate interpretation of CHA and ED sequences
    in LLDB output, allowing edits to previously emitted characters
    on the same line.
---
 lisp/progmodes/gud.el | 43 ++++++++++++++++++++++++++++++++++++-------
 1 file changed, 36 insertions(+), 7 deletions(-)

diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el
index d3064b6116c..1d3c2a72863 100644
--- a/lisp/progmodes/gud.el
+++ b/lisp/progmodes/gud.el
@@ -3886,13 +3886,42 @@ so they have been disabled."))
                    string)
      (setq gud-last-last-frame nil)
      (setq gud-overlay-arrow-position nil)))
-  ;; While being attached to a process, LLDB emits control sequences,
-  ;; even if TERM is "dumb".  This is the case in at least LLDB
-  ;; version 14 to 17.  The control sequences are filtered out by
-  ;; Emacs after this process filter runs, but LLDB also prints an
-  ;; extra space after the prompt, which we fix here.
-  (replace-regexp-in-string (rx "(lldb)" (group (1+ blank)) "\e[8")
-                            " " string nil nil 1))
+
+  ;; LLDB sometimes emits certain ECMA-48 sequences even if TERM is "dumb":
+  ;; CHA (Character Horizontal Absolute) and ED (Erase in Display),
+  ;; seemingly to undo previous output on the same line.
+  ;; Filter out these sequences here while carrying out their edits.
+  (let ((bol (pos-bol)))
+    (when (> (point) bol)
+      ;; Move the current line to the string, so that control sequences
+      ;; can delete parts of it.
+      (setq string (concat (buffer-substring-no-properties bol (point))
+                           string))
+      (delete-region bol (point))))
+  (let ((ofs 0))
+    (while (string-match (rx (group (* (not (in "\e\n"))))  ; preceding chars
+                             "\e["                          ; CSI
+                             (? (group (+ digit)))          ; argument
+                             (group (in "GJ")))             ; CHA or ED
+                         string ofs)
+      (let* ((start (match-beginning 1))
+             (prefix-end (match-end 1))
+             (op (aref string (match-beginning 3)))
+             (end (match-end 0))
+             (keep-end
+              (if (eq op ?G)
+                  ;; Move to absolute column (CHA)
+                  (min prefix-end
+                       (+ start
+                          (if (match-beginning 2)
+                              (1- (string-to-number (match-string 2 string)))
+                            0)))
+                ;; Erase in display (ED): no further action.
+                prefix-end)))
+        (setq string (concat (substring string 0 keep-end)
+                             (substring string end)))
+        (setq ofs start))))
+  string)
 
 ;; According to SBCommanInterpreter.cpp, the return value of
 ;; HandleCompletions is as follows:



reply via email to

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