From unknown Wed Aug 20 03:37:10 2025 X-Loop: help-debbugs@gnu.org Subject: bug#50806: 27.2; [PATCH] Optimize ansi-color.el Resent-From: miha@kamnitnik.top Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 25 Sep 2021 22:30:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 50806 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: 50806@debbugs.gnu.org Cc: Jim Porter X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.163260896810060 (code B ref -1); Sat, 25 Sep 2021 22:30:02 +0000 Received: (at submit) by debbugs.gnu.org; 25 Sep 2021 22:29:28 +0000 Received: from localhost ([127.0.0.1]:35029 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mUGAh-0002c8-8b for submit@debbugs.gnu.org; Sat, 25 Sep 2021 18:29:28 -0400 Received: from lists.gnu.org ([209.51.188.17]:42310) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mUGAe-0002by-HP for submit@debbugs.gnu.org; Sat, 25 Sep 2021 18:29:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44822) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mUGAd-0002ze-S9 for bug-gnu-emacs@gnu.org; Sat, 25 Sep 2021 18:29:24 -0400 Received: from kamnitnik.top ([209.250.245.214]:33178) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mUGAa-0006Jh-8z for bug-gnu-emacs@gnu.org; Sat, 25 Sep 2021 18:29:23 -0400 Received: from localhost (unknown [IPv6:2a00:ee2:e04:9300:e18:5d33:4bd1:d3a4]) by kamnitnik.top (Postfix) with ESMTPSA id 94AD99C700; Sat, 25 Sep 2021 22:29:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kamnitnik.top; s=mail; t=1632608955; bh=XLzF216Tm97yYUYIei7EVroWgt/3FhhoJCZnPo8MVe0=; h=From:To:Cc:Subject:Date:From; b=ETBIZTcwYexGub0l3ddSJU5whKUZEgIJ2hvd6ARrAW5X19zOvX4AffwIWwyOmPlXm l1m2AYzk/rlU8l9zvK5MHdfo45n+L29Z+M8dWs8nz5q8g5Bfm6FLCoQbk2QGUTNZaE xJuiYiifzlYgCBxrHDRhcmswb1fz47YrCRg/qmx+MV9Ws9a9R+9Gr4FRVJuLWd7UjG dN4jLUEVvsMq9t9koY1cE85hXa5E8Ldh8FysZt4EMoCtWK4g60oHXemRPvE/W4vyBP kcOORc+6QQCVhubGYA5HQeGOEAQqic2xqs011hMq/YnJMSSiMQ61qkz8LCtN3PeetW N30QqoHhg+pbA== From: miha@kamnitnik.top Date: Sun, 26 Sep 2021 00:32:36 +0200 Message-ID: <87tui8wakb.fsf@miha-pc> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="==-=-="; micalg=pgp-sha256; protocol="application/pgp-signature" Received-SPF: pass client-ip=209.250.245.214; envelope-from=miha@kamnitnik.top; helo=kamnitnik.top X-Spam_score_int: 24 X-Spam_score: 2.4 X-Spam_bar: ++ X-Spam_report: (2.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FROM_SUSPICIOUS_NTLD=0.498, FROM_SUSPICIOUS_NTLD_FP=1.997, PDS_OTHER_BAD_TLD=1.997, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-Spam-Score: 1.7 (+) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Attached patch speeds up ansi-color. It tries to eliminate as many allocations (cons and list) as possible. Benchmarks, recorded in emacs -q, are in the second attachments. With the patch applied, there is a 26% speedup in elapsed time, mostly because the garbage collector has to take care of less allocatio [...] Content analysis details: (1.7 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [209.51.188.17 listed in list.dnswl.org] 2.0 PDS_OTHER_BAD_TLD Untrustworthy TLDs [URI: kamnitnik.top (top)] 0.9 SPF_FAIL SPF: sender does not match SPF record (fail) [SPF failed: Please see http://www.openspf.org/Why?s=mfrom; id=miha%40kamnitnik.top; ip=209.51.188.17; r=debbugs.gnu.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.51.188.17 listed in wl.mailspike.net] 0.5 FROM_SUSPICIOUS_NTLD_FP From abused NTLD 0.5 FROM_SUSPICIOUS_NTLD From abused NTLD X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 0.1 (/) --==-=-= Content-Type: multipart/mixed; boundary="=-=-=" --=-=-= Content-Type: text/plain Attached patch speeds up ansi-color. It tries to eliminate as many allocations (cons and list) as possible. Benchmarks, recorded in emacs -q, are in the second attachments. With the patch applied, there is a 26% speedup in elapsed time, mostly because the garbage collector has to take care of less allocations. Two less important side notes: 1) This patch additionally makes it very straight forward to add support for ANSI color codes 38 and 48 allowing 256-colors and 24bit full-color. I plan to submit such a patch later (for both ansi-color and term-mode). 2) Two vector variables, that were recently added by Jim, were merged into one. Adding him as CC. Best regards. --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-Optimize-ansi-color.el.patch Content-Transfer-Encoding: quoted-printable From=209b40c13dd83a1c9336ba2eadf90041c07acb82a1 Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?Miha=3D20Rihtar=3DC5=3DA1i=3DC4=3D8D?=3D Date: Sat, 25 Sep 2021 23:05:11 +0200 Subject: [PATCH 1/3] Optimize ansi-color.el * lisp/ansi-color.el (ansi-color-normal-colors-vector): (ansi-color-bright-colors-vector): Merge these two vectors into one. (ansi-color-context-region): (ansi-color-context): Adjust doc string to the new format of ansi-color context. (ansi-color--find-face): Rename to ansi-color--face-vec-face (ansi-color--face-vec-face): Adjust to the new format ansi-color context. (ansi-color-apply): (ansi-color-apply-on-region): Adjust to the new format of ansi-color context in order to speed these two functions up (ansi-color-apply-sequence): Make it obsolete (ansi-color--update-face-vec): New function to handle the new format of ansi-color context. (ansi-color-get-face-1): Make obsolete as this function isn't used any more. =2D-- lisp/ansi-color.el | 308 ++++++++++++++++++++++++++++++--------------- 1 file changed, 206 insertions(+), 102 deletions(-) diff --git a/lisp/ansi-color.el b/lisp/ansi-color.el index b1c9cdaeca..d9d6f1c78d 100644 =2D-- a/lisp/ansi-color.el +++ b/lisp/ansi-color.el @@ -288,7 +288,7 @@ ansi-color-basic-faces-vector 6 rapidly blinking 7 negative image") =20 =2D(defvar ansi-color-normal-colors-vector +(defvar ansi-color-colors-vector [ansi-color-black ansi-color-red ansi-color-green @@ -296,12 +296,26 @@ ansi-color-normal-colors-vector ansi-color-blue ansi-color-magenta ansi-color-cyan =2D ansi-color-white] + ansi-color-white + + ansi-color-bright-black + ansi-color-bright-red + ansi-color-bright-green + ansi-color-bright-yellow + ansi-color-bright-blue + ansi-color-bright-magenta + ansi-color-bright-cyan + ansi-color-bright-white] + "Faces used for SGR control sequences determining a color. =2DThis vector holds the faces used for SGR control sequence parameters =2D30 to 37 (foreground colors) and 40 to 47 (background colors). +The first eight elements are faces used for SGR control sequence +parameters 30 to 37 (foreground colors) and 40 to 47 (background +colors). The second eight elements are the faces used for SGR +control sequence parameters 90 to 97 (bright foreground colors) +and 100 to 107 (bright background colors). =20 Parameter Color + 30 40 black 31 41 red 32 42 green @@ -309,23 +323,8 @@ ansi-color-normal-colors-vector 34 44 blue 35 45 magenta 36 46 cyan =2D 37 47 white") =2D =2D(defvar ansi-color-bright-colors-vector =2D [ansi-color-bright-black =2D ansi-color-bright-red =2D ansi-color-bright-green =2D ansi-color-bright-yellow =2D ansi-color-bright-blue =2D ansi-color-bright-magenta =2D ansi-color-bright-cyan =2D ansi-color-bright-white] =2D "Faces used for SGR control sequences determining a \"bright\" color. =2DThis vector holds the faces used for SGR control sequence parameters =2D90 to 97 (bright foreground colors) and 100 to 107 (bright background =2Dcolors). + 37 47 white =20 =2DParameter Color 90 100 bright black 91 101 bright red 92 102 bright green @@ -458,11 +457,18 @@ 'ansi-color-unfontify-region ;; Working with strings (defvar-local ansi-color-context nil "Context saved between two calls to `ansi-color-apply'. =2DThis is a list of the form (CODES FRAGMENT) or nil. CODES +This is a list of the form (FACE-VEC FRAGMENT) or nil. FACE-VEC represents the state the last call to `ansi-color-apply' ended =2Dwith, currently a list of ansi codes, and FRAGMENT is a string =2Dstarting with an escape sequence, possibly the start of a new =2Descape sequence.") +with, currently a list of the form + +(BASIC-FACES FG BG). + +BASIC-FACES is a bool-vector that specifies which basic faces +from `ansi-color-basic-faces-vector' to apply. FG and BG are +ANSI color codes for the foreground and background color. + +FRAGMENT is a string starting with an escape sequence, possibly +the start of a new escape sequence.") =20 (defun ansi-color-filter-apply (string) "Filter out all ANSI control sequences from STRING. @@ -494,20 +500,39 @@ ansi-color-filter-apply (setq ansi-color-context (if fragment (list nil fragment)))) (apply #'concat (nreverse result)))) =20 =2D(defun ansi-color--find-face (codes) =2D "Return the face corresponding to CODES." =2D ;; Sort the codes in ascending order to guarantee that "bold" comes be= fore =2D ;; any of the colors. This ensures that `ansi-color-bold-is-bright' is =2D ;; applied correctly. =2D (let (faces bright (codes (sort (copy-sequence codes) #'<))) =2D (while codes =2D (when-let ((face (ansi-color-get-face-1 (pop codes) bright))) =2D (when (and ansi-color-bold-is-bright (eq face 'ansi-color-bold)) =2D (setq bright t)) =2D (push face faces))) +(defun ansi-color--face-vec-face (face-vec) + "Return the face corresponding to FACE-VEC. +FACE-VEC is a list containing information about the ANSI sequence +code. It is usually stored as the car of the variable +`ansi-color-context-region'." + (let* ((basic-faces (car face-vec)) + (colors (cdr face-vec)) + (bright (and ansi-color-bold-is-bright (aref basic-faces 1))) + (faces nil)) + + (when-let ((fg (car colors))) + (push + `(:foreground + ,(face-foreground + (aref ansi-color-colors-vector (logior (if bright 8 0) fg)) + nil 'default)) + faces)) + (when-let ((bg (cadr colors))) + (push + `(:background + ,(face-background + (aref ansi-color-colors-vector (logior (if bright 8 0) bg)) + nil 'default)) + faces)) + + (let ((i 8)) + (while (> i 0) + (setq i (1- i)) + (when (aref basic-faces i) + (push (aref ansi-color-basic-faces-vector i) faces)))) ;; Avoid some long-lived conses in the common case. (if (cdr faces) =2D (nreverse faces) + faces (car faces)))) =20 (defun ansi-color-apply (string) @@ -524,49 +549,71 @@ ansi-color-apply Set `ansi-color-context' to nil if you don't want this. =20 This function can be added to `comint-preoutput-filter-functions'." =2D (let ((codes (car ansi-color-context)) =2D (start 0) end result) + (let* ((context + (or ansi-color-context + (setq ansi-color-context + (list + (list + ;; 8 slots for the basic faces + (make-bool-vector 8 nil) + ;; 2 slots for fg and bg number + nil nil) + "")))) + (face-vec (car context)) + (start 0) + end result) ;; If context was saved and is a string, prepend it. =2D (if (cadr ansi-color-context) =2D (setq string (concat (cadr ansi-color-context) string) =2D ansi-color-context nil)) + (setq string (concat (cadr context) string)) + (setcar (cdr context) "") ;; Find the next escape sequence. (while (setq end (string-match ansi-color-control-seq-regexp string st= art)) (let ((esc-end (match-end 0))) ;; Colorize the old block from start to end using old face. =2D (when codes + (when-let ((face (ansi-color--face-vec-face face-vec))) (put-text-property start end 'font-lock-face =2D (ansi-color--find-face codes) string)) + face string)) (push (substring string start end) result) (setq start (match-end 0)) ;; If this is a color escape sequence, (when (eq (aref string (1- esc-end)) ?m) ;; create a new face from it. =2D (setq codes (ansi-color-apply-sequence =2D (substring string end esc-end) codes))))) + (let ((cur-pos end)) + (ansi-color--update-face-vec + face-vec + (lambda () + (when (string-match ansi-color-parameter-regexp + string cur-pos) + (setq cur-pos (match-end 0)) + (when (<=3D cur-pos esc-end) + (string-to-number (match-string 1 string)))))))))) ;; if the rest of the string should have a face, put it there =2D (when codes + (when-let ((face (ansi-color--face-vec-face face-vec))) (put-text-property start (length string) =2D 'font-lock-face (ansi-color--find-face codes) s= tring)) + 'font-lock-face face string)) ;; save context, add the remainder of the string to the result =2D (let (fragment) =2D (if (string-match "\033" string start) =2D (let ((pos (match-beginning 0))) =2D (setq fragment (substring string pos)) =2D (push (substring string start pos) result)) =2D (push (substring string start) result)) =2D (setq ansi-color-context (if (or codes fragment) (list codes fragm= ent)))) + (if (string-match "\033" string start) + (let ((pos (match-beginning 0))) + (setcar (cdr context) (substring string pos)) + (push (substring string start pos) result)) + (push (substring string start) result)) (apply 'concat (nreverse result)))) =20 ;; Working with regions =20 (defvar-local ansi-color-context-region nil "Context saved between two calls to `ansi-color-apply-on-region'. =2DThis is a list of the form (CODES MARKER) or nil. CODES +This is a list of the form (FACE-VEC MARKER) or nil. FACE-VEC represents the state the last call to `ansi-color-apply-on-region' =2Dended with, currently a list of ansi codes, and MARKER is a =2Dbuffer position within an escape sequence or the last position =2Dprocessed.") +ended with, currently a list of the form + +(BASIC-FACES FG BG). + +BASIC-FACES is a bool-vector that specifies which basic faces +from `ansi-color-basic-faces-vector' to apply. FG and BG are +ANSI color codes for the foreground and background color. + +MARKER is a buffer position within an escape sequence or the last +position processed.") =20 (defun ansi-color-filter-region (begin end) "Filter out all ANSI control sequences from region BEGIN to END. @@ -608,58 +655,63 @@ ansi-color-apply-on-region =20 If PRESERVE-SEQUENCES is t, the sequences are hidden instead of being deleted." =2D (let ((codes (car ansi-color-context-region)) =2D (start-marker (or (cadr ansi-color-context-region) =2D (copy-marker begin))) =2D (end-marker (copy-marker end))) + (let* ((context + (or ansi-color-context-region + (setq ansi-color-context-region + (list + (list + ;; 8 slots for the basic faces + (make-bool-vector 8 nil) + ;; 2 slots for fg and bg numbers + nil nil) + (copy-marker begin))))) + (face-vec (car context)) + (start-marker (cadr context)) + (end-marker (copy-marker end))) (save-excursion (goto-char start-marker) ;; Find the next escape sequence. (while (re-search-forward ansi-color-control-seq-regexp end-marker t) ;; Extract escape sequence. =2D (let ((esc-seq (buffer-substring =2D (match-beginning 0) (point)))) =2D (if preserve-sequences =2D ;; Make the escape sequence transparent. =2D (overlay-put (make-overlay (match-beginning 0) (point)) =2D 'invisible t) =2D ;; Otherwise, strip. =2D (delete-region (match-beginning 0) (point))) =2D + (let ((esc-beg (match-beginning 0)) + (esc-end (point))) ;; Colorize the old block from start to end using old face. (funcall ansi-color-apply-face-function (prog1 (marker-position start-marker) ;; Store new start position. =2D (set-marker start-marker (point))) =2D (match-beginning 0) (ansi-color--find-face codes)) + (set-marker start-marker esc-end)) + esc-beg (ansi-color--face-vec-face face-vec)) ;; If this is a color sequence, =2D (when (eq (aref esc-seq (1- (length esc-seq))) ?m) =2D ;; update the list of ansi codes. =2D (setq codes (ansi-color-apply-sequence esc-seq codes))))) + (when (eq (char-before esc-end) ?m) + (goto-char esc-beg) + (ansi-color--update-face-vec + face-vec (lambda () + (when (re-search-forward ansi-color-parameter-rege= xp + esc-end t) + (string-to-number (match-string 1)))))) + + (if preserve-sequences + ;; Make the escape sequence transparent. + (overlay-put (make-overlay esc-beg esc-end) 'invisible t) + ;; Otherwise, strip. + (delete-region esc-beg esc-end)))) ;; search for the possible start of a new escape sequence (if (re-search-forward "\033" end-marker t) =2D (progn =2D ;; if the rest of the region should have a face, put it there =2D (funcall ansi-color-apply-face-function =2D start-marker (point) (ansi-color--find-face codes)) =2D ;; save codes and point =2D (setq ansi-color-context-region =2D (list codes (copy-marker (match-beginning 0))))) =2D ;; if the rest of the region should have a face, put it there =2D (funcall ansi-color-apply-face-function =2D start-marker end-marker (ansi-color--find-face codes)) =2D ;; Save a restart position when there are codes active. It's =2D ;; convenient for man.el's process filter to pass `begin' =2D ;; positions that overlap regions previously colored; these =2D ;; `codes' should not be applied to that overlap, so we need =2D ;; to know where they should really start. =2D (setq ansi-color-context-region =2D (if codes (list codes (copy-marker (point))))))) =2D ;; Clean up our temporary markers. =2D (unless (eq start-marker (cadr ansi-color-context-region)) =2D (set-marker start-marker nil)) =2D (unless (eq end-marker (cadr ansi-color-context-region)) =2D (set-marker end-marker nil)))) + (progn + (while (re-search-forward "\033" end-marker t)) + (backward-char)) + (goto-char end-marker)) + (funcall ansi-color-apply-face-function + start-marker (point) + (ansi-color--face-vec-face face-vec)) + ;; Save a restart position when there are codes active. It's + ;; convenient for man.el's process filter to pass `begin' + ;; positions that overlap regions previously colored; these + ;; `codes' should not be applied to that overlap, so we need + ;; to know where they should really start. + (set-marker start-marker (point))) + ;; Clean up our temporary marker. + (set-marker end-marker nil))) =20 (defun ansi-color-apply-overlay-face (beg end face) "Make an overlay from BEG to END, and apply face FACE. @@ -767,6 +819,7 @@ ansi-color-apply-sequence is 40-47 (or 100-107) resp. 49, the background color code is replaced or added resp. deleted; any other code is discarded together with the old codes. Finally, the so changed list of codes is returned." + (declare (obsolete "it isn't used any more." "28.1")) (let ((new-codes (ansi-color-parse-sequence escape-sequence))) (while new-codes (let* ((new (pop new-codes)) @@ -795,6 +848,56 @@ ansi-color-apply-sequence (_ nil))))) codes)) =20 +(defun ansi-color--update-face-vec (face-vec iterator) + "Apply escape sequences to FACE-VEC. + +Destructively modify FACE-VEC, which should be a list containing +face information. It is described in +`ansi-color-context-region'. ITERATOR is a function which is +called repeatedly with zero arguments and should return either +the next ANSI code in the current sequence as a number or nil if +there are no more ANSI codes left + +For each new code, the following happens: if it is 1-7, set the +corresponding properties; if it is 21-25 or 27, unset appropriate +properties; if it is 30-37 (or 90-97) or resp. 39, set the +foreground color or resp. unset it; if it is 40-47 (or 100-107) +resp. 49, set the background color or resp. unset it; if it is 38 +or 48, the following codes are used to set the foreground or +background color and the correct color mode; any other code will +unset all properties and colors." + (let ((basic-faces (car face-vec)) + (colors (cdr face-vec)) + new q do-clear) + (while (setq new (funcall iterator)) + (setq q (/ new 10)) + (pcase q + (0 (if (memq new '(0 8 9)) + (setq do-clear t) + (aset basic-faces new t))) + (2 (if (memq new '(20 26 28 29)) + (setq do-clear t) + ;; The standard says `21 doubly underlined' while + ;; https://en.wikipedia.org/wiki/ANSI_escape_code claims + ;; `21 Bright/Bold: off or Underline: Double'. + (aset basic-faces (- new 20) nil) + (aset basic-faces (pcase new (22 1) (25 6) (_ 0)) nil))) + ((or 3 4 9 10) + (let ((r (mod new 10)) + (cell (if (memq q '(3 9)) colors (cdr colors)))) + (pcase r + (8 (setq do-clear t)) + (9 (setcar cell nil)) + (_ (setcar cell (+ (if (memq q '(3 4)) 0 8) r)))))) + (_ (setq do-clear t))) + + (when do-clear + (setq do-clear nil) + ;; Zero out our bool vector without any allocation + (bool-vector-intersection basic-faces #&8"\0" basic-faces) + (setcar colors nil) + (setcar (cdr colors) nil))))) + (defun ansi-color-make-color-map () "Create a vector of face definitions and return it. =20 @@ -859,6 +962,7 @@ ansi-color-get-face-1 "Get face definition for ANSI-CODE. BRIGHT, if non-nil, requests \"bright\" ANSI colors, even if ANSI-CODE is a normal-intensity color." + (declare (obsolete "it isn't used any more." "28.1")) (when (and bright (<=3D 30 ansi-code 49)) (setq ansi-code (+ ansi-code 60))) (cond ((<=3D 0 ansi-code 7) @@ -866,22 +970,22 @@ ansi-color-get-face-1 ((<=3D 30 ansi-code 38) (list :foreground (face-foreground =2D (aref ansi-color-normal-colors-vector (- ansi-code 30)) + (aref ansi-color-colors-vector (- ansi-code 30)) nil 'default))) ((<=3D 40 ansi-code 48) (list :background (face-background =2D (aref ansi-color-normal-colors-vector (- ansi-code 40)) + (aref ansi-color-colors-vector (- ansi-code 40)) nil 'default))) ((<=3D 90 ansi-code 98) (list :foreground (face-foreground =2D (aref ansi-color-bright-colors-vector (- ansi-code 90)) + (aref ansi-color-colors-vector (+ 8 (- ansi-code 90))) nil 'default))) ((<=3D 100 ansi-code 108) (list :background (face-background =2D (aref ansi-color-bright-colors-vector (- ansi-code 100)) + (aref ansi-color-colors-vector (+ 8 (- ansi-code 100))) nil 'default))))) =20 (provide 'ansi-color) =2D-=20 2.33.0 --=-=-= Content-Type: application/vnd.lotus-organizer Content-Disposition: attachment; filename=ansi-color-benchmark.org Content-Transfer-Encoding: base64 SW4gb3JnLW1vZGUsIHByZXNzIEMtYyBDLWMgb24gdGhlIGZvbGxvd2luZyBzb3VyY2UgYmxvY2sg dG8gcHJvZHVjZSBhCm5ldyBiZW5jaG1hcmsgcmVzdWx0LgoKIytiZWdpbl9zcmMgZW1hY3MtbGlz cCA6cmVzdWx0cyBhcHBlbmQKICAocmVxdWlyZSAnYW5zaS1jb2xvcikKICAoZXZhbC13aGVuLWNv bXBpbGUKICAgIChyZXF1aXJlICdjbC1saWIpKQoKICAoZGVmdW4gYW5zaS1jb2xvci1iZW5jaC1y YW5kb20tZXNjLXNlcSAoKQogICAgKGNvbmNhdAogICAgICJcZVsiCiAgICAgKG1hcGNvbmNhdAog ICAgICAjJ2lkZW50aXR5CiAgICAgIChjbC1sb29wCiAgICAgICBmb3IgaSBiZWxvdyAocmFuZG9t IDEyKQogICAgICAgY29sbGVjdAogICAgICAgKHBjYXNlIChyYW5kb20gNikKICAgICAgICAgKDAg KG51bWJlci10by1zdHJpbmcgKDErIChyYW5kb20gNykpKSkKICAgICAgICAgKDEgKG51bWJlci10 by1zdHJpbmcgKCsgMjEgKHJhbmRvbSA3KSkpKQogICAgICAgICAoMiAobnVtYmVyLXRvLXN0cmlu ZyAoKyAzMCAocmFuZG9tIDgpKSkpCiAgICAgICAgICgzIChudW1iZXItdG8tc3RyaW5nICgrIDQw IChyYW5kb20gOCkpKSkKICAgICAgICAgKDQgKG51bWJlci10by1zdHJpbmcgKCsgOTAgKHJhbmRv bSA4KSkpKQogICAgICAgICAoNSAobnVtYmVyLXRvLXN0cmluZyAoKyAxMDAgKHJhbmRvbSA4KSkp KSkpCiAgICAgICI7IikKICAgICAibSIpKQoKICAod2l0aC10ZW1wLWJ1ZmZlcgogICAgKGRvdGlt ZXMgKF8gNTAwMDApCiAgICAgIChpbnNlcnQgKGFuc2ktY29sb3ItYmVuY2gtcmFuZG9tLWVzYy1z ZXEpKQogICAgICAoaW5zZXJ0ICJhYmNkZSIpKQogICAgKGdvdG8tY2hhciAocG9pbnQtbWluKSkK ICAgIChsZXQgKChhbnNpLWNvbG9yLWFwcGx5LWZhY2UtZnVuY3Rpb24gIydhbnNpLWNvbG9yLWFw cGx5LXRleHQtcHJvcGVydHktZmFjZSkpCiAgICAgIChiZW5jaG1hcmstcnVuLWNvbXBpbGVkIDEK ICAgICAgICAod2hpbGUgKG5vdCAoZW9icCkpCiAgICAgICAgICAoYW5zaS1jb2xvci1hcHBseS1v bi1yZWdpb24KICAgICAgICAgICAocG9pbnQpCiAgICAgICAgICAgKHByb2duIChnb3RvLWNoYXIg KCsgKHBvaW50KSAocmFuZG9tIDQwMCkpKSAocG9pbnQpKSkpKSkpCiMrZW5kX3NyYwoKIytSRVNV TFRTOgp8ICAgICAgIEVsYXBzZWQgdGltZSB8IEdDcyB8ICAgICAgICAgICAgR0MgdGltZSB8Cnwt LS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLXwKfCAgICAgICAg IFdpdGggcGF0Y2ggfCAgICAgfCAgICAgICAgICAgICAgICAgICAgfAp8LS0tLS0tLS0tLS0tLS0t LS0tLS0rLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS18CnwgMi4wODEwNTgwNzIwMDAwMDAzIHwg IDE5IHwgMC44ODA5ODYyODE5OTk5OTg1IHwKfCAgICAgICAgMi4wODQzODIxNjggfCAgMTggfCAw Ljg5MjAyMjA0MzAwMDAwMDggfAp8IDIuMDMwNDc4MTAxMDAwMDAwNCB8ICAxNyB8IDAuODQzMTUx MDg5OTk5OTk5MiB8CnwgICAgICAgIDIuMDg3OTkwMzc5IHwgIDE4IHwgMC44OTc3NTE3NTIwMDAw MDEzIHwKfCAyLjA3ODAzOTg4MDAwMDAwMDQgfCAgMTggfCAwLjg5MDI1NDM1OTAwMDAwMzYgfAp8 LS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS18CnwgICAgICBX aXRob3V0IHBhdGNoIHwgICAgIHwgICAgICAgICAgICAgICAgICAgIHwKfC0tLS0tLS0tLS0tLS0t LS0tLS0tKy0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tfAp8IDIuODQzMTk5MTk5MDAwMDAwMyB8 ICAzMSB8IDEuNTAwNTMyMjM1OTk5OTk4OSB8CnwgICAgICAgICAyLjc4OTE2ODcyIHwgIDI4IHwg ICAgICAgIDEuNDU3MDA3NjM0IHwKfCAyLjc4Nzc0NDM3Njk5OTk5OTcgfCAgMjggfCAxLjQ0OTQ5 OTI3NDAwMDAwMDggfAp8ICAgICAgICAgMi44MDcxNTc5NSB8ICAyOCB8IDEuNDU3NTAzMjkzOTk5 OTk4NiB8CnwgICAgICAgIDIuNzkxNzMyMjQ1IHwgIDI4IHwgMS40NTYxOTc2ODQ5OTk5OTk0IHwK --=-=-=-- --==-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQJHBAEBCAAxFiEEmxVnesoT5rQXvVXnswkaGpIVmT8FAmFPo4QTHG1paGFAa2Ft bml0bmlrLnRvcAAKCRCzCRoakhWZP7heEADAhI/VD7idYJgGLNGlzAfHYqTgJRa8 WFvpGeJ+ASiZkJjfx+34xYlfGz1OO+5E1Qur1VShPx/mNoFI5YJpdPWbh+tAdtna q1oOMkqqiVIrT6Se6bK9ugdOhFp0y7JIwr4UT6emvxtHMLKtLcubursZynJxfjfZ +Q/P1pYljRlLDDrx4B2HERwCJOs9fa+0gHFKzgtN0G5dSEkiXqzO0zIpgTZL1w3j /yPRtAXLyfGuOFd4qzKhsrm68CCIw3xrawkyCvCHZTmYFdsF2U1jctgbHo2HvMbU cvQdgMJTdmMqDURP6GKe/J0BDEuZvJ0X6doBRu0VTD7I44OS6GCI/6O7O2M9CZRc 46LjqVnVc+vI7BJ1mOEgLY4x5C4oH67uZa3sDaTzCQLYRd3sjRfGyAza8qFx0vln eAx6vs4m8xVgAYOrYdaR3j1UE4k5oY6np9XKWKs2ygY2O5fNtZIVTPFfeQg3i024 9U1rXfUIc8V3cXAtrB0oHMrAYtyT37IdjEnRm+j6hHZyvQmKexyBFL4Hm3fIyrD+ dXYnhbtsoNkWlNVtqVlovQTLO6TLs7KBwdC42+bVVTZSjuGYVbz5q5xSMN0nAljK +jkCh8tT82P+3XkROcxUh4IhbofMQbrJ6u/Gju+X4k62cNDZOJ3hr92fIxJEPft1 XPr9WELoWQKQnQ== =5WLh -----END PGP SIGNATURE----- --==-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Wed Sep 29 11:20:29 2021 Received: (at control) by debbugs.gnu.org; 29 Sep 2021 15:20:29 +0000 Received: from localhost ([127.0.0.1]:49846 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mVbNl-0007iO-A6 for submit@debbugs.gnu.org; Wed, 29 Sep 2021 11:20:29 -0400 Received: from mail-pj1-f51.google.com ([209.85.216.51]:35483) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mVbNj-0007i4-CK for control@debbugs.gnu.org; Wed, 29 Sep 2021 11:20:27 -0400 Received: by mail-pj1-f51.google.com with SMTP id d13-20020a17090ad3cd00b0019e746f7bd4so4497871pjw.0 for ; Wed, 29 Sep 2021 08:20:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:mime-version:date:message-id:subject:to; bh=LDrq6Wjzt4RU3zFvwKo/Mo+cpCSCZ3dQm8vOhk8qaa4=; b=iPJtBqvZHiHeMbfE8an5RMSjr6UAORaVzDsqzAF9knWlPxiWOQ1ghI/GmvkGql5Ywm 1osII0kPt43ZvmcdNUTqNdiw+txmafE76TY6mfFvYvJ9ZPhMhQdqjDjfJaxhPzCgZaJh ukZ/JN8XyYZifq1mMEl1as8P07f/Kr2k6fXbNR1IECiFP8cyxpkGZs8tRuZ6KlSgCP9C Pe80pg4UHpPZysSbzgG7RWBZuAIeCsscYgU+KkA2cgOd6baTeOqK1RVOOwL/6484qIMI PeVKg0Er46OETkiLCHpbS3RZqvori2Yg2Y5ke8S9pe1KNqaOqBY8cWFYsx25elX3ZK4B MF/g== X-Gm-Message-State: AOAM533J0WbUEzpTAGUVM8VdGWxhN9LImkfhrqGublrpoKIHoUPY5Ru9 T5L+FwTFB63Rr0fsMgxA0s+1NmyUTWlM77g5yEDPUDEh X-Google-Smtp-Source: ABdhPJy6jk7osOcT393TPl0TUqP9c50rNhtJifwE4luVifHxHKzctWv30S4021EeY4GBv43pIbeiA7mIjdNleyOL8hA= X-Received: by 2002:a17:902:b691:b029:12d:2b6:d116 with SMTP id c17-20020a170902b691b029012d02b6d116mr197454pls.71.1632928821692; Wed, 29 Sep 2021 08:20:21 -0700 (PDT) Received: from 753933720722 named unknown by gmailapi.google.com with HTTPREST; Wed, 29 Sep 2021 08:20:21 -0700 From: Stefan Kangas MIME-Version: 1.0 Date: Wed, 29 Sep 2021 08:20:21 -0700 Message-ID: Subject: control message for bug #50806 To: control@debbugs.gnu.org Content-Type: text/plain; charset="UTF-8" X-Spam-Score: 0.5 (/) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.5 (/) severity 50806 wishlist quit From unknown Wed Aug 20 03:37:10 2025 X-Loop: help-debbugs@gnu.org Subject: bug#50806: 27.2; [PATCH] Optimize ansi-color.el Resent-From: Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 03 Oct 2021 16:29:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 50806 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: 50806@debbugs.gnu.org Cc: Jim Porter Received: via spool by 50806-submit@debbugs.gnu.org id=B50806.163327851115689 (code B ref 50806); Sun, 03 Oct 2021 16:29:01 +0000 Received: (at 50806) by debbugs.gnu.org; 3 Oct 2021 16:28:31 +0000 Received: from localhost ([127.0.0.1]:34802 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mX4Lm-00044y-EG for submit@debbugs.gnu.org; Sun, 03 Oct 2021 12:28:31 -0400 Received: from kamnitnik.top ([209.250.245.214]:38050) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mX4Lh-00044l-CD for 50806@debbugs.gnu.org; Sun, 03 Oct 2021 12:28:29 -0400 Received: from localhost (BSN-77-156-43.static.siol.net [193.77.156.43]) by kamnitnik.top (Postfix) with ESMTPSA id A62B29C707; Sun, 3 Oct 2021 16:28:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kamnitnik.top; s=mail; t=1633278503; bh=feMmCQ+V8m3sDvEuGuVmsHNLsj5HE16ZpzcjwXEpZ7c=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From; b=tQ/T8NOycnSQ8W+3oobBfusJR+GB256OcV3tpIDyLRsLRx6Gq55zv3cfB8S1daNqO L+d/OGzUqS4UVNrvQylzJuBNB2F6CupcUxugcJvggO0tes05Qs5zVwYkd3XFviGB/s rWpUkieUzV1cbKMsK5uTrEmI91w5H5p2t6AMWk+TsV1U0Ft2aPdTaBQtHg6cItbZ+N GLPv7KKJiop5uuPNpYbtJdJrqgPglw6iF+Xjvi4uVUwvr771JJq+uDG3jFma0oyFnw pcVOwimQ+dTQQDNejRPMuFkv8WXg5MvfG+So7R/8y+WvvBgGH/Tu4qVQjMULeKj5al hqhmGnucgeAuQ== From: In-Reply-To: <87tui8wakb.fsf@miha-pc> References: <87tui8wakb.fsf@miha-pc> Date: Sun, 03 Oct 2021 18:31:55 +0200 Message-ID: <87v92eax38.fsf@miha-pc> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="==-=-="; micalg=pgp-sha256; protocol="application/pgp-signature" X-Spam-Score: 2.5 (++) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: miha--- via "Bug reports for GNU Emacs, the Swiss army knife of text editors" writes: > Attached patch speeds up ansi-color. It tries to eliminate as many > allocations (cons and list) as possible. > Sending patch, adjusted for Emacs 29. Content analysis details: (2.5 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 2.0 PDS_OTHER_BAD_TLD Untrustworthy TLDs [URI: kamnitnik.top (top)] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record 0.5 FROM_SUSPICIOUS_NTLD From abused NTLD X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 2.5 (++) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: miha--- via "Bug reports for GNU Emacs, the Swiss army knife of text editors" writes: > Attached patch speeds up ansi-color. It tries to eliminate as many > allocations (cons and list) as possible. > Sending patch, adjusted for Emacs 29. Content analysis details: (2.5 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 2.0 PDS_OTHER_BAD_TLD Untrustworthy TLDs [URI: kamnitnik.top (top)] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record 0.5 FROM_SUSPICIOUS_NTLD From abused NTLD 1.0 BULK_RE_SUSP_NTLD Precedence bulk and RE: from a suspicious TLD -1.0 MAILING_LIST_MULTI Multiple indicators imply a widely-seen list manager --==-=-= Content-Type: multipart/mixed; boundary="=-=-=" --=-=-= Content-Type: text/plain miha--- via "Bug reports for GNU Emacs, the Swiss army knife of text editors" writes: > Attached patch speeds up ansi-color. It tries to eliminate as many > allocations (cons and list) as possible. > Sending patch, adjusted for Emacs 29. --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-Optimize-ansi-color.el.patch Content-Transfer-Encoding: quoted-printable From=2051ea3f59898fec91a9760447c9c5f4bbd51f85f2 Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?Miha=3D20Rihtar=3DC5=3DA1i=3DC4=3D8D?=3D Date: Sat, 2 Oct 2021 21:36:10 +0200 Subject: [PATCH] Optimize ansi-color.el (ansi-color-context-region): (ansi-color-context): Adjust doc string to the new format of ansi-color context. (ansi-color--find-face): Rename to ansi-color--face-vec-face (ansi-color--face-vec-face): Adjust to the new format ansi-color context. (ansi-color-filter-apply): (ansi-color-apply): (ansi-color-filter-region): (ansi-color-apply-on-region): Adjust to the new format of ansi-color context in order to speed these functions up. (ansi-color-apply-sequence): Make it obsolete. (ansi-color--update-face-vec): New function to handle the new format of ansi-color context. (ansi-color-get-face-1): Make obsolete as this function isn't used any more. =2D-- lisp/ansi-color.el | 309 +++++++++++++++++++++++++++++++-------------- 1 file changed, 217 insertions(+), 92 deletions(-) diff --git a/lisp/ansi-color.el b/lisp/ansi-color.el index b1c9cdaeca..7b46754d83 100644 =2D-- a/lisp/ansi-color.el +++ b/lisp/ansi-color.el @@ -458,11 +458,18 @@ 'ansi-color-unfontify-region ;; Working with strings (defvar-local ansi-color-context nil "Context saved between two calls to `ansi-color-apply'. =2DThis is a list of the form (CODES FRAGMENT) or nil. CODES +This is a list of the form (FACE-VEC FRAGMENT) or nil. FACE-VEC represents the state the last call to `ansi-color-apply' ended =2Dwith, currently a list of ansi codes, and FRAGMENT is a string =2Dstarting with an escape sequence, possibly the start of a new =2Descape sequence.") +with, currently a list of the form + +(BASIC-FACES FG BG). + +BASIC-FACES is a bool-vector that specifies which basic faces +from `ansi-color-basic-faces-vector' to apply. FG and BG are +ANSI color codes for the foreground and background color. + +FRAGMENT is a string starting with an escape sequence, possibly +the start of a new escape sequence.") =20 (defun ansi-color-filter-apply (string) "Filter out all ANSI control sequences from STRING. @@ -473,17 +480,17 @@ ansi-color-filter-apply `ansi-color-context' to nil if you don't want this. =20 This function can be added to `comint-preoutput-filter-functions'." =2D (let ((start 0) end result) + (let ((context (ansi-color--ensure-context 'ansi-color-context nil)) + (start 0) end result) ;; if context was saved and is a string, prepend it =2D (if (cadr ansi-color-context) =2D (setq string (concat (cadr ansi-color-context) string) =2D ansi-color-context nil)) + (setq string (concat (cadr context) string)) + (setcar (cdr context) "") ;; find the next escape sequence (while (setq end (string-match ansi-color-control-seq-regexp string st= art)) (push (substring string start end) result) (setq start (match-end 0))) ;; save context, add the remainder of the string to the result =2D (let (fragment) + (let ((fragment "")) (push (substring string start (if (string-match "\033" string start) (let ((pos (match-beginning 0))) @@ -491,25 +498,9 @@ ansi-color-filter-apply pos) nil)) result) =2D (setq ansi-color-context (if fragment (list nil fragment)))) + (setcar (cdr context) fragment)) (apply #'concat (nreverse result)))) =20 =2D(defun ansi-color--find-face (codes) =2D "Return the face corresponding to CODES." =2D ;; Sort the codes in ascending order to guarantee that "bold" comes be= fore =2D ;; any of the colors. This ensures that `ansi-color-bold-is-bright' is =2D ;; applied correctly. =2D (let (faces bright (codes (sort (copy-sequence codes) #'<))) =2D (while codes =2D (when-let ((face (ansi-color-get-face-1 (pop codes) bright))) =2D (when (and ansi-color-bold-is-bright (eq face 'ansi-color-bold)) =2D (setq bright t)) =2D (push face faces))) =2D ;; Avoid some long-lived conses in the common case. =2D (if (cdr faces) =2D (nreverse faces) =2D (car faces)))) =2D (defun ansi-color-apply (string) "Translates SGR control sequences into text properties. Delete all other control sequences without processing them. @@ -524,49 +515,129 @@ ansi-color-apply Set `ansi-color-context' to nil if you don't want this. =20 This function can be added to `comint-preoutput-filter-functions'." =2D (let ((codes (car ansi-color-context)) =2D (start 0) end result) + (let* ((context + (ansi-color--ensure-context 'ansi-color-context nil)) + (face-vec (car context)) + (start 0) + end result) ;; If context was saved and is a string, prepend it. =2D (if (cadr ansi-color-context) =2D (setq string (concat (cadr ansi-color-context) string) =2D ansi-color-context nil)) + (setq string (concat (cadr context) string)) + (setcar (cdr context) "") ;; Find the next escape sequence. (while (setq end (string-match ansi-color-control-seq-regexp string st= art)) (let ((esc-end (match-end 0))) ;; Colorize the old block from start to end using old face. =2D (when codes + (when-let ((face (ansi-color--face-vec-face face-vec))) (put-text-property start end 'font-lock-face =2D (ansi-color--find-face codes) string)) + face string)) (push (substring string start end) result) (setq start (match-end 0)) ;; If this is a color escape sequence, (when (eq (aref string (1- esc-end)) ?m) ;; create a new face from it. =2D (setq codes (ansi-color-apply-sequence =2D (substring string end esc-end) codes))))) + (let ((cur-pos end)) + (ansi-color--update-face-vec + face-vec + (lambda () + (when (string-match ansi-color-parameter-regexp + string cur-pos) + (setq cur-pos (match-end 0)) + (when (<=3D cur-pos esc-end) + (string-to-number (match-string 1 string)))))))))) ;; if the rest of the string should have a face, put it there =2D (when codes + (when-let ((face (ansi-color--face-vec-face face-vec))) (put-text-property start (length string) =2D 'font-lock-face (ansi-color--find-face codes) s= tring)) + 'font-lock-face face string)) ;; save context, add the remainder of the string to the result =2D (let (fragment) =2D (if (string-match "\033" string start) =2D (let ((pos (match-beginning 0))) =2D (setq fragment (substring string pos)) =2D (push (substring string start pos) result)) =2D (push (substring string start) result)) =2D (setq ansi-color-context (if (or codes fragment) (list codes fragm= ent)))) + (if (string-match "\033" string start) + (let ((pos (match-beginning 0))) + (setcar (cdr context) (substring string pos)) + (push (substring string start pos) result)) + (push (substring string start) result)) (apply 'concat (nreverse result)))) =20 +(defun ansi-color--ensure-context (context-sym position) + "Return CONTEXT-SYM's value as a valid context. +If it is nil, set CONTEXT-SYM's value to a new context and return +it. Context is a list of the form as described in +`ansi-color-context' if POSITION is nil, or +`ansi-color-context-region' if POSITION is non-nil. + +If CONTEXT-SYM's value is already non-nil, return it. If its +marker doesn't point anywhere yet, position it before character +number POSITION, if non-nil." + (let ((context (symbol-value context-sym))) + (if context + (if position + (let ((marker (cadr context))) + (unless (marker-position marker) + (set-marker marker position)) + context) + context) + (set context-sym + (list (list (make-bool-vector 8 nil) + nil nil) + (if position + (copy-marker position) + "")))))) + +(defun ansi-color--face-vec-face (face-vec) + "Return the face corresponding to FACE-VEC. +FACE-VEC is a list containing information about the ANSI sequence +code. It is usually stored as the car of the variable +`ansi-color-context-region'." + (let* ((basic-faces (car face-vec)) + (colors (cdr face-vec)) + (bright (and ansi-color-bold-is-bright (aref basic-faces 1))) + (faces nil)) + + (when-let ((fg (car colors))) + (push + `(:foreground + ,(face-foreground + (aref (if (or bright (>=3D fg 8)) + ansi-color-bright-colors-vector + ansi-color-normal-colors-vector) + (mod fg 8)) + nil 'default)) + faces)) + (when-let ((bg (cadr colors))) + (push + `(:background + ,(face-background + (aref (if (or bright (>=3D bg 8)) + ansi-color-bright-colors-vector + ansi-color-normal-colors-vector) + (mod bg 8)) + nil 'default)) + faces)) + + (let ((i 8)) + (while (> i 0) + (setq i (1- i)) + (when (aref basic-faces i) + (push (aref ansi-color-basic-faces-vector i) faces)))) + ;; Avoid some long-lived conses in the common case. + (if (cdr faces) + faces + (car faces)))) + ;; Working with regions =20 (defvar-local ansi-color-context-region nil "Context saved between two calls to `ansi-color-apply-on-region'. =2DThis is a list of the form (CODES MARKER) or nil. CODES +This is a list of the form (FACE-VEC MARKER) or nil. FACE-VEC represents the state the last call to `ansi-color-apply-on-region' =2Dended with, currently a list of ansi codes, and MARKER is a =2Dbuffer position within an escape sequence or the last position =2Dprocessed.") +ended with, currently a list of the form + +(BASIC-FACES FG BG). + +BASIC-FACES is a bool-vector that specifies which basic faces +from `ansi-color-basic-faces-vector' to apply. FG and BG are +ANSI color codes for the foreground and background color. + +MARKER is a buffer position within an escape sequence or the last +position processed.") =20 (defun ansi-color-filter-region (begin end) "Filter out all ANSI control sequences from region BEGIN to END. @@ -576,8 +647,10 @@ ansi-color-filter-region used for the next call to `ansi-color-apply-on-region'. Specifically, it will override BEGIN, the start of the region. Set `ansi-color-context-region' to nil if you don't want this." =2D (let ((end-marker (copy-marker end)) =2D (start (or (cadr ansi-color-context-region) begin))) + (let* ((end-marker (copy-marker end)) + (context (ansi-color--ensure-context + 'ansi-color-context-region begin)) + (start (cadr context))) (save-excursion (goto-char start) ;; Delete escape sequences. @@ -585,8 +658,8 @@ ansi-color-filter-region (delete-region (match-beginning 0) (match-end 0))) ;; save context, add the remainder of the string to the result (if (re-search-forward "\033" end-marker t) =2D (setq ansi-color-context-region (list nil (match-beginning 0))) =2D (setq ansi-color-context-region nil))))) + (set-marker start (match-beginning 0)) + (set-marker start nil))))) =20 (defun ansi-color-apply-on-region (begin end &optional preserve-sequences) "Translates SGR control sequences into overlays or extents. @@ -608,58 +681,58 @@ ansi-color-apply-on-region =20 If PRESERVE-SEQUENCES is t, the sequences are hidden instead of being deleted." =2D (let ((codes (car ansi-color-context-region)) =2D (start-marker (or (cadr ansi-color-context-region) =2D (copy-marker begin))) =2D (end-marker (copy-marker end))) + (let* ((context (ansi-color--ensure-context + 'ansi-color-context-region begin)) + (face-vec (car context)) + (start-marker (cadr context)) + (end-marker (copy-marker end))) (save-excursion (goto-char start-marker) ;; Find the next escape sequence. (while (re-search-forward ansi-color-control-seq-regexp end-marker t) ;; Extract escape sequence. =2D (let ((esc-seq (buffer-substring =2D (match-beginning 0) (point)))) =2D (if preserve-sequences =2D ;; Make the escape sequence transparent. =2D (overlay-put (make-overlay (match-beginning 0) (point)) =2D 'invisible t) =2D ;; Otherwise, strip. =2D (delete-region (match-beginning 0) (point))) =2D + (let ((esc-beg (match-beginning 0)) + (esc-end (point))) ;; Colorize the old block from start to end using old face. (funcall ansi-color-apply-face-function (prog1 (marker-position start-marker) ;; Store new start position. =2D (set-marker start-marker (point))) =2D (match-beginning 0) (ansi-color--find-face codes)) + (set-marker start-marker esc-end)) + esc-beg (ansi-color--face-vec-face face-vec)) ;; If this is a color sequence, =2D (when (eq (aref esc-seq (1- (length esc-seq))) ?m) =2D ;; update the list of ansi codes. =2D (setq codes (ansi-color-apply-sequence esc-seq codes))))) + (when (eq (char-before esc-end) ?m) + (goto-char esc-beg) + (ansi-color--update-face-vec + face-vec (lambda () + (when (re-search-forward ansi-color-parameter-rege= xp + esc-end t) + (string-to-number (match-string 1)))))) + + (if preserve-sequences + ;; Make the escape sequence transparent. + (overlay-put (make-overlay esc-beg esc-end) 'invisible t) + ;; Otherwise, strip. + (delete-region esc-beg esc-end)))) ;; search for the possible start of a new escape sequence (if (re-search-forward "\033" end-marker t) =2D (progn =2D ;; if the rest of the region should have a face, put it there =2D (funcall ansi-color-apply-face-function =2D start-marker (point) (ansi-color--find-face codes)) =2D ;; save codes and point =2D (setq ansi-color-context-region =2D (list codes (copy-marker (match-beginning 0))))) =2D ;; if the rest of the region should have a face, put it there =2D (funcall ansi-color-apply-face-function =2D start-marker end-marker (ansi-color--find-face codes)) =2D ;; Save a restart position when there are codes active. It's =2D ;; convenient for man.el's process filter to pass `begin' =2D ;; positions that overlap regions previously colored; these =2D ;; `codes' should not be applied to that overlap, so we need =2D ;; to know where they should really start. =2D (setq ansi-color-context-region =2D (if codes (list codes (copy-marker (point))))))) =2D ;; Clean up our temporary markers. =2D (unless (eq start-marker (cadr ansi-color-context-region)) =2D (set-marker start-marker nil)) =2D (unless (eq end-marker (cadr ansi-color-context-region)) =2D (set-marker end-marker nil)))) + (progn + (while (re-search-forward "\033" end-marker t)) + (backward-char) + (funcall ansi-color-apply-face-function + start-marker (point) + (ansi-color--face-vec-face face-vec)) + (set-marker start-marker (point))) + (let ((faces (ansi-color--face-vec-face face-vec))) + (funcall ansi-color-apply-face-function + start-marker end-marker faces) + ;; Save a restart position when there are codes active. It's + ;; convenient for man.el's process filter to pass `begin' + ;; positions that overlap regions previously colored; these + ;; `codes' should not be applied to that overlap, so we need + ;; to know where they should really start. + (set-marker start-marker (when faces end-marker))))) + ;; Clean up our temporary marker. + (set-marker end-marker nil))) =20 (defun ansi-color-apply-overlay-face (beg end face) "Make an overlay from BEG to END, and apply face FACE. @@ -767,6 +840,7 @@ ansi-color-apply-sequence is 40-47 (or 100-107) resp. 49, the background color code is replaced or added resp. deleted; any other code is discarded together with the old codes. Finally, the so changed list of codes is returned." + (declare (obsolete ansi-color--update-face-vec "29.1")) (let ((new-codes (ansi-color-parse-sequence escape-sequence))) (while new-codes (let* ((new (pop new-codes)) @@ -795,6 +869,56 @@ ansi-color-apply-sequence (_ nil))))) codes)) =20 +(defun ansi-color--update-face-vec (face-vec iterator) + "Apply escape sequences to FACE-VEC. + +Destructively modify FACE-VEC, which should be a list containing +face information. It is described in +`ansi-color-context-region'. ITERATOR is a function which is +called repeatedly with zero arguments and should return either +the next ANSI code in the current sequence as a number or nil if +there are no more ANSI codes left + +For each new code, the following happens: if it is 1-7, set the +corresponding properties; if it is 21-25 or 27, unset appropriate +properties; if it is 30-37 (or 90-97) or resp. 39, set the +foreground color or resp. unset it; if it is 40-47 (or 100-107) +resp. 49, set the background color or resp. unset it; if it is 38 +or 48, the following codes are used to set the foreground or +background color and the correct color mode; any other code will +unset all properties and colors." + (let ((basic-faces (car face-vec)) + (colors (cdr face-vec)) + new q do-clear) + (while (setq new (funcall iterator)) + (setq q (/ new 10)) + (pcase q + (0 (if (memq new '(0 8 9)) + (setq do-clear t) + (aset basic-faces new t))) + (2 (if (memq new '(20 26 28 29)) + (setq do-clear t) + ;; The standard says `21 doubly underlined' while + ;; https://en.wikipedia.org/wiki/ANSI_escape_code claims + ;; `21 Bright/Bold: off or Underline: Double'. + (aset basic-faces (- new 20) nil) + (aset basic-faces (pcase new (22 1) (25 6) (_ 0)) nil))) + ((or 3 4 9 10) + (let ((r (mod new 10)) + (cell (if (memq q '(3 9)) colors (cdr colors)))) + (pcase r + (8 (setq do-clear t)) + (9 (setcar cell nil)) + (_ (setcar cell (+ (if (memq q '(3 4)) 0 8) r)))))) + (_ (setq do-clear t))) + + (when do-clear + (setq do-clear nil) + ;; Zero out our bool vector without any allocation + (bool-vector-intersection basic-faces #&8"\0" basic-faces) + (setcar colors nil) + (setcar (cdr colors) nil))))) + (defun ansi-color-make-color-map () "Create a vector of face definitions and return it. =20 @@ -859,6 +983,7 @@ ansi-color-get-face-1 "Get face definition for ANSI-CODE. BRIGHT, if non-nil, requests \"bright\" ANSI colors, even if ANSI-CODE is a normal-intensity color." + (declare (obsolete ansi-color--face-vec-face "28.1")) (when (and bright (<=3D 30 ansi-code 49)) (setq ansi-code (+ ansi-code 60))) (cond ((<=3D 0 ansi-code 7) =2D-=20 2.33.0 --=-=-=-- --==-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQJHBAEBCAAxFiEEmxVnesoT5rQXvVXnswkaGpIVmT8FAmFZ2vsTHG1paGFAa2Ft bml0bmlrLnRvcAAKCRCzCRoakhWZP4QcD/96olJLR+4qlj5aeRSTEfqu2RaoiT30 VDm6hcK902DZ6GEB5ty8pPwzoL3cSJuGKBhgETfayHGE+OEGQfZ08i9XSnPdC8ZW m+gUqnEiYz006W5g628mI9K2WFjzeh1TugZ6ARQHxMR+9eFzpySQ22Gx6aeLfih1 oHQqZz1RTrlAQsYSK/cACJzxAJtJyMija2H2/SmZQUw5WffLoLEomKsHNTnU8Wcy FPIztbjDVPiPiFj16/LYphaqyOX1f3WUmnuAOF58FR0mO+Gjp5FvWzkcpsm8DTV+ WwYIQBZgT8uS3w0ChnkEkI5Wxg0qmdBfFWDeA53y/7yY3vHVJ5AOKyzhC2d6V6L1 AbNJgHKwNA1Dj0Z7QCtfsPVbMmg1JShC1CnwlO7Fu8fjCvnvqpWfxf/x6kR+PBvt oiOWM6BLcyhymjCur4tr6ON4FXSvDHAWO+8c3wDt08JT+lgoV4tKRROUWyOmUu49 Es9rZzS1aMH8Qom5eIhPCwkh8CcmTVOo806WD/8TYWhBKDJTSzPKxaGNUZVkN1Ak oTib1mT4o3QBOKAGJl28qPnjrSVv1tH3dNQ0tgF4c8RhUnXMAxDRrAQ1wgkVOqs+ wmvlYplneNKe7jKwgiaiZ2D4yVe0QpmEzFDd7ftXagpwXwWslsaKY7dsZmV1P+79 eGfOlg4OnUV6CQ== =c7YM -----END PGP SIGNATURE----- --==-=-=-- From unknown Wed Aug 20 03:37:10 2025 X-Loop: help-debbugs@gnu.org Subject: bug#50806: 27.2; [PATCH] Optimize ansi-color.el Resent-From: Jim Porter Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 03 Oct 2021 17:54:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 50806 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: miha@kamnitnik.top, 50806@debbugs.gnu.org Cc: Lars Ingebrigtsen Received: via spool by 50806-submit@debbugs.gnu.org id=B50806.163328361124641 (code B ref 50806); Sun, 03 Oct 2021 17:54:01 +0000 Received: (at 50806) by debbugs.gnu.org; 3 Oct 2021 17:53:31 +0000 Received: from localhost ([127.0.0.1]:34884 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mX5g3-0006PN-8A for submit@debbugs.gnu.org; Sun, 03 Oct 2021 13:53:31 -0400 Received: from mail-pg1-f171.google.com ([209.85.215.171]:40659) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mX5fz-0006P8-No for 50806@debbugs.gnu.org; Sun, 03 Oct 2021 13:53:29 -0400 Received: by mail-pg1-f171.google.com with SMTP id h3so3775192pgb.7 for <50806@debbugs.gnu.org>; Sun, 03 Oct 2021 10:53:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=subject:to:references:from:cc:message-id:date:mime-version :in-reply-to:content-language:content-transfer-encoding; bh=XeJCPsLjF/9ipt+KG41SlYtsVFf10DAkOSbq0VrjEC8=; b=ejRPUepBHbUrVgVTC+Yr2/ArxzkiezPYri5PZZhEloI66E8KuxdAr8sJui+Er0qNG2 RfOmefGWypWj25Uq8N6MUfocb/kfCExn/kq6jiKg8OVzfW8K26K+uTzTFrjV6pfMRHHM IcKgPlLl3ePC0CxHVVzZ67skEhoJKil1mJCR5o4NR+JzLzGP5knL/3dKe/+UkHOF4YzS 3acdl03Z6BLA1a/eQRS6ZId28XcfUEgH48zTNFjm+UXvjgsqptsxSFdmPP7hhyWh1FrC 992XqGMny0MVlxeIh35HlIqtGfrX3UeFUWTj/K0Xb0LmJHUHOuI/MMjBHzZQP7plxGhT he3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:subject:to:references:from:cc:message-id:date :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=XeJCPsLjF/9ipt+KG41SlYtsVFf10DAkOSbq0VrjEC8=; b=jgPjZShzzSfDQXmHGimLlFUYOgQyGmcsdhYoagHva5mF/BDkyb8AEdxRd44LQM+Pen qIW0GbbwVjDMcIhnZRGe5tdD6Pk7PZ0QTwyxCAR4J9biuW7pBrOrjaNpbB1DHcPXpGTm +70T3007FCGCXdRZvRXoJYV5kXjasSdgCzGE+8ZMdMOIxlK/8Sbrc0yO4TLQryDrxHVI qItUVgVT8av3Vi9skdF3YiO8TSBZHydnHAff1B/0Fyjhb0fFtrOQPrPK8SXCpFVPA1UZ 7ovPcyg1H4gqKPoBzI5L3rjFLLtmsM1kVmMebBZKkk5H3Hwr7+ailyzQI7gAX/1589cY Rq6g== X-Gm-Message-State: AOAM532kIGbVP5eZQsnyex0mb9rr7VbSnni39QEKXK1lAdWfCNf0jsxF dfYuroiNizQ7fweNJr92Hjs= X-Google-Smtp-Source: ABdhPJzwyeGepcGBg2Otes17eSXo8yoONoUnd82ZdL+lGFtDPrWmf10Rj+/ubEiHYr/bvhqNpXFqJw== X-Received: by 2002:a63:7405:: with SMTP id p5mr7434529pgc.426.1633283601834; Sun, 03 Oct 2021 10:53:21 -0700 (PDT) Received: from [192.168.1.2] (cpe-76-168-148-233.socal.res.rr.com. [76.168.148.233]) by smtp.googlemail.com with ESMTPSA id u12sm13351714pjr.2.2021.10.03.10.53.20 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 03 Oct 2021 10:53:21 -0700 (PDT) References: <87tui8wakb.fsf@miha-pc> From: Jim Porter Message-ID: <25ed8125-3f78-c9c9-9324-d75e48e702c6@gmail.com> Date: Sun, 3 Oct 2021 10:53:20 -0700 MIME-Version: 1.0 In-Reply-To: <87tui8wakb.fsf@miha-pc> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) (Apologies for the delay in replying; the original message hit my spam filter, and I only saw the followup. CC'ing Lars, who reviewed my patches and can hopefully provide a more-helpful review than me with my shaky Lisp skills.) On 9/25/2021 3:32 PM, miha--- via Bug reports for GNU Emacs, the Swiss army knife of text editors wrote: > Attached patch speeds up ansi-color. It tries to eliminate as many > allocations (cons and list) as possible. > > Benchmarks, recorded in emacs -q, are in the second attachments. With > the patch applied, there is a 26% speedup in elapsed time, mostly > because the garbage collector has to take care of less allocations. Sounds good to me. I did some very light benchmarking on my patches, but only to make sure I didn't make things too much slower (hopefully I succeeded). Making it faster would definitely be nice. > Two less important side notes: > > 1) This patch additionally makes it very straight forward to add support > for ANSI color codes 38 and 48 allowing 256-colors and 24bit > full-color. I plan to submit such a patch later (for both ansi-color > and term-mode). Glad to hear it! I was planning on doing this for Emacs 29, but if you've already got something in mind for this, feel free to work on it. Another thing that might be worth looking at would be improving term.el's support for "basic" ANSI escapes; I think it only does bold, underline, and inverse. Also, the inverse implementation seems a bit over-complicated when it could just use the :inverse-video face attribute instead. > 2) Two vector variables, that were recently added by Jim, were merged > into one. Adding him as CC. I see you posted an updated patch that doesn't merge these vectors. I don't have an opinion here, although if we do merge them, it would probably be nice to get that into Emacs 28; other packages might conceivably want to let-bind those[1]. [1] See man.el, which let-binds `ansi-color-basic-faces-vector' in `Man-fontify-manpage'. That's for the basic faces, not the colors, but the same idea should apply. From unknown Wed Aug 20 03:37:10 2025 X-Loop: help-debbugs@gnu.org Subject: bug#50806: 27.2; [PATCH] Optimize ansi-color.el Resent-From: Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 03 Oct 2021 19:51:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 50806 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Jim Porter , 50806@debbugs.gnu.org Cc: Lars Ingebrigtsen Received: via spool by 50806-submit@debbugs.gnu.org id=B50806.16332906413771 (code B ref 50806); Sun, 03 Oct 2021 19:51:02 +0000 Received: (at 50806) by debbugs.gnu.org; 3 Oct 2021 19:50:41 +0000 Received: from localhost ([127.0.0.1]:35022 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mX7VP-0000yj-Sr for submit@debbugs.gnu.org; Sun, 03 Oct 2021 15:50:41 -0400 Received: from kamnitnik.top ([209.250.245.214]:38786) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mX7VL-0000yZ-P2 for 50806@debbugs.gnu.org; Sun, 03 Oct 2021 15:50:39 -0400 Received: from localhost (BSN-77-156-43.static.siol.net [193.77.156.43]) by kamnitnik.top (Postfix) with ESMTPSA id 79CFC9C707; Sun, 3 Oct 2021 19:50:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kamnitnik.top; s=mail; t=1633290634; bh=jLpkfjs/UaQv6rKAwwAjFLIjcNjY8KjoM98HjWExvIg=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From; b=Jg7XcEBjfT9t5w1o688v4n2QX8GVVg3ApEo2VJYr3Y5tYlEiJ2i5tKwMeSzinxY24 IF39uS2jTb9qZZY9CX5Jtlpxy4HvyqmO0F9jnxHEk9yhQhTrbTsXbHzHoI3CbWSRbz SY+Zffmi3ndL3WODGyoxqKxdAg88GPXD84WhQe7ptyBBI/L4eBoGgim4YT1ui9VKSI gBcBuipVAWypp05wYoDTK6I2kX94gDvYuljYjhKeQJOvCewPzLJMkeZQdb6zKtF3Pi a3YNfOYQnV3tcddAaJRgxfXXrx1xdm4oTTaTDP9j/cMMok6DpZwzL1DiurgbzL/QJ0 MnzYkPnMZaDBg== From: In-Reply-To: <25ed8125-3f78-c9c9-9324-d75e48e702c6@gmail.com> References: <87tui8wakb.fsf@miha-pc> <25ed8125-3f78-c9c9-9324-d75e48e702c6@gmail.com> Date: Sun, 03 Oct 2021 21:54:06 +0200 Message-ID: <87k0itc2ap.fsf@miha-pc> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="==-=-="; micalg=pgp-sha256; protocol="application/pgp-signature" X-Spam-Score: 2.5 (++) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: >> Two less important side notes: >> >> 1) This patch additionally makes it very straight forward to add support >> for ANSI color codes 38 and 48 allowing 256-colors and 24bit >> full-color. I plan t [...] Content analysis details: (2.5 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 2.0 PDS_OTHER_BAD_TLD Untrustworthy TLDs [URI: kamnitnik.top (top)] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record 0.5 FROM_SUSPICIOUS_NTLD From abused NTLD X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 2.5 (++) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: >> Two less important side notes: >> >> 1) This patch additionally makes it very straight forward to add support >> for ANSI color codes 38 and 48 allowing 256-colors and 24bit >> full-color. I plan t [...] Content analysis details: (2.5 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 2.0 PDS_OTHER_BAD_TLD Untrustworthy TLDs [URI: kamnitnik.top (top)] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record 0.5 FROM_SUSPICIOUS_NTLD From abused NTLD 1.0 BULK_RE_SUSP_NTLD Precedence bulk and RE: from a suspicious TLD -1.0 MAILING_LIST_MULTI Multiple indicators imply a widely-seen list manager --==-=-= Content-Type: multipart/mixed; boundary="=-=-=" --=-=-= Content-Type: text/plain Content-Transfer-Encoding: quoted-printable >> Two less important side notes: >>=20 >> 1) This patch additionally makes it very straight forward to add support >> for ANSI color codes 38 and 48 allowing 256-colors and 24bit >> full-color. I plan to submit such a patch later (for both ansi-color >> and term-mode). > > Glad to hear it! I was planning on doing this for Emacs 29, but if > you've already got something in mind for this, feel free to work on > it. Another thing that might be worth looking at would be improving > term.el's support for "basic" ANSI escapes; I think it only does bold, > underline, and inverse. Also, the inverse implementation seems a bit > over-complicated when it could just use the :inverse-video face > attribute instead. > Ok, thanks. I have actually already prepared patches for all these features: full-color in ansi-color.el and term.el and also "basic" ANSI escapes 1-8 for term.el that you mentioned. I guess there's no harm in sending them right now. >> 2) Two vector variables, that were recently added by Jim, were merged >> into one. Adding him as CC. > > I see you posted an updated patch that doesn't merge these vectors. I=20 > don't have an opinion here, although if we do merge them, it would=20 > probably be nice to get that into Emacs 28; other packages might=20 > conceivably want to let-bind those[1]. Indeed, if we wanted to merge them we'd have to do it in Emacs 28. That's why I think its best to simply leave them un-merged. Thanks and best regards. --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0002-Add-support-for-256-color-and-24bit-ANSI-colors-in-a.patch Content-Transfer-Encoding: quoted-printable From=20cc7c1a4888b6e4dfda3a370ce357d0029b6448cc Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?Miha=3D20Rihtar=3DC5=3DA1i=3DC4=3D8D?=3D Date: Sat, 2 Oct 2021 23:13:21 +0200 Subject: [PATCH 2/4] Add support for 256-color and 24bit ANSI colors in ansi-color * lisp/ansi-color.el (ansi-color--code-as-hex): New function to convert from 256-color and 24-bit ANSI codes. (ansi-color--face-vec-face): Add support for ANSI color codes greater than 16 (ansi-color--update-face-vec): Add support for ANSI codes 38 and 48 which can specify 256-color and 24bit ANSI colors. * test/lisp/ansi-color-tests.el (ansi-color-tests--strings): Add tests for ANSI codes 38 and 34 =2D-- etc/NEWS | 7 ++++ lisp/ansi-color.el | 70 ++++++++++++++++++++++++++++------- test/lisp/ansi-color-tests.el | 12 +++++- 3 files changed, 74 insertions(+), 15 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 8c22230daf..e862b77563 100644 =2D-- a/etc/NEWS +++ b/etc/NEWS @@ -65,6 +65,13 @@ binding in the menu. ** subr-x *** New macro 'with-memoization' provides a very primitive form of memoiza= tion =20 +** ansi-color.el + +--- +*** Support for ANSI 256-color and 24-bit colors. +256-color and 24-bit color codes are now handled by ANSI color +filters and displayed with the specified color. + * New Modes and Packages in Emacs 29.1 =20 diff --git a/lisp/ansi-color.el b/lisp/ansi-color.el index 7b46754d83..8d394f353b 100644 =2D-- a/lisp/ansi-color.el +++ b/lisp/ansi-color.el @@ -594,22 +594,24 @@ ansi-color--face-vec-face (when-let ((fg (car colors))) (push `(:foreground =2D ,(face-foreground =2D (aref (if (or bright (>=3D fg 8)) =2D ansi-color-bright-colors-vector =2D ansi-color-normal-colors-vector) =2D (mod fg 8)) =2D nil 'default)) + ,(or (ansi-color--code-as-hex fg) + (face-foreground + (aref (if (or bright (>=3D fg 8)) + ansi-color-bright-colors-vector + ansi-color-normal-colors-vector) + (mod fg 8)) + nil 'default))) faces)) (when-let ((bg (cadr colors))) (push `(:background =2D ,(face-background =2D (aref (if (or bright (>=3D bg 8)) =2D ansi-color-bright-colors-vector =2D ansi-color-normal-colors-vector) =2D (mod bg 8)) =2D nil 'default)) + ,(or (ansi-color--code-as-hex bg) + (face-background + (aref (if (or bright (>=3D bg 8)) + ansi-color-bright-colors-vector + ansi-color-normal-colors-vector) + (mod bg 8)) + nil 'default))) faces)) =20 (let ((i 8)) @@ -622,6 +624,32 @@ ansi-color--face-vec-face faces (car faces)))) =20 +(defun ansi-color--code-as-hex (color) + "Convert COLOR to hexadecimal string representation. +COLOR is an ANSI color code. If it is between 16 and 255 +inclusive, it corresponds to a color from an 8-bit color cube. +If it is greater or equal than 256, it is subtracted by 256 to +directly specify a 24-bit color. + +Return a hexadecimal string, specifying the color, or nil, if +COLOR is less than 16." + (cond + ((< color 16) nil) + ((>=3D color 256) (format "#%06X" (- color 256))) + ((>=3D color 232) ;; Grayscale + (format "#%06X" (* #x010101 (+ 8 (* 10 (- color 232)))))) + (t ;; 6x6x6 color cube + (setq color (- color 16)) + (let ((res 0) + (frac (* 6 6))) + (while (<=3D 1 frac) ; Repeat 3 times + (setq res (* res #x000100)) + (let ((color-num (mod (/ color frac) 6))) + (unless (zerop color-num) + (setq res (+ res #x37 (* #x28 color-num))))) + (setq frac (/ frac 6))) + (format "#%06X" res))))) + ;; Working with regions =20 (defvar-local ansi-color-context-region nil @@ -907,7 +935,23 @@ ansi-color--update-face-vec (let ((r (mod new 10)) (cell (if (memq q '(3 9)) colors (cdr colors)))) (pcase r =2D (8 (setq do-clear t)) + (8 + (pcase (funcall iterator) + (5 (setq new (setcar cell (funcall iterator))) + (setq do-clear (or (null new) (>=3D new 256)))) + (2 + (let ((red (funcall iterator)) + (green (funcall iterator)) + (blue (funcall iterator))) + (if (and red green blue + (progn + (setq new (+ (* #x010000 red) + (* #x000100 green) + (* #x000001 blue))) + (<=3D new #xFFFFFF))) + (setcar cell (+ 256 new)) + (setq do-clear t)))) + (_ (setq do-clear t)))) (9 (setcar cell nil)) (_ (setcar cell (+ (if (memq q '(3 4)) 0 8) r)))))) (_ (setq do-clear t))) diff --git a/test/lisp/ansi-color-tests.el b/test/lisp/ansi-color-tests.el index 953fdff893..16a1ba4a89 100644 =2D-- a/test/lisp/ansi-color-tests.el +++ b/test/lisp/ansi-color-tests.el @@ -27,7 +27,8 @@ =20 (defvar ansi-color-tests--strings (let ((bright-yellow (face-foreground 'ansi-color-bright-yellow nil 'def= ault)) =2D (yellow (face-foreground 'ansi-color-yellow nil 'default))) + (yellow (face-foreground 'ansi-color-yellow nil 'default)) + (custom-color "#87FFFF")) `(("Hello World" "Hello World") ("\e[33mHello World\e[0m" "Hello World" (:foreground ,yellow)) @@ -51,7 +52,14 @@ ansi-color-tests--strings (ansi-color-bold (:foreground ,bright-yellow))) ("\e[1m\e[3m\e[5mbold italics blink\e[0m" "bold italics blink" (ansi-color-bold ansi-color-italic ansi-color-slow-blink)) =2D ("\e[10munrecognized\e[0m" "unrecognized")))) + ("\e[10munrecognized\e[0m" "unrecognized") + ("\e[38;5;3;1mHello World\e[0m" "Hello World" + (ansi-color-bold (:foreground ,yellow)) + (ansi-color-bold (:foreground ,bright-yellow))) + ("\e[48;5;123;1mHello World\e[0m" "Hello World" + (ansi-color-bold (:background ,custom-color))) + ("\e[48;2;135;255;255;1mHello World\e[0m" "Hello World" + (ansi-color-bold (:background ,custom-color)))))) =20 (ert-deftest ansi-color-apply-on-region-test () (pcase-dolist (`(,input ,text ,face) ansi-color-tests--strings) =2D-=20 2.33.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0003-Add-support-for-256-color-and-24bit-ANSI-colors-in-t.patch Content-Transfer-Encoding: quoted-printable From=20ad667c79926f28c5e82654c9f99dc23f41e9375e Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?Miha=3D20Rihtar=3DC5=3DA1i=3DC4=3D8D?=3D Date: Sat, 25 Sep 2021 23:28:08 +0200 Subject: [PATCH 3/4] Add support for 256-color and 24bit ANSI colors in term-mode (term-ansi-face-already-done): Make obsolete (term--maybe-brighten-color): Remove (term--color-as-hex): New function (term-handle-colors-array): Make obsolete in favour of the new function 'term--handle-colors-list'. (term--handle-colors-list): New function, that can also handle ANSI codes 38 and 48. (term-handle-ansi-escape): Use it * test/lisp/term-tests.el (ansi-test-strings): Add tests for 256-color and 24bit ANSI colors =2D-- etc/NEWS | 7 ++ etc/e/README | 18 +-- etc/e/eterm-color | Bin 1179 -> 1275 bytes etc/e/eterm-color.ti | 15 ++- etc/e/eterm-direct | Bin 0 -> 1354 bytes lisp/term.el | 249 +++++++++++++++++++--------------------- test/lisp/term-tests.el | 16 ++- 7 files changed, 163 insertions(+), 142 deletions(-) create mode 100644 etc/e/eterm-direct diff --git a/etc/NEWS b/etc/NEWS index e862b77563..e22eac5e75 100644 =2D-- a/etc/NEWS +++ b/etc/NEWS @@ -72,6 +72,13 @@ binding in the menu. 256-color and 24-bit color codes are now handled by ANSI color filters and displayed with the specified color. =20 +** term-mode + +--- +*** Support for ANSI 256-color and 24-bit colors. +256-color and 24-bit color codes are now displayed with the specified +color. + * New Modes and Packages in Emacs 29.1 =20 diff --git a/etc/e/README b/etc/e/README index dd2c8d64e2..1293292a87 100644 =2D-- a/etc/e/README +++ b/etc/e/README @@ -1,12 +1,12 @@ =2Determ-color.ti is a terminfo source file. eterm-color is a compiled =2Dversion produced by the terminfo compiler (tic). The compiled files =2Dare binary, and depend on the version of tic, but they seem to be =2Dsystem-independent and backwardly compatible. So there should be no =2Dneed to recompile the distributed binary version. If it is =2Dnecessary, use: +eterm-color.ti is a terminfo source file. eterm-color and +eterm-direct are compiled versions produced by the terminfo compiler +(tic). The compiled files are binary, and depend on the version of +tic, but they seem to be system-independent and backwardly compatible. +So there should be no need to recompile the distributed binary +version. If it is necessary, use: =20 tic -o ../ ./eterm-color.ti =20 =2DThe compiled file is used by lisp/term.el, so if it is moved term.el =2Dneeds to be changed. terminfo requires it to be stored in an 'e' =2Dsubdirectory (the first character of the file name). +The compiled files are used by lisp/term.el, so if they are moved, +term.el needs to be changed. terminfo requires them to be stored in +an 'e' subdirectory (the first character of the file name). diff --git a/etc/e/eterm-color b/etc/e/eterm-color index bd3f5003ae620db49b89a2c1387b0ba1c836f4f1..99603ba5613b822d9916df63b7c= 1fcc6833a038d 100644 GIT binary patch delta 160 zcmbQu`J0nliqV~c9|$uUS5D+EWMN?ZU%#>80uy8A=3D0IjW#u|Io0z=3Dhmi&|A1)e>V6 tJ4H1WEM#Z~7PExO>w;vAEv!wgA*!r%8Kk3Ck+qv((QasfqTd8XKLBEMDcJx3 delta 64 zcmey(Ih&JPiqV~c9|$uUJtuM(vT!gsFl=3DnNz{F^^IgnY8QKrC9wc6OAR#jUyC6_@u MS{2Aw*HDLW0nn2UQ~&?~ diff --git a/etc/e/eterm-color.ti b/etc/e/eterm-color.ti index a6ef814990..61c29e6dcc 100644 =2D-- a/etc/e/eterm-color.ti +++ b/etc/e/eterm-color.ti @@ -9,10 +9,10 @@ eterm-color|Emacs term.el terminal emulator term-protocol= -version 0.96, # Any change to this file should be done at the same time with a # corresponding change to the TERMCAP environment variable in term.el. # Comments in term.el specify where each of these capabilities is implemen= ted. =2D colors#8, + colors#256, cols#80, lines#24, =2D pairs#64, + pairs#32767, am, mir, msgr, @@ -65,8 +65,8 @@ eterm-color|Emacs term.el terminal emulator term-protocol= -version 0.96, rmul=3D\E[24m, rs1=3D\Ec, sc=3D\E7, =2D setab=3D\E[%p1%{40}%+%dm, =2D setaf=3D\E[%p1%{30}%+%dm, + setab=3D\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, + setaf=3D\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, sgr0=3D\E[m, smir=3D\E[4h, smul=3D\E[4m, @@ -76,3 +76,10 @@ eterm-color|Emacs term.el terminal emulator term-protoco= l-version 0.96, # smcup=3D\E[?47h, # rmcup=3D\E[?47l, # rs2 may need to be added + +eterm-direct|Emacs term.el with direct-color indexing term-protocol-versio= n 0.96, + use=3Determ-color, + colors#0x1000000, + pairs#0x10000, + setab=3D\E[%?%p1%{8}%<%t4%p1%d%e48;2;%p1%{65536}%/%d;%p1%{256}%/%{255}%&%= d;%p1%{255}%&%d%;m, + setaf=3D\E[%?%p1%{8}%<%t3%p1%d%e38;2;%p1%{65536}%/%d;%p1%{256}%/%{255}%&%= d;%p1%{255}%&%d%;m, diff --git a/etc/e/eterm-direct b/etc/e/eterm-direct new file mode 100644 index 0000000000000000000000000000000000000000..35983ec8aded7b0c6b818df47ab= e57b9440934cb GIT binary patch literal 1354 zcmcgoJ!lkB5T18LqCpW0LD(QG_$&e!z5Tm8HbJ8aM9q!MenQy-Nd-Kj0?$Bv`k=3Dj;a8YZn` z5G7$FeLT}zYOI*djE7BgHA+7Be9*h%6vMxgj8Oje?}ZC)9# zdPGWolB3iDY=3D(0#w~YUGkSa~GjHp0Es6R`iWJ;flP7jF`J3Nk}C#plko94*pa zpnJ4L_l0>VI;ND?^Nhhgo`HFuvoBy@?#meDX4xxxjrb&_~*$ zPsrS%&-4ZM>u*)xa(@?g5ARS=3Dy~<;`{rMgT#luIaJ?M=3D8n|Jb%8=3DX<3QgPvsb^mg! zG1XPWbc&3+j&!G_17CM69V8%TjruK^+Yq+D#Aj)QGw3+<4agK^0aAmMT2Rh1RE1Ib zhjJK6unAyEz!Gwfo`SKTkTHK9paf92*qa9M*mK##q#JP7QR(Ulo!Zh#hjzuc keBnLUwY{#sEboXs%M}mS?dnSdw&!VoUrQ%%=3D^UZucQ(5!9smFU literal 0 HcmV?d00001 diff --git a/lisp/term.el b/lisp/term.el index e76eb77647..771b73238f 100644 =2D-- a/lisp/term.el +++ b/lisp/term.el @@ -303,6 +303,7 @@ term-protocol-version (require 'ange-ftp) (require 'cl-lib)) (require 'comint) ; Password regexp. +(require 'ansi-color) (require 'ehelp) (require 'ring) (require 'shell) @@ -717,6 +718,9 @@ term-ansi-current-underline (defvar term-ansi-current-reverse nil) (defvar term-ansi-current-invisible nil) =20 +(make-obsolete-variable 'term-ansi-face-already-done + "it doesn't have any effect." "28.1") + ;;; Faces (defvar ansi-term-color-vector [term @@ -1039,10 +1043,6 @@ term-ansi-reset (setq term-ansi-current-reverse nil) (setq term-ansi-current-color 0) (setq term-ansi-current-invisible nil) =2D ;; Stefan thought this should be t, but could not remember why. =2D ;; Setting it to t seems to cause bug#11785. Setting it to nil =2D ;; again to see if there are other consequences... =2D (setq term-ansi-face-already-done nil) (setq term-ansi-current-bg-color 0)) =20 (define-derived-mode term-mode fundamental-mode "Term" @@ -1584,7 +1584,8 @@ term-termcap-format :so=3D\\E[7m:se=3D\\E[m:us=3D\\E[4m:ue=3D\\E[m:md=3D\\E[1m:mr=3D\\E[7m:me= =3D\\E[m\ :UP=3D\\E[%%dA:DO=3D\\E[%%dB:LE=3D\\E[%%dD:RI=3D\\E[%%dC\ :kl=3D\\EOD:kd=3D\\EOB:kr=3D\\EOC:ku=3D\\EOA:kN=3D\\E[6~:kP=3D\\E[5~:@7=3D= \\E[4~:kh=3D\\E[1~\ =2D:mk=3D\\E[8m:cb=3D\\E[1K:op=3D\\E[39;49m:Co#8:pa#64:AB=3D\\E[4%%dm:AF=3D= \\E[3%%dm:cr=3D^M\ +:mk=3D\\E[8m:cb=3D\\E[1K:op=3D\\E[39;49m:Co#256:pa#32767\ +:AB=3D\\E[48;5;%%dm:AF=3D\\E[38;5;%%dm:cr=3D^M\ :bl=3D^G:do=3D^J:le=3D^H:ta=3D^I:se=3D\\E[27m:ue=3D\\E[24m\ :kb=3D^?:kD=3D^[[3~:sc=3D\\E7:rc=3D\\E8:r1=3D\\Ec:" ;; : -undefine ic @@ -3285,133 +3286,125 @@ term-reset-terminal (setq term-current-row 0) (setq term-current-column 1) (term--reset-scroll-region) =2D (setq term-insert-mode nil) =2D ;; FIXME: No idea why this is here, it looks wrong. --Stef =2D (setq term-ansi-face-already-done nil)) =2D =2D(defun term--maybe-brighten-color (color bold) =2D "Possibly convert COLOR to its bright variant. =2DCOLOR is an index into `ansi-term-color-vector'. If BOLD and =2D`ansi-color-bold-is-bright' are non-nil and COLOR is a regular color, =2Dreturn the bright version of COLOR; otherwise, return COLOR." =2D (if (and ansi-color-bold-is-bright bold (<=3D 1 color 8)) =2D (+ color 8) =2D color)) + (setq term-insert-mode nil)) + +(defun term--color-as-hex (for-foreground) + "Return the current ANSI color as a hexadecimal color string. +Use the current background color if FOR-FOREGROUND is nil, +otherwise use the current foreground color." + (let ((color (if for-foreground term-ansi-current-color + term-ansi-current-bg-color))) + (or (ansi-color--code-as-hex (1- color)) + (progn + (and ansi-color-bold-is-bright term-ansi-current-bold + (<=3D 1 color 8) + (setq color (+ color 8))) + (if for-foreground + (face-foreground (elt ansi-term-color-vector color) + nil 'default) + (face-background (elt ansi-term-color-vector color) + nil 'default)))))) =20 ;; New function to deal with ansi colorized output, as you can see you can ;; have any bold/underline/fg/bg/reverse combination. -mm =20 (defun term-handle-colors-array (parameter) =2D (cond =2D =2D ;; Bold (terminfo: bold) =2D ((eq parameter 1) =2D (setq term-ansi-current-bold t)) =2D =2D ;; Underline =2D ((eq parameter 4) =2D (setq term-ansi-current-underline t)) =2D =2D ;; Blink (unsupported by Emacs), will be translated to bold. =2D ;; This may change in the future though. =2D ((eq parameter 5) =2D (setq term-ansi-current-bold t)) =2D =2D ;; Reverse (terminfo: smso) =2D ((eq parameter 7) =2D (setq term-ansi-current-reverse t)) =2D =2D ;; Invisible =2D ((eq parameter 8) =2D (setq term-ansi-current-invisible t)) =2D =2D ;; Reset underline (terminfo: rmul) =2D ((eq parameter 24) =2D (setq term-ansi-current-underline nil)) =2D =2D ;; Reset reverse (terminfo: rmso) =2D ((eq parameter 27) =2D (setq term-ansi-current-reverse nil)) =2D =2D ;; Foreground =2D ((and (>=3D parameter 30) (<=3D parameter 37)) =2D (setq term-ansi-current-color (- parameter 29))) =2D =2D ;; Bright foreground =2D ((and (>=3D parameter 90) (<=3D parameter 97)) =2D (setq term-ansi-current-color (- parameter 81))) =2D =2D ;; Reset foreground =2D ((eq parameter 39) =2D (setq term-ansi-current-color 0)) =2D =2D ;; Background =2D ((and (>=3D parameter 40) (<=3D parameter 47)) =2D (setq term-ansi-current-bg-color (- parameter 39))) =2D =2D ;; Bright foreground =2D ((and (>=3D parameter 100) (<=3D parameter 107)) =2D (setq term-ansi-current-bg-color (- parameter 91))) =2D =2D ;; Reset background =2D ((eq parameter 49) =2D (setq term-ansi-current-bg-color 0)) =2D =2D ;; 0 (Reset) or unknown (reset anyway) =2D (t =2D (term-ansi-reset))) =2D =2D ;; (message "Debug: U-%d R-%d B-%d I-%d D-%d F-%d B-%d" =2D ;; term-ansi-current-underline =2D ;; term-ansi-current-reverse =2D ;; term-ansi-current-bold =2D ;; term-ansi-current-invisible =2D ;; term-ansi-face-already-done =2D ;; term-ansi-current-color =2D ;; term-ansi-current-bg-color) =2D =2D (unless term-ansi-face-already-done =2D (let ((current-color (term--maybe-brighten-color =2D term-ansi-current-color =2D term-ansi-current-bold)) =2D (current-bg-color (term--maybe-brighten-color =2D term-ansi-current-bg-color =2D term-ansi-current-bold))) =2D (if term-ansi-current-invisible =2D (let ((color =2D (if term-ansi-current-reverse =2D (face-foreground =2D (elt ansi-term-color-vector current-color) =2D nil 'default) =2D (face-background =2D (elt ansi-term-color-vector current-bg-color) =2D nil 'default)))) =2D (setq term-current-face =2D (list :background color =2D :foreground color)) =2D ) ;; No need to bother with anything else if it's invisible. =2D (setq term-current-face =2D (list :foreground =2D (face-foreground =2D (elt ansi-term-color-vector current-color) =2D nil 'default) =2D :background =2D (face-background =2D (elt ansi-term-color-vector current-bg-color) =2D nil 'default) =2D :inverse-video term-ansi-current-reverse)) =2D =2D (when term-ansi-current-bold =2D (setq term-current-face =2D `(,term-current-face :inherit term-bold))) =2D =2D (when term-ansi-current-underline =2D (setq term-current-face =2D `(,term-current-face :inherit term-underline)))))) =2D =2D ;; (message "Debug %S" term-current-face) =2D ;; FIXME: shouldn't we set term-ansi-face-already-done to t here? --S= tef =2D (setq term-ansi-face-already-done nil)) + (declare (obsolete term--handle-colors-list "28.1")) + (term--handle-colors-list (list parameter))) + +(defun term--handle-colors-list (parameters) + (while parameters + (pcase (pop parameters) + (1 (setq term-ansi-current-bold t)) ; (terminfo: bold) + (4 (setq term-ansi-current-underline t)) ; (terminfo: smul) + (5 (setq term-ansi-current-bold t)) ; (terminfo: bold) + (7 (setq term-ansi-current-reverse t)) ; (terminfo: smso, rev) + (8 (setq term-ansi-current-invisible t)) ; (terminfo: invis) + (24 (setq term-ansi-current-underline nil)) ; (terminfo: rmul) + (27 (setq term-ansi-current-reverse nil)) ; (terminfo: rmso) + + ;; Foreground (terminfo: setaf) + ((and param (guard (<=3D 30 param 37))) + (setq term-ansi-current-color (- param 29))) + + ;; Bright foreground (terminfo: setaf) + ((and param (guard (<=3D 90 param 97))) + (setq term-ansi-current-color (- param 81))) + + ;; Extended foreground (terminfo: setaf) + (38 + (pcase (pop parameters) + ;; 256 color + (5 (if (setq term-ansi-current-color (pop parameters)) + (cl-incf term-ansi-current-color) + (term-ansi-reset))) + ;; Full 24-bit color + (2 (cl-loop with color =3D (1+ 256) ; Base + for i from 16 downto 0 by 8 + if (pop parameters) + do (setq color (+ color (ash it i))) + else return (term-ansi-reset) + finally + (if (> color (+ 1 256 #xFFFFFF)) + (term-ansi-reset) + (setq term-ansi-current-color color)))) + (_ (term-ansi-reset)))) + + ;; Reset foreground (terminfo: op) + (39 (setq term-ansi-current-color 0)) + + ;; Background (terminfo: setab) + ((and param (guard (<=3D 40 param 47))) + (setq term-ansi-current-bg-color (- param 39))) + + ;; Bright background (terminfo: setab) + ((and param (guard (<=3D 100 param 107))) + (setq term-ansi-current-bg-color (- param 91))) + + ;; Extended background (terminfo: setab) + (48 + (pcase (pop parameters) + ;; 256 color + (5 (if (setq term-ansi-current-bg-color (pop parameters)) + (cl-incf term-ansi-current-bg-color) + (term-ansi-reset))) + ;; Full 24-bit color + (2 (cl-loop with color =3D (1+ 256) ; Base + for i from 16 downto 0 by 8 + if (pop parameters) + do (setq color (+ color (ash it i))) + else return (term-ansi-reset) + finally + (if (> color (+ 1 256 #xFFFFFF)) + (term-ansi-reset) + (setq term-ansi-current-bg-color color)))) + (_ (term-ansi-reset)))) + + ;; Reset background (terminfo: op) + (49 (setq term-ansi-current-bg-color 0)) + + ;; 0 (Reset) (terminfo: sgr0) or unknown (reset anyway) + (_ (term-ansi-reset)))) + + (let (fg bg) + (if term-ansi-current-invisible + (setq bg (term--color-as-hex term-ansi-current-reverse) + fg bg) + (setq fg (term--color-as-hex t) + bg (term--color-as-hex nil))) + (setq term-current-face + `( :foreground ,fg + :background ,bg + ,@(unless term-ansi-current-invisible + (list :inverse-video term-ansi-current-reverse))))) + + (when term-ansi-current-bold + (setq term-current-face + `(,term-current-face :inherit term-bold))) + + (when term-ansi-current-underline + (setq term-current-face + `(,term-current-face :inherit term-underline)))) =20 =20 ;; Handle a character assuming (eq terminal-state 2) - @@ -3499,7 +3492,7 @@ term-handle-ansi-escape ;; \E[m - Set/reset modes, set bg/fg ;;(terminfo: smso,rmso,smul,rmul,rev,bold,sgr0,invis,op,setab,setaf) ((eq char ?m) =2D (mapc #'term-handle-colors-array params)) + (term--handle-colors-list params)) =20 ;; \E[6n - Report cursor position (terminfo: u7) ((eq char ?n) diff --git a/test/lisp/term-tests.el b/test/lisp/term-tests.el index 96b6d73488..b8adc62c9d 100644 =2D-- a/test/lisp/term-tests.el +++ b/test/lisp/term-tests.el @@ -42,6 +42,9 @@ bright-yellow-bg-props `( :foreground "unspecified-fg" :background ,(face-background 'term-color-bright-yellow nil 'default) :inverse-video nil)) +(defvar custom-color-fg-props + `( :foreground "#87FFFF" + :background "unspecified-bg" :inverse-video nil)) =20 (defvar ansi-test-strings `(("\e[33mHello World\e[0m" @@ -71,7 +74,18 @@ ansi-test-strings ,(propertize "Hello World" 'font-lock-face `(,yellow-fg-props :inherit term-bold)) ,(propertize "Hello World" 'font-lock-face =2D `(,bright-yellow-fg-props :inherit term-bold))))) + `(,bright-yellow-fg-props :inherit term-bold))) + ("\e[38;5;3;1mHello World\e[0m" + ,(propertize "Hello World" 'font-lock-face + `(,yellow-fg-props :inherit term-bold)) + ,(propertize "Hello World" 'font-lock-face + `(,bright-yellow-fg-props :inherit term-bold))) + ("\e[38;5;123;1mHello World\e[0m" + ,(propertize "Hello World" 'font-lock-face + `(,custom-color-fg-props :inherit term-bold))) + ("\e[38;2;135;255;255;1mHello World\e[0m" + ,(propertize "Hello World" 'font-lock-face + `(,custom-color-fg-props :inherit term-bold))))) =20 (defun term-test-screen-from-input (width height input &optional return-va= r) (with-temp-buffer =2D-=20 2.33.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0004-In-term-mode-handle-ANSI-codes-specifying-italic-and.patch Content-Transfer-Encoding: quoted-printable From=20d1b256c98b658231cc4bbec83c7e3c2a44601dc3 Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?Miha=3D20Rihtar=3DC5=3DA1i=3DC4=3D8D?=3D Date: Mon, 27 Sep 2021 15:15:57 +0200 Subject: [PATCH 4/4] In term-mode, handle ANSI codes, specifying italic and other modes * etc/e/eterm-color.ti: Add new capabilities * lisp/term.el: New faces and variables to support new ANSI modes. (term-termcap-format): Add new capabilities (term-emulate-terminal): When saving cursor, additionally save the new variables. (term--handle-colors-list): Handle ANSI codes, specifying italic other modes. * test/lisp/term-tests.el (ansi-test-strings): Adjust tests. =2D-- etc/NEWS | 8 +-- etc/e/eterm-color | Bin 1275 -> 1296 bytes etc/e/eterm-color.ti | 4 ++ etc/e/eterm-direct | Bin 1354 -> 1375 bytes lisp/term.el | 105 ++++++++++++++++++++++++++++++---------- test/lisp/term-tests.el | 32 ++++++------ 6 files changed, 104 insertions(+), 45 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index e22eac5e75..4b6a25c1e7 100644 =2D-- a/etc/NEWS +++ b/etc/NEWS @@ -75,9 +75,11 @@ filters and displayed with the specified color. ** term-mode =20 --- =2D*** Support for ANSI 256-color and 24-bit colors. =2D256-color and 24-bit color codes are now displayed with the specified =2Dcolor. +*** Support for ANSI 256-color and 24-bit colors, italic and other fonts. +Term-mode can now display 256-color and 24-bit color codes. It can +also handle ANSI codes for faint, italic and blinking text, displaying +it with new 'ansi-term-faint/italic/slow-blinking/fast-blinking' +faces. =20 * New Modes and Packages in Emacs 29.1 diff --git a/etc/e/eterm-color b/etc/e/eterm-color index 99603ba5613b822d9916df63b7c1fcc6833a038d..bf44fa0f36de0f6681fa3172db1= 3a83c414aa42a 100644 GIT binary patch delta 286 zcmey(If08?iqV~c9|$uU_f6zp>EX)|#PA;o!Wm*15`nBVhHQocut+JGtYoNTXaTc8 zs$ifCDAETNodBe#GE6pPl#!UpFb~LC48+SB)-Y^@D%i>}c_O2d%}$0x45t~c00r+d zJY#qdq<=3Dsaz)WRigs@nEG&>^~BM+3%&p7!aqZN}Nh&nl0fRUX^j1g$09+xzu8d!-o zBhY#&F%zhIn0X-D5~RtC*`Bd(av*a6w`neebhIIeFq*uG`3}1=3Dm}xw@ilq?%rk#|p delta 241 zcmbQh^_!DhiqV~c9|$uUS5D+!>GA)+FT;N@2x15avSJt#8PdQa*z1egFUf diff --git a/etc/e/eterm-color.ti b/etc/e/eterm-color.ti index 61c29e6dcc..eeb9b0b6e6 100644 =2D-- a/etc/e/eterm-color.ti +++ b/etc/e/eterm-color.ti @@ -18,6 +18,7 @@ eterm-color|Emacs term.el terminal emulator term-protocol= -version 0.96, msgr, xenl, bel=3D^G, + blink=3D\E[5m, bold=3D\E[1m, clear=3D\E[H\E[J, cr=3D\r, @@ -31,6 +32,7 @@ eterm-color|Emacs term.el terminal emulator term-protocol= -version 0.96, cup=3D\E[%i%p1%d;%p2%dH, cuu1=3D\E[A, cuu=3D\E[%p1%dA, + dim=3D\E[2m, dch1=3D\E[P, dch=3D\E[%p1%dP, dl1=3D\E[M, @@ -60,6 +62,7 @@ eterm-color|Emacs term.el terminal emulator term-protocol= -version 0.96, rc=3D\E8, rev=3D\E[7m, ri=3D\EM, + ritm=3D\E[23m, rmir=3D\E[4l, rmso=3D\E[27m, rmul=3D\E[24m, @@ -68,6 +71,7 @@ eterm-color|Emacs term.el terminal emulator term-protocol= -version 0.96, setab=3D\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, setaf=3D\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, sgr0=3D\E[m, + sitm=3D\E[3m, smir=3D\E[4h, smul=3D\E[4m, smso=3D\E[7m, diff --git a/etc/e/eterm-direct b/etc/e/eterm-direct index 35983ec8aded7b0c6b818df47abe57b9440934cb..c113c3713693b948ae9d52e75df= 5d89957fd0c77 100644 GIT binary patch delta 262 zcmX@bb)Sn{jwz6V9|$uUpHAey=3D;6x{#PA;o!Wm*15`nBVhHQocut+JGtYoNTXaTc8 zs$ifCDAETNodBe#GE8igk(kLa56E5&#LF4hFl>a%Z)KQ#kWtBcC&M9z(+pRDf_E97 zF}w%TKcEU=3DhB7ijSS&!Aoso-?2g>K4{E^X`Q4mO8WE2CE`kc~?YG65SAWxdn1V{=3Dq oS^`OLW_!j-lPj46xJ`2zq@xW%gwfiKf@FtdnORiWmv?p94fz>Ve&ynCF}JJI~Wc!oB|47X1K%f z6iB~=3DDu5aL9m@X&r2jH7FfuVhWLPJEWVB{v2a*>Vd4Qxory!#YSWXeht7g_>tesrR R9KdKe`3m!$$-7yW000mDghK!T diff --git a/lisp/term.el b/lisp/term.el index 771b73238f..ce086c379b 100644 =2D-- a/lisp/term.el +++ b/lisp/term.el @@ -711,10 +711,14 @@ term-ansi-at-save-user (defvar term-ansi-at-save-pwd nil) (defvar term-ansi-at-save-anon nil) (defvar term-ansi-current-bold nil) +(defvar term-ansi-current-faint nil) +(defvar term-ansi-current-italic nil) +(defvar term-ansi-current-underline nil) +(defvar term-ansi-current-slow-blink nil) +(defvar term-ansi-current-fast-blink nil) (defvar term-ansi-current-color 0) (defvar term-ansi-face-already-done nil) (defvar term-ansi-current-bg-color 0) =2D(defvar term-ansi-current-underline nil) (defvar term-ansi-current-reverse nil) (defvar term-ansi-current-invisible nil) =20 @@ -769,12 +773,36 @@ term-bold :group 'term :version "28.1") =20 +(defface term-faint + '((t :inherit ansi-color-faint)) + "Default face to use for faint text." + :group 'term + :version "28.1") + +(defface term-italic + '((t :inherit ansi-color-italic)) + "Default face to use for italic text." + :group 'term + :version "28.1") + (defface term-underline '((t :inherit ansi-color-underline)) "Default face to use for underlined text." :group 'term :version "28.1") =20 +(defface term-slow-blink + '((t :inherit ansi-color-slow-blink)) + "Default face to use for slowly blinking text." + :group 'term + :version "28.1") + +(defface term-fast-blink + '((t :inherit ansi-color-fast-blink)) + "Default face to use for rapidly blinking text." + :group 'term + :version "28.1") + (defface term-color-black '((t :inherit ansi-color-black)) "Face used to render black color code." @@ -1038,8 +1066,12 @@ term-display-table =20 (defun term-ansi-reset () (setq term-current-face 'term) =2D (setq term-ansi-current-underline nil) (setq term-ansi-current-bold nil) + (setq term-ansi-current-faint nil) + (setq term-ansi-current-italic nil) + (setq term-ansi-current-underline nil) + (setq term-ansi-current-slow-blink nil) + (setq term-ansi-current-fast-blink nil) (setq term-ansi-current-reverse nil) (setq term-ansi-current-color 0) (setq term-ansi-current-invisible nil) @@ -1581,6 +1613,7 @@ term-termcap-format :nd=3D\\E[C:up=3D\\E[A:ce=3D\\E[K:ho=3D\\E[H:pt\ :al=3D\\E[L:dl=3D\\E[M:DL=3D\\E[%%dM:AL=3D\\E[%%dL:cs=3D\\E[%%i%%d;%%dr:sf= =3D^J\ :dc=3D\\E[P:DC=3D\\E[%%dP:IC=3D\\E[%%d@:im=3D\\E[4h:ei=3D\\E[4l:mi:\ +:mb=3D\\E[5m:mh=3D\\E[2m:ZR=3D\\E[23m:ZH=3D\\E[3m\ :so=3D\\E[7m:se=3D\\E[m:us=3D\\E[4m:ue=3D\\E[m:md=3D\\E[1m:mr=3D\\E[7m:me= =3D\\E[m\ :UP=3D\\E[%%dA:DO=3D\\E[%%dB:LE=3D\\E[%%dD:RI=3D\\E[%%dC\ :kl=3D\\EOD:kd=3D\\EOB:kr=3D\\EOC:ku=3D\\EOA:kN=3D\\E[6~:kP=3D\\E[5~:@7=3D= \\E[4~:kh=3D\\E[1~\ @@ -3105,30 +3138,34 @@ term-emulate-terminal (term-horizontal-column) term-ansi-current-bg-color term-ansi-current-bold + term-ansi-current-faint + term-ansi-current-italic + term-ansi-current-underline + term-ansi-current-slow-blink + term-ansi-current-fast-blink term-ansi-current-color term-ansi-current-invisible term-ansi-current-reverse =2D term-ansi-current-underline term-current-face))) (?8 ;; Restore cursor (terminfo: rc, [ctlseqs] ;; "DECRC"). (when term-saved-cursor (term-goto (nth 0 term-saved-cursor) (nth 1 term-saved-cursor)) =2D (setq term-ansi-current-bg-color =2D (nth 2 term-saved-cursor) =2D term-ansi-current-bold =2D (nth 3 term-saved-cursor) =2D term-ansi-current-color =2D (nth 4 term-saved-cursor) =2D term-ansi-current-invisible =2D (nth 5 term-saved-cursor) =2D term-ansi-current-reverse =2D (nth 6 term-saved-cursor) =2D term-ansi-current-underline =2D (nth 7 term-saved-cursor) =2D term-current-face =2D (nth 8 term-saved-cursor)))) + (pcase-setq + `( ,_ ,_ + ,term-ansi-current-bg-color + ,term-ansi-current-bold + ,term-ansi-current-faint + ,term-ansi-current-italic + ,term-ansi-current-underline + ,term-ansi-current-slow-blink + ,term-ansi-current-fast-blink + ,term-ansi-current-color + ,term-ansi-current-invisible + ,term-ansi-current-reverse + ,term-current-face) + term-saved-cursor))) (?c ;; \Ec - Reset (terminfo: rs1, [ctlseqs] "RIS"). ;; This is used by the "clear" program. (term-reset-terminal)) @@ -3316,11 +3353,20 @@ term--handle-colors-list (while parameters (pcase (pop parameters) (1 (setq term-ansi-current-bold t)) ; (terminfo: bold) + (2 (setq term-ansi-current-faint t)) ; (terminfo: dim) + (3 (setq term-ansi-current-italic t)) ; (terminfo: sitm) (4 (setq term-ansi-current-underline t)) ; (terminfo: smul) =2D (5 (setq term-ansi-current-bold t)) ; (terminfo: bold) + (5 (setq term-ansi-current-slow-blink t)) ; (terminfo: blink) + (6 (setq term-ansi-current-fast-blink t)) (7 (setq term-ansi-current-reverse t)) ; (terminfo: smso, rev) (8 (setq term-ansi-current-invisible t)) ; (terminfo: invis) + (21 (setq term-ansi-current-bold nil)) + (22 (setq term-ansi-current-bold nil) + (setq term-ansi-current-faint nil)) + (23 (setq term-ansi-current-italic nil)) ; (terminfo: ritm) (24 (setq term-ansi-current-underline nil)) ; (terminfo: rmul) + (25 (setq term-ansi-current-slow-blink nil) + (setq term-ansi-current-fast-blink nil)) (27 (setq term-ansi-current-reverse nil)) ; (terminfo: rmso) =20 ;; Foreground (terminfo: setaf) @@ -3398,13 +3444,20 @@ term--handle-colors-list ,@(unless term-ansi-current-invisible (list :inverse-video term-ansi-current-reverse))))) =20 =2D (when term-ansi-current-bold =2D (setq term-current-face =2D `(,term-current-face :inherit term-bold))) =2D =2D (when term-ansi-current-underline =2D (setq term-current-face =2D `(,term-current-face :inherit term-underline)))) + (setq term-current-face + `(,term-current-face + ,@(when term-ansi-current-bold + '(term-bold)) + ,@(when term-ansi-current-faint + '(term-faint)) + ,@(when term-ansi-current-italic + '(term-italic)) + ,@(when term-ansi-current-underline + '(term-underline)) + ,@(when term-ansi-current-slow-blink + '(term-slow-blink)) + ,@(when term-ansi-current-fast-blink + '(term-fast-blink))))) =20 =20 ;; Handle a character assuming (eq terminal-state 2) - @@ -3490,7 +3543,7 @@ term-handle-ansi-escape =20 ;; Modified to allow ansi coloring -mm ;; \E[m - Set/reset modes, set bg/fg =2D ;;(terminfo: smso,rmso,smul,rmul,rev,bold,sgr0,invis,op,setab,setaf) + ;;(terminfo: smso,rmso,smul,rmul,rev,bold,dim,sitm,ritm,blink,sgr0,invi= s,op,setab,setaf) ((eq char ?m) (term--handle-colors-list params)) =20 diff --git a/test/lisp/term-tests.el b/test/lisp/term-tests.el index b8adc62c9d..73d39cf3b6 100644 =2D-- a/test/lisp/term-tests.el +++ b/test/lisp/term-tests.el @@ -48,44 +48,44 @@ custom-color-fg-props =20 (defvar ansi-test-strings `(("\e[33mHello World\e[0m" =2D ,(propertize "Hello World" 'font-lock-face yellow-fg-props)) + ,(propertize "Hello World" 'font-lock-face `(,yellow-fg-props))) ("\e[43mHello World\e[0m" =2D ,(propertize "Hello World" 'font-lock-face yellow-bg-props)) + ,(propertize "Hello World" 'font-lock-face `(,yellow-bg-props))) ("\e[93mHello World\e[0m" =2D ,(propertize "Hello World" 'font-lock-face bright-yellow-fg-props)) + ,(propertize "Hello World" 'font-lock-face `(,bright-yellow-fg-props)= )) ("\e[103mHello World\e[0m" =2D ,(propertize "Hello World" 'font-lock-face bright-yellow-bg-props)) + ,(propertize "Hello World" 'font-lock-face `(,bright-yellow-bg-props)= )) ("\e[1;33mHello World\e[0m" ,(propertize "Hello World" 'font-lock-face =2D `(,yellow-fg-props :inherit term-bold)) + `(,yellow-fg-props term-bold)) ,(propertize "Hello World" 'font-lock-face =2D `(,bright-yellow-fg-props :inherit term-bold))) + `(,bright-yellow-fg-props term-bold))) ("\e[33;1mHello World\e[0m" ,(propertize "Hello World" 'font-lock-face =2D `(,yellow-fg-props :inherit term-bold)) + `(,yellow-fg-props term-bold)) ,(propertize "Hello World" 'font-lock-face =2D `(,bright-yellow-fg-props :inherit term-bold))) + `(,bright-yellow-fg-props term-bold))) ("\e[1m\e[33mHello World\e[0m" ,(propertize "Hello World" 'font-lock-face =2D `(,yellow-fg-props :inherit term-bold)) + `(,yellow-fg-props term-bold)) ,(propertize "Hello World" 'font-lock-face =2D `(,bright-yellow-fg-props :inherit term-bold))) + `(,bright-yellow-fg-props term-bold))) ("\e[33m\e[1mHello World\e[0m" ,(propertize "Hello World" 'font-lock-face =2D `(,yellow-fg-props :inherit term-bold)) + `(,yellow-fg-props term-bold)) ,(propertize "Hello World" 'font-lock-face =2D `(,bright-yellow-fg-props :inherit term-bold))) + `(,bright-yellow-fg-props term-bold))) ("\e[38;5;3;1mHello World\e[0m" ,(propertize "Hello World" 'font-lock-face =2D `(,yellow-fg-props :inherit term-bold)) + `(,yellow-fg-props term-bold)) ,(propertize "Hello World" 'font-lock-face =2D `(,bright-yellow-fg-props :inherit term-bold))) + `(,bright-yellow-fg-props term-bold))) ("\e[38;5;123;1mHello World\e[0m" ,(propertize "Hello World" 'font-lock-face =2D `(,custom-color-fg-props :inherit term-bold))) + `(,custom-color-fg-props term-bold))) ("\e[38;2;135;255;255;1mHello World\e[0m" ,(propertize "Hello World" 'font-lock-face =2D `(,custom-color-fg-props :inherit term-bold))))) + `(,custom-color-fg-props term-bold))))) =20 (defun term-test-screen-from-input (width height input &optional return-va= r) (with-temp-buffer =2D-=20 2.33.0 --=-=-=-- --==-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQJHBAEBCAAxFiEEmxVnesoT5rQXvVXnswkaGpIVmT8FAmFaCl4THG1paGFAa2Ft bml0bmlrLnRvcAAKCRCzCRoakhWZP616D/wOhwC5Brh238kJNHxxZn6fhwJ3asvN bnyZOgHgL6SrZC8XrEjScUsXRb6KAN2dM/RMADlmxXmpOmJj0+sf2CniUeo/RvfE lrQ/FNZsdU8ExN7UU3WEjuyPLgYHAv5e+UigVNnFiSocYkWPtYB/vKaWMSnNgfZn UnykteM7IEHkJk8/AuScy5M5cFF4DVgJ1SIB3jRT5Fz6Jl9IHzjROZScUbIagjMS bL49jyRlmWskVDWX411a7rm53J+HOqU5aODa8S9CW/yO4vHgMU8AEmFl8ygKmWbw DVUzMFySN/c0vNP3e7K7EncsyNE7ERy2aHoO2K8YmJTZn8xyCnynPsjch7sjNfoJ IUxA2cZ4AgO1upu3s37Nmp4eYAIt8PBWvftiT9tVzlcjSTiIm6Eh5uF6vzpToQAI pubKxvU2XuNAefOi1w3gnEukJ+9y4A8lePN2STHhETFAvQS++EjZayVHdTGHzKNt CHEhnm1S1UOj96ygCUlasSiUrONZeYfpPK82c6+jBYB7L+5EC8+BoqD2XvN7TtXL cMUpkstsTgdtXAJkb5YJ62akXDt3QKg8ADcDyOVZRQBAGhK3+jMUk0ynxR17i2Gb wiDiYcWIg9Pl91mSTErxjYjyos3lSxqZI71dILoKw5RIOBfS6QZhnG2qCeXP2iox mpyuf0heKMFN0g== =p5Bx -----END PGP SIGNATURE----- --==-=-=-- From unknown Wed Aug 20 03:37:10 2025 X-Loop: help-debbugs@gnu.org Subject: bug#50806: 27.2; [PATCH] Optimize ansi-color.el Resent-From: Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 03 Oct 2021 19:56:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 50806 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Jim Porter , 50806@debbugs.gnu.org Cc: Lars Ingebrigtsen Received: via spool by 50806-submit@debbugs.gnu.org id=B50806.16332909614253 (code B ref 50806); Sun, 03 Oct 2021 19:56:02 +0000 Received: (at 50806) by debbugs.gnu.org; 3 Oct 2021 19:56:01 +0000 Received: from localhost ([127.0.0.1]:35030 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mX7aZ-00016V-6p for submit@debbugs.gnu.org; Sun, 03 Oct 2021 15:56:00 -0400 Received: from kamnitnik.top ([209.250.245.214]:38806) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mX7aV-00016L-MJ for 50806@debbugs.gnu.org; Sun, 03 Oct 2021 15:55:57 -0400 Received: from localhost (BSN-77-156-43.static.siol.net [193.77.156.43]) by kamnitnik.top (Postfix) with ESMTPSA id 57C769C707; Sun, 3 Oct 2021 19:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kamnitnik.top; s=mail; t=1633290954; bh=HfnkghJAlqrdi+/ae4npWgd9D7J4wCDcIZZzffGyruM=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From; b=HDS/d4U+gvG1dD16YawO3e0m0Xs22uQ98bfw55DEIh7w9Pp+WsRd/45ZNedLOz5ro GzjEdMVTIFu2TQ465uCFyGLxDIB0AAgibXA3LzlpGfftesZnasfz6UJaBcKAu4GjuL +PcuGRvU+6i1war7nWqCVKT6PbmJ8L55P73nnxbzI5VewuVH1Uj0G20gH882elWmkX 66P/wGp+hP67me91ZJdEWCG0L3oE2HY1PT2YbG3RYb2lR2uQ8+Ao5Fw/TeJdrdLzuf l1mDC2oWsm4A+8qWQvj1J7o+0wTDJU+Z6cprL8BSZ4ebAdAzboiB5rDdDcNXou8nlY Fo53c7TdONc8g== From: In-Reply-To: <25ed8125-3f78-c9c9-9324-d75e48e702c6@gmail.com> References: <87tui8wakb.fsf@miha-pc> <25ed8125-3f78-c9c9-9324-d75e48e702c6@gmail.com> Date: Sun, 03 Oct 2021 21:59:25 +0200 Message-ID: <87fsthc21u.fsf@miha-pc> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="==-=-="; micalg=pgp-sha256; protocol="application/pgp-signature" X-Spam-Score: 2.5 (++) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: >> Two less important side notes: >> >> 1) This patch additionally makes it very straight forward to add support >> for ANSI color codes 38 and 48 allowing 256-colors and 24bit >> full-color. I plan t [...] Content analysis details: (2.5 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 2.0 PDS_OTHER_BAD_TLD Untrustworthy TLDs [URI: kamnitnik.top (top)] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record 0.5 FROM_SUSPICIOUS_NTLD From abused NTLD X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 2.5 (++) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: >> Two less important side notes: >> >> 1) This patch additionally makes it very straight forward to add support >> for ANSI color codes 38 and 48 allowing 256-colors and 24bit >> full-color. I plan t [...] Content analysis details: (2.5 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 2.0 PDS_OTHER_BAD_TLD Untrustworthy TLDs [URI: kamnitnik.top (top)] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record 0.5 FROM_SUSPICIOUS_NTLD From abused NTLD 1.0 BULK_RE_SUSP_NTLD Precedence bulk and RE: from a suspicious TLD -1.0 MAILING_LIST_MULTI Multiple indicators imply a widely-seen list manager --==-=-= Content-Type: multipart/mixed; boundary="=-=-=" --=-=-= Content-Type: text/plain Content-Transfer-Encoding: quoted-printable >> Two less important side notes: >>=20 >> 1) This patch additionally makes it very straight forward to add support >> for ANSI color codes 38 and 48 allowing 256-colors and 24bit >> full-color. I plan to submit such a patch later (for both ansi-color >> and term-mode). > > Glad to hear it! I was planning on doing this for Emacs 29, but if > you've already got something in mind for this, feel free to work on > it. Another thing that might be worth looking at would be improving > term.el's support for "basic" ANSI escapes; I think it only does bold, > underline, and inverse. Also, the inverse implementation seems a bit > over-complicated when it could just use the :inverse-video face > attribute instead. > Ok, thanks. I have actually already prepared patches for all these features: full-color in ansi-color.el and term.el and also "basic" ANSI escapes 1-8 for term.el that you mentioned. I guess there's no harm in sending them right now. >> 2) Two vector variables, that were recently added by Jim, were merged >> into one. Adding him as CC. > > I see you posted an updated patch that doesn't merge these vectors. I=20 > don't have an opinion here, although if we do merge them, it would=20 > probably be nice to get that into Emacs 28; other packages might=20 > conceivably want to let-bind those[1]. Indeed, if we wanted to merge them we'd have to do it in Emacs 28. That's why I think its best to simply leave them un-merged. Thanks and best regards. --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0002-Add-support-for-256-color-and-24bit-ANSI-colors-in-a.patch Content-Transfer-Encoding: quoted-printable From=20cc7c1a4888b6e4dfda3a370ce357d0029b6448cc Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?Miha=3D20Rihtar=3DC5=3DA1i=3DC4=3D8D?=3D Date: Sat, 2 Oct 2021 23:13:21 +0200 Subject: [PATCH 2/4] Add support for 256-color and 24bit ANSI colors in ansi-color * lisp/ansi-color.el (ansi-color--code-as-hex): New function to convert from 256-color and 24-bit ANSI codes. (ansi-color--face-vec-face): Add support for ANSI color codes greater than 16 (ansi-color--update-face-vec): Add support for ANSI codes 38 and 48 which can specify 256-color and 24bit ANSI colors. * test/lisp/ansi-color-tests.el (ansi-color-tests--strings): Add tests for ANSI codes 38 and 34 =2D-- etc/NEWS | 7 ++++ lisp/ansi-color.el | 70 ++++++++++++++++++++++++++++------- test/lisp/ansi-color-tests.el | 12 +++++- 3 files changed, 74 insertions(+), 15 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 8c22230daf..e862b77563 100644 =2D-- a/etc/NEWS +++ b/etc/NEWS @@ -65,6 +65,13 @@ binding in the menu. ** subr-x *** New macro 'with-memoization' provides a very primitive form of memoiza= tion =20 +** ansi-color.el + +--- +*** Support for ANSI 256-color and 24-bit colors. +256-color and 24-bit color codes are now handled by ANSI color +filters and displayed with the specified color. + * New Modes and Packages in Emacs 29.1 =20 diff --git a/lisp/ansi-color.el b/lisp/ansi-color.el index 7b46754d83..8d394f353b 100644 =2D-- a/lisp/ansi-color.el +++ b/lisp/ansi-color.el @@ -594,22 +594,24 @@ ansi-color--face-vec-face (when-let ((fg (car colors))) (push `(:foreground =2D ,(face-foreground =2D (aref (if (or bright (>=3D fg 8)) =2D ansi-color-bright-colors-vector =2D ansi-color-normal-colors-vector) =2D (mod fg 8)) =2D nil 'default)) + ,(or (ansi-color--code-as-hex fg) + (face-foreground + (aref (if (or bright (>=3D fg 8)) + ansi-color-bright-colors-vector + ansi-color-normal-colors-vector) + (mod fg 8)) + nil 'default))) faces)) (when-let ((bg (cadr colors))) (push `(:background =2D ,(face-background =2D (aref (if (or bright (>=3D bg 8)) =2D ansi-color-bright-colors-vector =2D ansi-color-normal-colors-vector) =2D (mod bg 8)) =2D nil 'default)) + ,(or (ansi-color--code-as-hex bg) + (face-background + (aref (if (or bright (>=3D bg 8)) + ansi-color-bright-colors-vector + ansi-color-normal-colors-vector) + (mod bg 8)) + nil 'default))) faces)) =20 (let ((i 8)) @@ -622,6 +624,32 @@ ansi-color--face-vec-face faces (car faces)))) =20 +(defun ansi-color--code-as-hex (color) + "Convert COLOR to hexadecimal string representation. +COLOR is an ANSI color code. If it is between 16 and 255 +inclusive, it corresponds to a color from an 8-bit color cube. +If it is greater or equal than 256, it is subtracted by 256 to +directly specify a 24-bit color. + +Return a hexadecimal string, specifying the color, or nil, if +COLOR is less than 16." + (cond + ((< color 16) nil) + ((>=3D color 256) (format "#%06X" (- color 256))) + ((>=3D color 232) ;; Grayscale + (format "#%06X" (* #x010101 (+ 8 (* 10 (- color 232)))))) + (t ;; 6x6x6 color cube + (setq color (- color 16)) + (let ((res 0) + (frac (* 6 6))) + (while (<=3D 1 frac) ; Repeat 3 times + (setq res (* res #x000100)) + (let ((color-num (mod (/ color frac) 6))) + (unless (zerop color-num) + (setq res (+ res #x37 (* #x28 color-num))))) + (setq frac (/ frac 6))) + (format "#%06X" res))))) + ;; Working with regions =20 (defvar-local ansi-color-context-region nil @@ -907,7 +935,23 @@ ansi-color--update-face-vec (let ((r (mod new 10)) (cell (if (memq q '(3 9)) colors (cdr colors)))) (pcase r =2D (8 (setq do-clear t)) + (8 + (pcase (funcall iterator) + (5 (setq new (setcar cell (funcall iterator))) + (setq do-clear (or (null new) (>=3D new 256)))) + (2 + (let ((red (funcall iterator)) + (green (funcall iterator)) + (blue (funcall iterator))) + (if (and red green blue + (progn + (setq new (+ (* #x010000 red) + (* #x000100 green) + (* #x000001 blue))) + (<=3D new #xFFFFFF))) + (setcar cell (+ 256 new)) + (setq do-clear t)))) + (_ (setq do-clear t)))) (9 (setcar cell nil)) (_ (setcar cell (+ (if (memq q '(3 4)) 0 8) r)))))) (_ (setq do-clear t))) diff --git a/test/lisp/ansi-color-tests.el b/test/lisp/ansi-color-tests.el index 953fdff893..16a1ba4a89 100644 =2D-- a/test/lisp/ansi-color-tests.el +++ b/test/lisp/ansi-color-tests.el @@ -27,7 +27,8 @@ =20 (defvar ansi-color-tests--strings (let ((bright-yellow (face-foreground 'ansi-color-bright-yellow nil 'def= ault)) =2D (yellow (face-foreground 'ansi-color-yellow nil 'default))) + (yellow (face-foreground 'ansi-color-yellow nil 'default)) + (custom-color "#87FFFF")) `(("Hello World" "Hello World") ("\e[33mHello World\e[0m" "Hello World" (:foreground ,yellow)) @@ -51,7 +52,14 @@ ansi-color-tests--strings (ansi-color-bold (:foreground ,bright-yellow))) ("\e[1m\e[3m\e[5mbold italics blink\e[0m" "bold italics blink" (ansi-color-bold ansi-color-italic ansi-color-slow-blink)) =2D ("\e[10munrecognized\e[0m" "unrecognized")))) + ("\e[10munrecognized\e[0m" "unrecognized") + ("\e[38;5;3;1mHello World\e[0m" "Hello World" + (ansi-color-bold (:foreground ,yellow)) + (ansi-color-bold (:foreground ,bright-yellow))) + ("\e[48;5;123;1mHello World\e[0m" "Hello World" + (ansi-color-bold (:background ,custom-color))) + ("\e[48;2;135;255;255;1mHello World\e[0m" "Hello World" + (ansi-color-bold (:background ,custom-color)))))) =20 (ert-deftest ansi-color-apply-on-region-test () (pcase-dolist (`(,input ,text ,face) ansi-color-tests--strings) =2D-=20 2.33.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0003-Add-support-for-256-color-and-24bit-ANSI-colors-in-t.patch Content-Transfer-Encoding: quoted-printable From=20ad667c79926f28c5e82654c9f99dc23f41e9375e Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?Miha=3D20Rihtar=3DC5=3DA1i=3DC4=3D8D?=3D Date: Sat, 25 Sep 2021 23:28:08 +0200 Subject: [PATCH 3/4] Add support for 256-color and 24bit ANSI colors in term-mode (term-ansi-face-already-done): Make obsolete (term--maybe-brighten-color): Remove (term--color-as-hex): New function (term-handle-colors-array): Make obsolete in favour of the new function 'term--handle-colors-list'. (term--handle-colors-list): New function, that can also handle ANSI codes 38 and 48. (term-handle-ansi-escape): Use it * test/lisp/term-tests.el (ansi-test-strings): Add tests for 256-color and 24bit ANSI colors =2D-- etc/NEWS | 7 ++ etc/e/README | 18 +-- etc/e/eterm-color | Bin 1179 -> 1275 bytes etc/e/eterm-color.ti | 15 ++- etc/e/eterm-direct | Bin 0 -> 1354 bytes lisp/term.el | 249 +++++++++++++++++++--------------------- test/lisp/term-tests.el | 16 ++- 7 files changed, 163 insertions(+), 142 deletions(-) create mode 100644 etc/e/eterm-direct diff --git a/etc/NEWS b/etc/NEWS index e862b77563..e22eac5e75 100644 =2D-- a/etc/NEWS +++ b/etc/NEWS @@ -72,6 +72,13 @@ binding in the menu. 256-color and 24-bit color codes are now handled by ANSI color filters and displayed with the specified color. =20 +** term-mode + +--- +*** Support for ANSI 256-color and 24-bit colors. +256-color and 24-bit color codes are now displayed with the specified +color. + * New Modes and Packages in Emacs 29.1 =20 diff --git a/etc/e/README b/etc/e/README index dd2c8d64e2..1293292a87 100644 =2D-- a/etc/e/README +++ b/etc/e/README @@ -1,12 +1,12 @@ =2Determ-color.ti is a terminfo source file. eterm-color is a compiled =2Dversion produced by the terminfo compiler (tic). The compiled files =2Dare binary, and depend on the version of tic, but they seem to be =2Dsystem-independent and backwardly compatible. So there should be no =2Dneed to recompile the distributed binary version. If it is =2Dnecessary, use: +eterm-color.ti is a terminfo source file. eterm-color and +eterm-direct are compiled versions produced by the terminfo compiler +(tic). The compiled files are binary, and depend on the version of +tic, but they seem to be system-independent and backwardly compatible. +So there should be no need to recompile the distributed binary +version. If it is necessary, use: =20 tic -o ../ ./eterm-color.ti =20 =2DThe compiled file is used by lisp/term.el, so if it is moved term.el =2Dneeds to be changed. terminfo requires it to be stored in an 'e' =2Dsubdirectory (the first character of the file name). +The compiled files are used by lisp/term.el, so if they are moved, +term.el needs to be changed. terminfo requires them to be stored in +an 'e' subdirectory (the first character of the file name). diff --git a/etc/e/eterm-color b/etc/e/eterm-color index bd3f5003ae620db49b89a2c1387b0ba1c836f4f1..99603ba5613b822d9916df63b7c= 1fcc6833a038d 100644 GIT binary patch delta 160 zcmbQu`J0nliqV~c9|$uUS5D+EWMN?ZU%#>80uy8A=3D0IjW#u|Io0z=3Dhmi&|A1)e>V6 tJ4H1WEM#Z~7PExO>w;vAEv!wgA*!r%8Kk3Ck+qv((QasfqTd8XKLBEMDcJx3 delta 64 zcmey(Ih&JPiqV~c9|$uUJtuM(vT!gsFl=3DnNz{F^^IgnY8QKrC9wc6OAR#jUyC6_@u MS{2Aw*HDLW0nn2UQ~&?~ diff --git a/etc/e/eterm-color.ti b/etc/e/eterm-color.ti index a6ef814990..61c29e6dcc 100644 =2D-- a/etc/e/eterm-color.ti +++ b/etc/e/eterm-color.ti @@ -9,10 +9,10 @@ eterm-color|Emacs term.el terminal emulator term-protocol= -version 0.96, # Any change to this file should be done at the same time with a # corresponding change to the TERMCAP environment variable in term.el. # Comments in term.el specify where each of these capabilities is implemen= ted. =2D colors#8, + colors#256, cols#80, lines#24, =2D pairs#64, + pairs#32767, am, mir, msgr, @@ -65,8 +65,8 @@ eterm-color|Emacs term.el terminal emulator term-protocol= -version 0.96, rmul=3D\E[24m, rs1=3D\Ec, sc=3D\E7, =2D setab=3D\E[%p1%{40}%+%dm, =2D setaf=3D\E[%p1%{30}%+%dm, + setab=3D\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, + setaf=3D\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, sgr0=3D\E[m, smir=3D\E[4h, smul=3D\E[4m, @@ -76,3 +76,10 @@ eterm-color|Emacs term.el terminal emulator term-protoco= l-version 0.96, # smcup=3D\E[?47h, # rmcup=3D\E[?47l, # rs2 may need to be added + +eterm-direct|Emacs term.el with direct-color indexing term-protocol-versio= n 0.96, + use=3Determ-color, + colors#0x1000000, + pairs#0x10000, + setab=3D\E[%?%p1%{8}%<%t4%p1%d%e48;2;%p1%{65536}%/%d;%p1%{256}%/%{255}%&%= d;%p1%{255}%&%d%;m, + setaf=3D\E[%?%p1%{8}%<%t3%p1%d%e38;2;%p1%{65536}%/%d;%p1%{256}%/%{255}%&%= d;%p1%{255}%&%d%;m, diff --git a/etc/e/eterm-direct b/etc/e/eterm-direct new file mode 100644 index 0000000000000000000000000000000000000000..35983ec8aded7b0c6b818df47ab= e57b9440934cb GIT binary patch literal 1354 zcmcgoJ!lkB5T18LqCpW0LD(QG_$&e!z5Tm8HbJ8aM9q!MenQy-Nd-Kj0?$Bv`k=3Dj;a8YZn` z5G7$FeLT}zYOI*djE7BgHA+7Be9*h%6vMxgj8Oje?}ZC)9# zdPGWolB3iDY=3D(0#w~YUGkSa~GjHp0Es6R`iWJ;flP7jF`J3Nk}C#plko94*pa zpnJ4L_l0>VI;ND?^Nhhgo`HFuvoBy@?#meDX4xxxjrb&_~*$ zPsrS%&-4ZM>u*)xa(@?g5ARS=3Dy~<;`{rMgT#luIaJ?M=3D8n|Jb%8=3DX<3QgPvsb^mg! zG1XPWbc&3+j&!G_17CM69V8%TjruK^+Yq+D#Aj)QGw3+<4agK^0aAmMT2Rh1RE1Ib zhjJK6unAyEz!Gwfo`SKTkTHK9paf92*qa9M*mK##q#JP7QR(Ulo!Zh#hjzuc keBnLUwY{#sEboXs%M}mS?dnSdw&!VoUrQ%%=3D^UZucQ(5!9smFU literal 0 HcmV?d00001 diff --git a/lisp/term.el b/lisp/term.el index e76eb77647..771b73238f 100644 =2D-- a/lisp/term.el +++ b/lisp/term.el @@ -303,6 +303,7 @@ term-protocol-version (require 'ange-ftp) (require 'cl-lib)) (require 'comint) ; Password regexp. +(require 'ansi-color) (require 'ehelp) (require 'ring) (require 'shell) @@ -717,6 +718,9 @@ term-ansi-current-underline (defvar term-ansi-current-reverse nil) (defvar term-ansi-current-invisible nil) =20 +(make-obsolete-variable 'term-ansi-face-already-done + "it doesn't have any effect." "28.1") + ;;; Faces (defvar ansi-term-color-vector [term @@ -1039,10 +1043,6 @@ term-ansi-reset (setq term-ansi-current-reverse nil) (setq term-ansi-current-color 0) (setq term-ansi-current-invisible nil) =2D ;; Stefan thought this should be t, but could not remember why. =2D ;; Setting it to t seems to cause bug#11785. Setting it to nil =2D ;; again to see if there are other consequences... =2D (setq term-ansi-face-already-done nil) (setq term-ansi-current-bg-color 0)) =20 (define-derived-mode term-mode fundamental-mode "Term" @@ -1584,7 +1584,8 @@ term-termcap-format :so=3D\\E[7m:se=3D\\E[m:us=3D\\E[4m:ue=3D\\E[m:md=3D\\E[1m:mr=3D\\E[7m:me= =3D\\E[m\ :UP=3D\\E[%%dA:DO=3D\\E[%%dB:LE=3D\\E[%%dD:RI=3D\\E[%%dC\ :kl=3D\\EOD:kd=3D\\EOB:kr=3D\\EOC:ku=3D\\EOA:kN=3D\\E[6~:kP=3D\\E[5~:@7=3D= \\E[4~:kh=3D\\E[1~\ =2D:mk=3D\\E[8m:cb=3D\\E[1K:op=3D\\E[39;49m:Co#8:pa#64:AB=3D\\E[4%%dm:AF=3D= \\E[3%%dm:cr=3D^M\ +:mk=3D\\E[8m:cb=3D\\E[1K:op=3D\\E[39;49m:Co#256:pa#32767\ +:AB=3D\\E[48;5;%%dm:AF=3D\\E[38;5;%%dm:cr=3D^M\ :bl=3D^G:do=3D^J:le=3D^H:ta=3D^I:se=3D\\E[27m:ue=3D\\E[24m\ :kb=3D^?:kD=3D^[[3~:sc=3D\\E7:rc=3D\\E8:r1=3D\\Ec:" ;; : -undefine ic @@ -3285,133 +3286,125 @@ term-reset-terminal (setq term-current-row 0) (setq term-current-column 1) (term--reset-scroll-region) =2D (setq term-insert-mode nil) =2D ;; FIXME: No idea why this is here, it looks wrong. --Stef =2D (setq term-ansi-face-already-done nil)) =2D =2D(defun term--maybe-brighten-color (color bold) =2D "Possibly convert COLOR to its bright variant. =2DCOLOR is an index into `ansi-term-color-vector'. If BOLD and =2D`ansi-color-bold-is-bright' are non-nil and COLOR is a regular color, =2Dreturn the bright version of COLOR; otherwise, return COLOR." =2D (if (and ansi-color-bold-is-bright bold (<=3D 1 color 8)) =2D (+ color 8) =2D color)) + (setq term-insert-mode nil)) + +(defun term--color-as-hex (for-foreground) + "Return the current ANSI color as a hexadecimal color string. +Use the current background color if FOR-FOREGROUND is nil, +otherwise use the current foreground color." + (let ((color (if for-foreground term-ansi-current-color + term-ansi-current-bg-color))) + (or (ansi-color--code-as-hex (1- color)) + (progn + (and ansi-color-bold-is-bright term-ansi-current-bold + (<=3D 1 color 8) + (setq color (+ color 8))) + (if for-foreground + (face-foreground (elt ansi-term-color-vector color) + nil 'default) + (face-background (elt ansi-term-color-vector color) + nil 'default)))))) =20 ;; New function to deal with ansi colorized output, as you can see you can ;; have any bold/underline/fg/bg/reverse combination. -mm =20 (defun term-handle-colors-array (parameter) =2D (cond =2D =2D ;; Bold (terminfo: bold) =2D ((eq parameter 1) =2D (setq term-ansi-current-bold t)) =2D =2D ;; Underline =2D ((eq parameter 4) =2D (setq term-ansi-current-underline t)) =2D =2D ;; Blink (unsupported by Emacs), will be translated to bold. =2D ;; This may change in the future though. =2D ((eq parameter 5) =2D (setq term-ansi-current-bold t)) =2D =2D ;; Reverse (terminfo: smso) =2D ((eq parameter 7) =2D (setq term-ansi-current-reverse t)) =2D =2D ;; Invisible =2D ((eq parameter 8) =2D (setq term-ansi-current-invisible t)) =2D =2D ;; Reset underline (terminfo: rmul) =2D ((eq parameter 24) =2D (setq term-ansi-current-underline nil)) =2D =2D ;; Reset reverse (terminfo: rmso) =2D ((eq parameter 27) =2D (setq term-ansi-current-reverse nil)) =2D =2D ;; Foreground =2D ((and (>=3D parameter 30) (<=3D parameter 37)) =2D (setq term-ansi-current-color (- parameter 29))) =2D =2D ;; Bright foreground =2D ((and (>=3D parameter 90) (<=3D parameter 97)) =2D (setq term-ansi-current-color (- parameter 81))) =2D =2D ;; Reset foreground =2D ((eq parameter 39) =2D (setq term-ansi-current-color 0)) =2D =2D ;; Background =2D ((and (>=3D parameter 40) (<=3D parameter 47)) =2D (setq term-ansi-current-bg-color (- parameter 39))) =2D =2D ;; Bright foreground =2D ((and (>=3D parameter 100) (<=3D parameter 107)) =2D (setq term-ansi-current-bg-color (- parameter 91))) =2D =2D ;; Reset background =2D ((eq parameter 49) =2D (setq term-ansi-current-bg-color 0)) =2D =2D ;; 0 (Reset) or unknown (reset anyway) =2D (t =2D (term-ansi-reset))) =2D =2D ;; (message "Debug: U-%d R-%d B-%d I-%d D-%d F-%d B-%d" =2D ;; term-ansi-current-underline =2D ;; term-ansi-current-reverse =2D ;; term-ansi-current-bold =2D ;; term-ansi-current-invisible =2D ;; term-ansi-face-already-done =2D ;; term-ansi-current-color =2D ;; term-ansi-current-bg-color) =2D =2D (unless term-ansi-face-already-done =2D (let ((current-color (term--maybe-brighten-color =2D term-ansi-current-color =2D term-ansi-current-bold)) =2D (current-bg-color (term--maybe-brighten-color =2D term-ansi-current-bg-color =2D term-ansi-current-bold))) =2D (if term-ansi-current-invisible =2D (let ((color =2D (if term-ansi-current-reverse =2D (face-foreground =2D (elt ansi-term-color-vector current-color) =2D nil 'default) =2D (face-background =2D (elt ansi-term-color-vector current-bg-color) =2D nil 'default)))) =2D (setq term-current-face =2D (list :background color =2D :foreground color)) =2D ) ;; No need to bother with anything else if it's invisible. =2D (setq term-current-face =2D (list :foreground =2D (face-foreground =2D (elt ansi-term-color-vector current-color) =2D nil 'default) =2D :background =2D (face-background =2D (elt ansi-term-color-vector current-bg-color) =2D nil 'default) =2D :inverse-video term-ansi-current-reverse)) =2D =2D (when term-ansi-current-bold =2D (setq term-current-face =2D `(,term-current-face :inherit term-bold))) =2D =2D (when term-ansi-current-underline =2D (setq term-current-face =2D `(,term-current-face :inherit term-underline)))))) =2D =2D ;; (message "Debug %S" term-current-face) =2D ;; FIXME: shouldn't we set term-ansi-face-already-done to t here? --S= tef =2D (setq term-ansi-face-already-done nil)) + (declare (obsolete term--handle-colors-list "28.1")) + (term--handle-colors-list (list parameter))) + +(defun term--handle-colors-list (parameters) + (while parameters + (pcase (pop parameters) + (1 (setq term-ansi-current-bold t)) ; (terminfo: bold) + (4 (setq term-ansi-current-underline t)) ; (terminfo: smul) + (5 (setq term-ansi-current-bold t)) ; (terminfo: bold) + (7 (setq term-ansi-current-reverse t)) ; (terminfo: smso, rev) + (8 (setq term-ansi-current-invisible t)) ; (terminfo: invis) + (24 (setq term-ansi-current-underline nil)) ; (terminfo: rmul) + (27 (setq term-ansi-current-reverse nil)) ; (terminfo: rmso) + + ;; Foreground (terminfo: setaf) + ((and param (guard (<=3D 30 param 37))) + (setq term-ansi-current-color (- param 29))) + + ;; Bright foreground (terminfo: setaf) + ((and param (guard (<=3D 90 param 97))) + (setq term-ansi-current-color (- param 81))) + + ;; Extended foreground (terminfo: setaf) + (38 + (pcase (pop parameters) + ;; 256 color + (5 (if (setq term-ansi-current-color (pop parameters)) + (cl-incf term-ansi-current-color) + (term-ansi-reset))) + ;; Full 24-bit color + (2 (cl-loop with color =3D (1+ 256) ; Base + for i from 16 downto 0 by 8 + if (pop parameters) + do (setq color (+ color (ash it i))) + else return (term-ansi-reset) + finally + (if (> color (+ 1 256 #xFFFFFF)) + (term-ansi-reset) + (setq term-ansi-current-color color)))) + (_ (term-ansi-reset)))) + + ;; Reset foreground (terminfo: op) + (39 (setq term-ansi-current-color 0)) + + ;; Background (terminfo: setab) + ((and param (guard (<=3D 40 param 47))) + (setq term-ansi-current-bg-color (- param 39))) + + ;; Bright background (terminfo: setab) + ((and param (guard (<=3D 100 param 107))) + (setq term-ansi-current-bg-color (- param 91))) + + ;; Extended background (terminfo: setab) + (48 + (pcase (pop parameters) + ;; 256 color + (5 (if (setq term-ansi-current-bg-color (pop parameters)) + (cl-incf term-ansi-current-bg-color) + (term-ansi-reset))) + ;; Full 24-bit color + (2 (cl-loop with color =3D (1+ 256) ; Base + for i from 16 downto 0 by 8 + if (pop parameters) + do (setq color (+ color (ash it i))) + else return (term-ansi-reset) + finally + (if (> color (+ 1 256 #xFFFFFF)) + (term-ansi-reset) + (setq term-ansi-current-bg-color color)))) + (_ (term-ansi-reset)))) + + ;; Reset background (terminfo: op) + (49 (setq term-ansi-current-bg-color 0)) + + ;; 0 (Reset) (terminfo: sgr0) or unknown (reset anyway) + (_ (term-ansi-reset)))) + + (let (fg bg) + (if term-ansi-current-invisible + (setq bg (term--color-as-hex term-ansi-current-reverse) + fg bg) + (setq fg (term--color-as-hex t) + bg (term--color-as-hex nil))) + (setq term-current-face + `( :foreground ,fg + :background ,bg + ,@(unless term-ansi-current-invisible + (list :inverse-video term-ansi-current-reverse))))) + + (when term-ansi-current-bold + (setq term-current-face + `(,term-current-face :inherit term-bold))) + + (when term-ansi-current-underline + (setq term-current-face + `(,term-current-face :inherit term-underline)))) =20 =20 ;; Handle a character assuming (eq terminal-state 2) - @@ -3499,7 +3492,7 @@ term-handle-ansi-escape ;; \E[m - Set/reset modes, set bg/fg ;;(terminfo: smso,rmso,smul,rmul,rev,bold,sgr0,invis,op,setab,setaf) ((eq char ?m) =2D (mapc #'term-handle-colors-array params)) + (term--handle-colors-list params)) =20 ;; \E[6n - Report cursor position (terminfo: u7) ((eq char ?n) diff --git a/test/lisp/term-tests.el b/test/lisp/term-tests.el index 96b6d73488..b8adc62c9d 100644 =2D-- a/test/lisp/term-tests.el +++ b/test/lisp/term-tests.el @@ -42,6 +42,9 @@ bright-yellow-bg-props `( :foreground "unspecified-fg" :background ,(face-background 'term-color-bright-yellow nil 'default) :inverse-video nil)) +(defvar custom-color-fg-props + `( :foreground "#87FFFF" + :background "unspecified-bg" :inverse-video nil)) =20 (defvar ansi-test-strings `(("\e[33mHello World\e[0m" @@ -71,7 +74,18 @@ ansi-test-strings ,(propertize "Hello World" 'font-lock-face `(,yellow-fg-props :inherit term-bold)) ,(propertize "Hello World" 'font-lock-face =2D `(,bright-yellow-fg-props :inherit term-bold))))) + `(,bright-yellow-fg-props :inherit term-bold))) + ("\e[38;5;3;1mHello World\e[0m" + ,(propertize "Hello World" 'font-lock-face + `(,yellow-fg-props :inherit term-bold)) + ,(propertize "Hello World" 'font-lock-face + `(,bright-yellow-fg-props :inherit term-bold))) + ("\e[38;5;123;1mHello World\e[0m" + ,(propertize "Hello World" 'font-lock-face + `(,custom-color-fg-props :inherit term-bold))) + ("\e[38;2;135;255;255;1mHello World\e[0m" + ,(propertize "Hello World" 'font-lock-face + `(,custom-color-fg-props :inherit term-bold))))) =20 (defun term-test-screen-from-input (width height input &optional return-va= r) (with-temp-buffer =2D-=20 2.33.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0004-In-term-mode-handle-ANSI-codes-specifying-italic-and.patch Content-Transfer-Encoding: quoted-printable From=20d1b256c98b658231cc4bbec83c7e3c2a44601dc3 Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?Miha=3D20Rihtar=3DC5=3DA1i=3DC4=3D8D?=3D Date: Mon, 27 Sep 2021 15:15:57 +0200 Subject: [PATCH 4/4] In term-mode, handle ANSI codes, specifying italic and other modes * etc/e/eterm-color.ti: Add new capabilities * lisp/term.el: New faces and variables to support new ANSI modes. (term-termcap-format): Add new capabilities (term-emulate-terminal): When saving cursor, additionally save the new variables. (term--handle-colors-list): Handle ANSI codes, specifying italic other modes. * test/lisp/term-tests.el (ansi-test-strings): Adjust tests. =2D-- etc/NEWS | 8 +-- etc/e/eterm-color | Bin 1275 -> 1296 bytes etc/e/eterm-color.ti | 4 ++ etc/e/eterm-direct | Bin 1354 -> 1375 bytes lisp/term.el | 105 ++++++++++++++++++++++++++++++---------- test/lisp/term-tests.el | 32 ++++++------ 6 files changed, 104 insertions(+), 45 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index e22eac5e75..4b6a25c1e7 100644 =2D-- a/etc/NEWS +++ b/etc/NEWS @@ -75,9 +75,11 @@ filters and displayed with the specified color. ** term-mode =20 --- =2D*** Support for ANSI 256-color and 24-bit colors. =2D256-color and 24-bit color codes are now displayed with the specified =2Dcolor. +*** Support for ANSI 256-color and 24-bit colors, italic and other fonts. +Term-mode can now display 256-color and 24-bit color codes. It can +also handle ANSI codes for faint, italic and blinking text, displaying +it with new 'ansi-term-faint/italic/slow-blinking/fast-blinking' +faces. =20 * New Modes and Packages in Emacs 29.1 diff --git a/etc/e/eterm-color b/etc/e/eterm-color index 99603ba5613b822d9916df63b7c1fcc6833a038d..bf44fa0f36de0f6681fa3172db1= 3a83c414aa42a 100644 GIT binary patch delta 286 zcmey(If08?iqV~c9|$uU_f6zp>EX)|#PA;o!Wm*15`nBVhHQocut+JGtYoNTXaTc8 zs$ifCDAETNodBe#GE6pPl#!UpFb~LC48+SB)-Y^@D%i>}c_O2d%}$0x45t~c00r+d zJY#qdq<=3Dsaz)WRigs@nEG&>^~BM+3%&p7!aqZN}Nh&nl0fRUX^j1g$09+xzu8d!-o zBhY#&F%zhIn0X-D5~RtC*`Bd(av*a6w`neebhIIeFq*uG`3}1=3Dm}xw@ilq?%rk#|p delta 241 zcmbQh^_!DhiqV~c9|$uUS5D+!>GA)+FT;N@2x15avSJt#8PdQa*z1egFUf diff --git a/etc/e/eterm-color.ti b/etc/e/eterm-color.ti index 61c29e6dcc..eeb9b0b6e6 100644 =2D-- a/etc/e/eterm-color.ti +++ b/etc/e/eterm-color.ti @@ -18,6 +18,7 @@ eterm-color|Emacs term.el terminal emulator term-protocol= -version 0.96, msgr, xenl, bel=3D^G, + blink=3D\E[5m, bold=3D\E[1m, clear=3D\E[H\E[J, cr=3D\r, @@ -31,6 +32,7 @@ eterm-color|Emacs term.el terminal emulator term-protocol= -version 0.96, cup=3D\E[%i%p1%d;%p2%dH, cuu1=3D\E[A, cuu=3D\E[%p1%dA, + dim=3D\E[2m, dch1=3D\E[P, dch=3D\E[%p1%dP, dl1=3D\E[M, @@ -60,6 +62,7 @@ eterm-color|Emacs term.el terminal emulator term-protocol= -version 0.96, rc=3D\E8, rev=3D\E[7m, ri=3D\EM, + ritm=3D\E[23m, rmir=3D\E[4l, rmso=3D\E[27m, rmul=3D\E[24m, @@ -68,6 +71,7 @@ eterm-color|Emacs term.el terminal emulator term-protocol= -version 0.96, setab=3D\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, setaf=3D\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, sgr0=3D\E[m, + sitm=3D\E[3m, smir=3D\E[4h, smul=3D\E[4m, smso=3D\E[7m, diff --git a/etc/e/eterm-direct b/etc/e/eterm-direct index 35983ec8aded7b0c6b818df47abe57b9440934cb..c113c3713693b948ae9d52e75df= 5d89957fd0c77 100644 GIT binary patch delta 262 zcmX@bb)Sn{jwz6V9|$uUpHAey=3D;6x{#PA;o!Wm*15`nBVhHQocut+JGtYoNTXaTc8 zs$ifCDAETNodBe#GE8igk(kLa56E5&#LF4hFl>a%Z)KQ#kWtBcC&M9z(+pRDf_E97 zF}w%TKcEU=3DhB7ijSS&!Aoso-?2g>K4{E^X`Q4mO8WE2CE`kc~?YG65SAWxdn1V{=3Dq oS^`OLW_!j-lPj46xJ`2zq@xW%gwfiKf@FtdnORiWmv?p94fz>Ve&ynCF}JJI~Wc!oB|47X1K%f z6iB~=3DDu5aL9m@X&r2jH7FfuVhWLPJEWVB{v2a*>Vd4Qxory!#YSWXeht7g_>tesrR R9KdKe`3m!$$-7yW000mDghK!T diff --git a/lisp/term.el b/lisp/term.el index 771b73238f..ce086c379b 100644 =2D-- a/lisp/term.el +++ b/lisp/term.el @@ -711,10 +711,14 @@ term-ansi-at-save-user (defvar term-ansi-at-save-pwd nil) (defvar term-ansi-at-save-anon nil) (defvar term-ansi-current-bold nil) +(defvar term-ansi-current-faint nil) +(defvar term-ansi-current-italic nil) +(defvar term-ansi-current-underline nil) +(defvar term-ansi-current-slow-blink nil) +(defvar term-ansi-current-fast-blink nil) (defvar term-ansi-current-color 0) (defvar term-ansi-face-already-done nil) (defvar term-ansi-current-bg-color 0) =2D(defvar term-ansi-current-underline nil) (defvar term-ansi-current-reverse nil) (defvar term-ansi-current-invisible nil) =20 @@ -769,12 +773,36 @@ term-bold :group 'term :version "28.1") =20 +(defface term-faint + '((t :inherit ansi-color-faint)) + "Default face to use for faint text." + :group 'term + :version "28.1") + +(defface term-italic + '((t :inherit ansi-color-italic)) + "Default face to use for italic text." + :group 'term + :version "28.1") + (defface term-underline '((t :inherit ansi-color-underline)) "Default face to use for underlined text." :group 'term :version "28.1") =20 +(defface term-slow-blink + '((t :inherit ansi-color-slow-blink)) + "Default face to use for slowly blinking text." + :group 'term + :version "28.1") + +(defface term-fast-blink + '((t :inherit ansi-color-fast-blink)) + "Default face to use for rapidly blinking text." + :group 'term + :version "28.1") + (defface term-color-black '((t :inherit ansi-color-black)) "Face used to render black color code." @@ -1038,8 +1066,12 @@ term-display-table =20 (defun term-ansi-reset () (setq term-current-face 'term) =2D (setq term-ansi-current-underline nil) (setq term-ansi-current-bold nil) + (setq term-ansi-current-faint nil) + (setq term-ansi-current-italic nil) + (setq term-ansi-current-underline nil) + (setq term-ansi-current-slow-blink nil) + (setq term-ansi-current-fast-blink nil) (setq term-ansi-current-reverse nil) (setq term-ansi-current-color 0) (setq term-ansi-current-invisible nil) @@ -1581,6 +1613,7 @@ term-termcap-format :nd=3D\\E[C:up=3D\\E[A:ce=3D\\E[K:ho=3D\\E[H:pt\ :al=3D\\E[L:dl=3D\\E[M:DL=3D\\E[%%dM:AL=3D\\E[%%dL:cs=3D\\E[%%i%%d;%%dr:sf= =3D^J\ :dc=3D\\E[P:DC=3D\\E[%%dP:IC=3D\\E[%%d@:im=3D\\E[4h:ei=3D\\E[4l:mi:\ +:mb=3D\\E[5m:mh=3D\\E[2m:ZR=3D\\E[23m:ZH=3D\\E[3m\ :so=3D\\E[7m:se=3D\\E[m:us=3D\\E[4m:ue=3D\\E[m:md=3D\\E[1m:mr=3D\\E[7m:me= =3D\\E[m\ :UP=3D\\E[%%dA:DO=3D\\E[%%dB:LE=3D\\E[%%dD:RI=3D\\E[%%dC\ :kl=3D\\EOD:kd=3D\\EOB:kr=3D\\EOC:ku=3D\\EOA:kN=3D\\E[6~:kP=3D\\E[5~:@7=3D= \\E[4~:kh=3D\\E[1~\ @@ -3105,30 +3138,34 @@ term-emulate-terminal (term-horizontal-column) term-ansi-current-bg-color term-ansi-current-bold + term-ansi-current-faint + term-ansi-current-italic + term-ansi-current-underline + term-ansi-current-slow-blink + term-ansi-current-fast-blink term-ansi-current-color term-ansi-current-invisible term-ansi-current-reverse =2D term-ansi-current-underline term-current-face))) (?8 ;; Restore cursor (terminfo: rc, [ctlseqs] ;; "DECRC"). (when term-saved-cursor (term-goto (nth 0 term-saved-cursor) (nth 1 term-saved-cursor)) =2D (setq term-ansi-current-bg-color =2D (nth 2 term-saved-cursor) =2D term-ansi-current-bold =2D (nth 3 term-saved-cursor) =2D term-ansi-current-color =2D (nth 4 term-saved-cursor) =2D term-ansi-current-invisible =2D (nth 5 term-saved-cursor) =2D term-ansi-current-reverse =2D (nth 6 term-saved-cursor) =2D term-ansi-current-underline =2D (nth 7 term-saved-cursor) =2D term-current-face =2D (nth 8 term-saved-cursor)))) + (pcase-setq + `( ,_ ,_ + ,term-ansi-current-bg-color + ,term-ansi-current-bold + ,term-ansi-current-faint + ,term-ansi-current-italic + ,term-ansi-current-underline + ,term-ansi-current-slow-blink + ,term-ansi-current-fast-blink + ,term-ansi-current-color + ,term-ansi-current-invisible + ,term-ansi-current-reverse + ,term-current-face) + term-saved-cursor))) (?c ;; \Ec - Reset (terminfo: rs1, [ctlseqs] "RIS"). ;; This is used by the "clear" program. (term-reset-terminal)) @@ -3316,11 +3353,20 @@ term--handle-colors-list (while parameters (pcase (pop parameters) (1 (setq term-ansi-current-bold t)) ; (terminfo: bold) + (2 (setq term-ansi-current-faint t)) ; (terminfo: dim) + (3 (setq term-ansi-current-italic t)) ; (terminfo: sitm) (4 (setq term-ansi-current-underline t)) ; (terminfo: smul) =2D (5 (setq term-ansi-current-bold t)) ; (terminfo: bold) + (5 (setq term-ansi-current-slow-blink t)) ; (terminfo: blink) + (6 (setq term-ansi-current-fast-blink t)) (7 (setq term-ansi-current-reverse t)) ; (terminfo: smso, rev) (8 (setq term-ansi-current-invisible t)) ; (terminfo: invis) + (21 (setq term-ansi-current-bold nil)) + (22 (setq term-ansi-current-bold nil) + (setq term-ansi-current-faint nil)) + (23 (setq term-ansi-current-italic nil)) ; (terminfo: ritm) (24 (setq term-ansi-current-underline nil)) ; (terminfo: rmul) + (25 (setq term-ansi-current-slow-blink nil) + (setq term-ansi-current-fast-blink nil)) (27 (setq term-ansi-current-reverse nil)) ; (terminfo: rmso) =20 ;; Foreground (terminfo: setaf) @@ -3398,13 +3444,20 @@ term--handle-colors-list ,@(unless term-ansi-current-invisible (list :inverse-video term-ansi-current-reverse))))) =20 =2D (when term-ansi-current-bold =2D (setq term-current-face =2D `(,term-current-face :inherit term-bold))) =2D =2D (when term-ansi-current-underline =2D (setq term-current-face =2D `(,term-current-face :inherit term-underline)))) + (setq term-current-face + `(,term-current-face + ,@(when term-ansi-current-bold + '(term-bold)) + ,@(when term-ansi-current-faint + '(term-faint)) + ,@(when term-ansi-current-italic + '(term-italic)) + ,@(when term-ansi-current-underline + '(term-underline)) + ,@(when term-ansi-current-slow-blink + '(term-slow-blink)) + ,@(when term-ansi-current-fast-blink + '(term-fast-blink))))) =20 =20 ;; Handle a character assuming (eq terminal-state 2) - @@ -3490,7 +3543,7 @@ term-handle-ansi-escape =20 ;; Modified to allow ansi coloring -mm ;; \E[m - Set/reset modes, set bg/fg =2D ;;(terminfo: smso,rmso,smul,rmul,rev,bold,sgr0,invis,op,setab,setaf) + ;;(terminfo: smso,rmso,smul,rmul,rev,bold,dim,sitm,ritm,blink,sgr0,invi= s,op,setab,setaf) ((eq char ?m) (term--handle-colors-list params)) =20 diff --git a/test/lisp/term-tests.el b/test/lisp/term-tests.el index b8adc62c9d..73d39cf3b6 100644 =2D-- a/test/lisp/term-tests.el +++ b/test/lisp/term-tests.el @@ -48,44 +48,44 @@ custom-color-fg-props =20 (defvar ansi-test-strings `(("\e[33mHello World\e[0m" =2D ,(propertize "Hello World" 'font-lock-face yellow-fg-props)) + ,(propertize "Hello World" 'font-lock-face `(,yellow-fg-props))) ("\e[43mHello World\e[0m" =2D ,(propertize "Hello World" 'font-lock-face yellow-bg-props)) + ,(propertize "Hello World" 'font-lock-face `(,yellow-bg-props))) ("\e[93mHello World\e[0m" =2D ,(propertize "Hello World" 'font-lock-face bright-yellow-fg-props)) + ,(propertize "Hello World" 'font-lock-face `(,bright-yellow-fg-props)= )) ("\e[103mHello World\e[0m" =2D ,(propertize "Hello World" 'font-lock-face bright-yellow-bg-props)) + ,(propertize "Hello World" 'font-lock-face `(,bright-yellow-bg-props)= )) ("\e[1;33mHello World\e[0m" ,(propertize "Hello World" 'font-lock-face =2D `(,yellow-fg-props :inherit term-bold)) + `(,yellow-fg-props term-bold)) ,(propertize "Hello World" 'font-lock-face =2D `(,bright-yellow-fg-props :inherit term-bold))) + `(,bright-yellow-fg-props term-bold))) ("\e[33;1mHello World\e[0m" ,(propertize "Hello World" 'font-lock-face =2D `(,yellow-fg-props :inherit term-bold)) + `(,yellow-fg-props term-bold)) ,(propertize "Hello World" 'font-lock-face =2D `(,bright-yellow-fg-props :inherit term-bold))) + `(,bright-yellow-fg-props term-bold))) ("\e[1m\e[33mHello World\e[0m" ,(propertize "Hello World" 'font-lock-face =2D `(,yellow-fg-props :inherit term-bold)) + `(,yellow-fg-props term-bold)) ,(propertize "Hello World" 'font-lock-face =2D `(,bright-yellow-fg-props :inherit term-bold))) + `(,bright-yellow-fg-props term-bold))) ("\e[33m\e[1mHello World\e[0m" ,(propertize "Hello World" 'font-lock-face =2D `(,yellow-fg-props :inherit term-bold)) + `(,yellow-fg-props term-bold)) ,(propertize "Hello World" 'font-lock-face =2D `(,bright-yellow-fg-props :inherit term-bold))) + `(,bright-yellow-fg-props term-bold))) ("\e[38;5;3;1mHello World\e[0m" ,(propertize "Hello World" 'font-lock-face =2D `(,yellow-fg-props :inherit term-bold)) + `(,yellow-fg-props term-bold)) ,(propertize "Hello World" 'font-lock-face =2D `(,bright-yellow-fg-props :inherit term-bold))) + `(,bright-yellow-fg-props term-bold))) ("\e[38;5;123;1mHello World\e[0m" ,(propertize "Hello World" 'font-lock-face =2D `(,custom-color-fg-props :inherit term-bold))) + `(,custom-color-fg-props term-bold))) ("\e[38;2;135;255;255;1mHello World\e[0m" ,(propertize "Hello World" 'font-lock-face =2D `(,custom-color-fg-props :inherit term-bold))))) + `(,custom-color-fg-props term-bold))))) =20 (defun term-test-screen-from-input (width height input &optional return-va= r) (with-temp-buffer =2D-=20 2.33.0 --=-=-=-- --==-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQJHBAEBCAAxFiEEmxVnesoT5rQXvVXnswkaGpIVmT8FAmFaC50THG1paGFAa2Ft bml0bmlrLnRvcAAKCRCzCRoakhWZP9eZEACcpxETDtrFGbdnaTUIMYrLCsSBxCL3 uOYe17ya+cqlN2dARrNeTIB6ve0k1+S+oqPj96fHvL2JDfLsMCafLcFSIDH7kK3y F18S6Lql5+MLRKWyYxznklXOfqRiE2egDSJtYDyEkTuIpnLYcHQH/vN318VtyIVm 9p6Adl/QcF6zh3HwWPkEsgI65M/ZicEXwZgu5Srv6KGcSzIPAuBMXruSDoO+q4l4 GDfDFrVo+LjloyzGCZf9BLOqLj/WAAaH3bsZ8E0m+/REkLTZhO7GH5wI0gB1r/h7 5kiAkStBLZzEJtf5JsAOW2jf/30yypZEZKGi6YJlDNUDOsK77KV6ce9S1ysYnL6u HnFXdkIr4UlONDqDP6qSfKwCsIq7l0aVKCWDf9SNgw6BVJng0UidbrSB7iL69U5i 8F8cQtw4FQ7dutafKUmAJ4dQ5ybdlan+QzJBNRD8zjJw5Zk7WhQOYkHibt5+txmE LDqeXKoAejFQz2BRk2UPYKaVLcEcwkjqevSr58YuVVNujdzYu56ioeZgCAlyTiXO CdqN91IycQ9VrYMTD6VSyunHWHZrU00U7AILxz2IegQLau9MZ0RXpOo+KK1dTGqJ JHxqcKLORAo2CU3YtIVnXivpI57p3HGMd+JOKud/Ub0iTJjmqHqvXatN81sDfZqn YCvurxW16xz47g== =fuiC -----END PGP SIGNATURE----- --==-=-=-- From unknown Wed Aug 20 03:37:10 2025 X-Loop: help-debbugs@gnu.org Subject: bug#50806: 27.2; [PATCH] Optimize ansi-color.el Resent-From: Jim Porter Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 03 Oct 2021 20:17:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 50806 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: miha@kamnitnik.top, 50806@debbugs.gnu.org Cc: Lars Ingebrigtsen Received: via spool by 50806-submit@debbugs.gnu.org id=B50806.163329217810624 (code B ref 50806); Sun, 03 Oct 2021 20:17:01 +0000 Received: (at 50806) by debbugs.gnu.org; 3 Oct 2021 20:16:18 +0000 Received: from localhost ([127.0.0.1]:35050 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mX7uE-0002kx-1Z for submit@debbugs.gnu.org; Sun, 03 Oct 2021 16:16:18 -0400 Received: from mail-pl1-f181.google.com ([209.85.214.181]:39793) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mX7u9-0002cT-Le for 50806@debbugs.gnu.org; Sun, 03 Oct 2021 16:16:17 -0400 Received: by mail-pl1-f181.google.com with SMTP id c4so9716225pls.6 for <50806@debbugs.gnu.org>; Sun, 03 Oct 2021 13:16:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=subject:to:cc:references:from:message-id:date:mime-version :in-reply-to:content-language:content-transfer-encoding; bh=NMYHLR5IzkVkk7a8Emg1rWqHbalLOGY/oHrJQCpHFB4=; b=k+HRxS74hwkXRuoTvvGcC1cQMgwh0R/eoMaaJ0BUDPfdIUR7EMPRiDdJyyM6lLPkcK bI/8Z7MjO2Gone6lCKR6kCWqX67tx3j/D3xyXcoZ34W1AGhuoT7LyBEsBZTiTrWcYw5u 1R+9yZUors7FoPWvj5bqfFDzHj+t+RYVwDJNYCep9+HFroK4BPDlIPWOudFQ8jpSCFLH bGwcaeulgBW8tUZFinJDenCqboSq5CNT30FWMB7hczP7GuYU1YM6GPc8MoDpQpDwSjQ1 7GpDOwDW/XsSvc1ugh0i85icqv2+hvRLsFoAiua0hjrrEHeyIw4sTa5hKSF4UQe+U+fx KekA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=NMYHLR5IzkVkk7a8Emg1rWqHbalLOGY/oHrJQCpHFB4=; b=llqL4zZLJpMeqok7TonLjPpvoJUDFxkZQks05f+Zcgl0BkljAA3IK27eHNnV0s0RhH pTYdzYBlcx/LZJHHO6TJGxUmxj8DV3B7c3KXMtTq9f3yOlj5vS8l9jdH/CxUfiQHIRN/ rznT9TwHYY8VVKEIEHQu488FxEDMOWT+jvtpGi4PqgV/0oe5QtQlyJeh9WPpgR7UaM0G BpAF+MsUFMYSeijEtY8G1qRWlZAKnbaOc4cdbqb4Tq+5YUI3PbTcjmF5H+5QVWLbDv/F mUdNerYtJJaLAoKFh1rUBfAZ/Sb7BEH02JvEjbSm9vxzmS0NnJ03w4rEqP4IXziOdIZj vTOw== X-Gm-Message-State: AOAM530tKgcqLhJRgWToFB0V/CNGyGgxU3ECj3Zt8o2wW007KDHGXXC3 iLJ9WKfi0k0AsvhlWtmPpIw= X-Google-Smtp-Source: ABdhPJzH70s7SkmfVqu0UobQnK8rkw6uUQiRmAavR+EQo1SsG4ZWWkN6UiLBtqWxrGLb27sY6f8CJA== X-Received: by 2002:a17:90b:4c43:: with SMTP id np3mr8456610pjb.187.1633292167784; Sun, 03 Oct 2021 13:16:07 -0700 (PDT) Received: from [192.168.1.2] (cpe-76-168-148-233.socal.res.rr.com. [76.168.148.233]) by smtp.googlemail.com with ESMTPSA id s3sm13664069pjr.1.2021.10.03.13.16.06 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 03 Oct 2021 13:16:07 -0700 (PDT) References: <87tui8wakb.fsf@miha-pc> <25ed8125-3f78-c9c9-9324-d75e48e702c6@gmail.com> <87k0itc2ap.fsf@miha-pc> From: Jim Porter Message-ID: <3e19d87f-371b-31d5-cc1a-dd0b22659acf@gmail.com> Date: Sun, 3 Oct 2021 13:16:05 -0700 MIME-Version: 1.0 In-Reply-To: <87k0itc2ap.fsf@miha-pc> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Score: -0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) On 10/3/2021 12:54 PM, miha--- via Bug reports for GNU Emacs, the Swiss army knife of text editors wrote: > Ok, thanks. I have actually already prepared patches for all these > features: full-color in ansi-color.el and term.el and also "basic" ANSI > escapes 1-8 for term.el that you mentioned. > > I guess there's no harm in sending them right now. I took a brief look at these and they seem reasonable to my eyes. It'll be nice to have (mostly) complete support for reading ANSI colors in Emacs. Thinking about it a bit more, one thing that might be nice to add for the first patch would be some additional tests to be sure that `ansi-color-context-region' and `ansi-color-context' work as expected (i.e. testing that multiple calls to `ansi-color-apply-on-region' and similar produce the correct results). That's one of the trickier bits in ansi-color.el (to me, anyway), and it'd be good to be sure all the various cases still work there. That said, it might be best to let the maintainers take a look before spending too much time on further tests. >> I see you posted an updated patch that doesn't merge these vectors. I >> don't have an opinion here, although if we do merge them, it would >> probably be nice to get that into Emacs 28; other packages might >> conceivably want to let-bind those[1]. > > Indeed, if we wanted to merge them we'd have to do it in Emacs 28. > That's why I think its best to simply leave them un-merged. If there's a performance benefit to merging them, I think it would be nice to do so while we have the chance. Perhaps a patch that just merges the two vectors, and nothing else, would make sense for Emacs 28. Best to ask the maintainers in this case too, though. From unknown Wed Aug 20 03:37:10 2025 X-Loop: help-debbugs@gnu.org Subject: bug#50806: 27.2; [PATCH] Optimize ansi-color.el Resent-From: Lars Ingebrigtsen Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 04 Oct 2021 09:28:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 50806 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Cc: Jim Porter , 50806@debbugs.gnu.org Received: via spool by 50806-submit@debbugs.gnu.org id=B50806.163333966711803 (code B ref 50806); Mon, 04 Oct 2021 09:28:01 +0000 Received: (at 50806) by debbugs.gnu.org; 4 Oct 2021 09:27:47 +0000 Received: from localhost ([127.0.0.1]:35692 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mXKGA-00034I-Um for submit@debbugs.gnu.org; Mon, 04 Oct 2021 05:27:47 -0400 Received: from quimby.gnus.org ([95.216.78.240]:56654) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mXKG8-000345-Bn for 50806@debbugs.gnu.org; Mon, 04 Oct 2021 05:27:46 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnus.org; s=20200322; h=Content-Type:MIME-Version:Message-ID:In-Reply-To:Date: References:Subject:Cc:To:From:Sender:Reply-To:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=Z2u9KNjy/9QFev3MH9UFyJDC/rxriGnxg8WUXo4ZGsU=; b=TtGjMSmdtO3Mxgnc22XMtOIfXL uzADC791k8rTOA9XURo4QX/EvFEAb+vh9EIFHE4Zd8MjDQWQkbk+vIpnGGHfjvPZF4LStyYoa7LMr cZ9VtLKw/2gcWhEimYqGNcgEReZxQJx4zXdBVK1Fxcu4+oWnT3KxNOOHIk4dYyd5TqhU=; Received: from [84.212.220.105] (helo=elva) by quimby.gnus.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mXKFy-00017A-VN; Mon, 04 Oct 2021 11:27:37 +0200 From: Lars Ingebrigtsen References: <87tui8wakb.fsf@miha-pc> <25ed8125-3f78-c9c9-9324-d75e48e702c6@gmail.com> <87fsthc21u.fsf@miha-pc> X-Now-Playing: Sacred Paws's _Run Around The Sun_: "Life's Too Short" Date: Mon, 04 Oct 2021 11:27:34 +0200 In-Reply-To: <87fsthc21u.fsf@miha-pc> (miha@kamnitnik.top's message of "Sun, 03 Oct 2021 21:59:25 +0200") Message-ID: <87czolp2bd.fsf@gnus.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Report: Spam detection software, running on the system "quimby.gnus.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see @@CONTACT_ADDRESS@@ for details. Content preview: writes: > Ok, thanks. I have actually already prepared patches for all these > features: full-color in ansi-color.el and term.el and also "basic" ANSI > escapes 1-8 for term.el that you mentioned. > > I guess [...] Content analysis details: (-2.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-Spam-Score: -0.3 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.3 (-) writes: > Ok, thanks. I have actually already prepared patches for all these > features: full-color in ansi-color.el and term.el and also "basic" ANSI > escapes 1-8 for term.el that you mentioned. > > I guess there's no harm in sending them right now. We could apply both the patch to optimize ansi-color.el and add this new stuff now (to the Emacs trunk, i.e., Emacs 29), but there was some discussion about merging... er... something? That I didn't quite understand? :-) So just to clarify -- Subject: [PATCH] Optimize ansi-color.el and Subject: [PATCH 2/4] Add support for 256-color and 24bit ANSI colors in ansi-color are independent patches, and they should both be applied to Emacs 29? -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no From unknown Wed Aug 20 03:37:10 2025 X-Loop: help-debbugs@gnu.org Subject: bug#50806: 27.2; [PATCH] Optimize ansi-color.el Resent-From: Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 04 Oct 2021 10:04:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 50806 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Lars Ingebrigtsen Cc: Jim Porter , 50806@debbugs.gnu.org Received: via spool by 50806-submit@debbugs.gnu.org id=B50806.16333418218016 (code B ref 50806); Mon, 04 Oct 2021 10:04:01 +0000 Received: (at 50806) by debbugs.gnu.org; 4 Oct 2021 10:03:41 +0000 Received: from localhost ([127.0.0.1]:35741 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mXKov-00025C-4l for submit@debbugs.gnu.org; Mon, 04 Oct 2021 06:03:41 -0400 Received: from kamnitnik.top ([209.250.245.214]:41860) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mXKos-000253-Tf for 50806@debbugs.gnu.org; Mon, 04 Oct 2021 06:03:39 -0400 Received: from localhost (BSN-77-156-43.static.siol.net [193.77.156.43]) by kamnitnik.top (Postfix) with ESMTPSA id 2DBB59C700; Mon, 4 Oct 2021 10:03:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kamnitnik.top; s=mail; t=1633341817; bh=uF6b/QmLbxqgOKPJaidVpeq//qotNBRS4jEmQaLuqO4=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From; b=n9ZTBGE1i1OheqqK9SYYmWSYENrP7S2q9tNu4Dc9h5reW+sdnvNMp+cB21KJ1MevW U7TCrC6nm0LrxH+j4c8WSS77B1h5cVRV2n7rttpY9udUY2v+xT5Fu8sHHy3OFHVB/m i4i3kcWkSJMfe09PchRf+vVz+GJ5nmctbF6p4lYByJOJmCtpR5o1h8BIvB0Jia6hMl qJPCdkd0XSUL3ZSOYOSKWPhb6fy9k/6Q7HfyYctCPJFZBq+w2ZjSzx1acyqQJFZaf7 IcG9aRTrQDEd78DpTGhJ1W1Hw7N+1WQf3UU6j6qjrr/Cy/nOEASHNJFwxH4VAArAXK +LUe/VIQzWZ3w== From: In-Reply-To: <87czolp2bd.fsf@gnus.org> References: <87tui8wakb.fsf@miha-pc> <25ed8125-3f78-c9c9-9324-d75e48e702c6@gmail.com> <87fsthc21u.fsf@miha-pc> <87czolp2bd.fsf@gnus.org> Date: Mon, 04 Oct 2021 12:07:09 +0200 Message-ID: <87v92df6ia.fsf@miha-pc> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha256; protocol="application/pgp-signature" X-Spam-Score: 2.5 (++) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Lars Ingebrigtsen writes: > writes: > >> Ok, thanks. I have actually already prepared patches for all these >> features: full-color in ansi-color.el and term.el and also "basic" ANSI >> escapes 1-8 for ter [...] Content analysis details: (2.5 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 2.0 PDS_OTHER_BAD_TLD Untrustworthy TLDs [URI: kamnitnik.top (top)] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record 0.5 FROM_SUSPICIOUS_NTLD From abused NTLD X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 2.5 (++) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Lars Ingebrigtsen writes: > writes: > >> Ok, thanks. I have actually already prepared patches for all these >> features: full-color in ansi-color.el and term.el and also "basic" ANSI >> escapes 1-8 for ter [...] Content analysis details: (2.5 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 2.0 PDS_OTHER_BAD_TLD Untrustworthy TLDs [URI: kamnitnik.top (top)] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record 0.5 FROM_SUSPICIOUS_NTLD From abused NTLD 1.0 BULK_RE_SUSP_NTLD Precedence bulk and RE: from a suspicious TLD -1.0 MAILING_LIST_MULTI Multiple indicators imply a widely-seen list manager --=-=-= Content-Type: text/plain Content-Transfer-Encoding: quoted-printable Lars Ingebrigtsen writes: > writes: > >> Ok, thanks. I have actually already prepared patches for all these >> features: full-color in ansi-color.el and term.el and also "basic" ANSI >> escapes 1-8 for term.el that you mentioned. >> >> I guess there's no harm in sending them right now. > > We could apply both the patch to optimize ansi-color.el and add this new > stuff now (to the Emacs trunk, i.e., Emacs 29), but there was some > discussion about merging... er... something? That I didn't quite > understand? :-) Yeah sorry for the confusion. We were talking about "merging" two vector variables of length 8 into one vector variable of length 16, specifically, replacing the two 'ansi-color-*-colors-vector' variables with one 'ansi-color-colors-vector'. These two variables are public and introduced in Emacs 28. If we wanted to merge them, we'd have to do it on the Emacs-28 branch. However, the performance gain from having them merged is negligible, so I think there will be less complications if we just leave them as they are. This means that patching Emacs-28 isn't required and all my patches from my second mail onward are meant for Emacs 29. > > So just to clarify --=20 > > Subject: [PATCH] Optimize ansi-color.el > > and > > Subject: [PATCH 2/4] Add support for 256-color and 24bit ANSI colors in a= nsi-color > > are independent patches, and they should both be applied to Emacs 29? Yes, [PATCH] Optimize ansi-color.el (from my second e-mail) and [PATCH 2/4] Add support for 256-color and 24bit ANSI colors in ansi-col= or are meant to be applied to Emacs 29 on top of each-other. > > --=20 > (domestic pets only, the antidote for overdose, milk.) > bloggy blog: http://lars.ingebrigtsen.no --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQJHBAEBCAAxFiEEmxVnesoT5rQXvVXnswkaGpIVmT8FAmFa0k0THG1paGFAa2Ft bml0bmlrLnRvcAAKCRCzCRoakhWZPzPND/0dZ1g0eBNyseOofNj/BIuX/ICJh+FX fREQEMpIsFbyd8Q0/Ac4TwQu2BBUsUMhD7zGfTCOveo1dJeblStUq3yPKbE504rE cDOeA3TQ7hBcydS1Cmk9o1718h+ggwHIyUyd/ubqZ2FVxp77NDu0H8uOWPFSQUeX cv0qJxyvkWfWUZecOgXqsDw038kxKW+EpiJU6bJJlEQ636FtgJlO9NupLK3HUCVV Oa2H4X1dlb+WMAYaAXKiJJ4Xpq/2B6hdis0VybfxfUQWFPrMxdmNDjZgovPA0KED R0fKpchG+tUo5h13IJynUOpWtqR8oHonIaZE16mewYD6ci35Au70um+VzNJg+Frj JwAhBWp3C9vsGV6CiUQ5lxWHWqXe4uwoSZJo3ZLkNRccCUCBjZFs6I/O139RMaTE e3fXaIQvU8oqGePYaSiehn4Yc7OdiS0E5C5p4T+8thZcbKTHFmX7G7brI6szbI0u rm2Hr1mc0wrHk9CjgpPjxzzQjVWQMsN2T6sYFIRCRcF7REBSlpVihjsXcD/m96SO EohHb/R/CjaKMnUwO08mc0yh6GdWuX5kgIuCeCl73kidGSgr3QdNwKNujj8w+jkq nnbAv5hZF+DBVSrGlITBbSqofD5ovoQcmq3op7mJWfmsO4BUg14FErMkQ8X5MAbS KC999/IMjlipmg== =ub0E -----END PGP SIGNATURE----- --=-=-=-- From unknown Wed Aug 20 03:37:10 2025 X-Loop: help-debbugs@gnu.org Subject: bug#50806: 27.2; [PATCH] Optimize ansi-color.el Resent-From: Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 04 Oct 2021 10:15:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 50806 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Jim Porter , 50806@debbugs.gnu.org Cc: Lars Ingebrigtsen Received: via spool by 50806-submit@debbugs.gnu.org id=B50806.16333424598939 (code B ref 50806); Mon, 04 Oct 2021 10:15:01 +0000 Received: (at 50806) by debbugs.gnu.org; 4 Oct 2021 10:14:19 +0000 Received: from localhost ([127.0.0.1]:35745 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mXKzC-0002K6-6L for submit@debbugs.gnu.org; Mon, 04 Oct 2021 06:14:19 -0400 Received: from kamnitnik.top ([209.250.245.214]:41892) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mXKz6-0002Jr-S2 for 50806@debbugs.gnu.org; Mon, 04 Oct 2021 06:14:17 -0400 Received: from localhost (BSN-77-156-43.static.siol.net [193.77.156.43]) by kamnitnik.top (Postfix) with ESMTPSA id A46819C707; Mon, 4 Oct 2021 10:14:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kamnitnik.top; s=mail; t=1633342451; bh=Z23kgMqPKuVvl14NxHCVyJmQY9BuHQTaMj1Oup8ZU9k=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From; b=BJen/OImCf32XsYNikgVUZPDQdtjTh1N3ZI2LiLyaqPqH3lAxzrE/s++/dbDvb0o/ L1qpI+7PFyXGtpwPOsM30F5o8TN0qKLgiXvfQFa2TssCekptLKGQ4kZSyYYCJ6tvzi iZCBQXYoNkZKwlAliyN/YEuiKaT0RbSzPBNiK50L2z0aRca90HAGSMjYEpkpiadO4t qyj84hyEmpagaSKBGkuidCpKu5JqwxKLSCvelfs3edbn0d1XHNKOVcQSScCkiP2NH/ I/mroWlJYtc7k6uK28PjgoHgdZQn8tYWmpUJsmjH3oThaZo7YSFLiFYaRr/JkL+abW fLf1aF+dAa68g== From: In-Reply-To: <3e19d87f-371b-31d5-cc1a-dd0b22659acf@gmail.com> References: <87tui8wakb.fsf@miha-pc> <25ed8125-3f78-c9c9-9324-d75e48e702c6@gmail.com> <87k0itc2ap.fsf@miha-pc> <3e19d87f-371b-31d5-cc1a-dd0b22659acf@gmail.com> Date: Mon, 04 Oct 2021 12:17:43 +0200 Message-ID: <87sfxhf60o.fsf@miha-pc> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha256; protocol="application/pgp-signature" X-Spam-Score: 2.5 (++) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Jim Porter writes: > I took a brief look at these and they seem reasonable to my eyes. It'll > be nice to have (mostly) complete support for reading ANSI colors in Emacs. > > Thinking about it a bit more, one thing that [...] Content analysis details: (2.5 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 2.0 PDS_OTHER_BAD_TLD Untrustworthy TLDs [URI: kamnitnik.top (top)] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record 0.5 FROM_SUSPICIOUS_NTLD From abused NTLD X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 2.5 (++) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Jim Porter writes: > I took a brief look at these and they seem reasonable to my eyes. It'll > be nice to have (mostly) complete support for reading ANSI colors in Emacs. > > Thinking about it a bit more, one thing that [...] Content analysis details: (2.5 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 2.0 PDS_OTHER_BAD_TLD Untrustworthy TLDs [URI: kamnitnik.top (top)] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record 0.5 FROM_SUSPICIOUS_NTLD From abused NTLD 1.0 BULK_RE_SUSP_NTLD Precedence bulk and RE: from a suspicious TLD -1.0 MAILING_LIST_MULTI Multiple indicators imply a widely-seen list manager --=-=-= Content-Type: text/plain Content-Transfer-Encoding: quoted-printable Jim Porter writes: > I took a brief look at these and they seem reasonable to my eyes. It'll=20 > be nice to have (mostly) complete support for reading ANSI colors in Emac= s. > > Thinking about it a bit more, one thing that might be nice to add for > the first patch would be some additional tests to be sure that > `ansi-color-context-region' and `ansi-color-context' work as expected > (i.e. testing that multiple calls to `ansi-color-apply-on-region' and > similar produce the correct results). That's one of the trickier bits > in ansi-color.el (to me, anyway), and it'd be good to be sure all the > various cases still work there. > [...] > Good idea. For testing my patches, I already made some private tests of this nature (but only for ansi-color and not for term-mode). It should be easy to polish them up for ansi-color-tests.el. Will probably send a patch later. >>> I see you posted an updated patch that doesn't merge these vectors. I >>> don't have an opinion here, although if we do merge them, it would >>> probably be nice to get that into Emacs 28; other packages might >>> conceivably want to let-bind those[1]. >>=20 >> Indeed, if we wanted to merge them we'd have to do it in Emacs 28. >> That's why I think its best to simply leave them un-merged. > > If there's a performance benefit to merging them, I think it would be=20 > nice to do so while we have the chance. Perhaps a patch that just merges= =20 > the two vectors, and nothing else, would make sense for Emacs 28. Best=20 > to ask the maintainers in this case too, though. The performance benefit I measured was negligible so I think it's fine to just focus on Emacs 29. --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQJHBAEBCAAxFiEEmxVnesoT5rQXvVXnswkaGpIVmT8FAmFa1McTHG1paGFAa2Ft bml0bmlrLnRvcAAKCRCzCRoakhWZP1aKEADBGLRyRlpx1EYmr+3frxmh1bFpbt6x jGOSCBiZWc2ceyDQ9q4m2WuQOn1+nvjcTrJCR6u7AnmIsRMXr1Sx09WJGVYCsPhZ rozCKOYb5S9/kFJL+GCeltf9QuCLtvnRKj1OC2CP9QxidBaKH15WupE6rFzchKNo otZeT/wPMeR0C1bCjQRQgDPccHdv6A3DP4arvjH3u8ionsNE9yDRo16qtRbUFie1 uSVFjpBBbqh7KK78Tjz4BDKFBolMcfd2nbti+yKcCveiDh4H2hDCEvWc7n43aJpz D5k9Yeeotr2yXYbYz+BZmA+uSIc8JMSAzFVuTT6lCiG8LsOUcz+UIGkQY5ach9rf 8fgQdIvvW99Q2B3/bjCH0cW+4qNalNCF1jRWwfOTKdQm2OEmEaaaxA71WLqs7OLG 1ILO7IxmU5DTw1myBoujbESS/ek9tREw5kunbklX6dFC+jVaQJxXUKnqpmo+k8gg LQLA+ii1AWwA5uxZ6ULnt0TTX1cFWC212NuDMEO4BPKp6ke0KUvgIzV8fcTxPJOx +PlZ0Aw9GO3rrbretHyXY5DCAl4CW/u6qYzm6B+EpM5fZDD+7X2euLoZQseIaFjG vlY2aM1P4O8ZKO9HSqxEB7yFB2EvdAj2pvZ3OFlP4DsIjARcsz6ikQyaWe+J56Vs AEN6gSdNWNimbg== =2DNf -----END PGP SIGNATURE----- --=-=-=-- From unknown Wed Aug 20 03:37:10 2025 X-Loop: help-debbugs@gnu.org Subject: bug#50806: 27.2; [PATCH] Optimize ansi-color.el Resent-From: Lars Ingebrigtsen Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 05 Oct 2021 06:57:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 50806 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Cc: Jim Porter , 50806@debbugs.gnu.org Received: via spool by 50806-submit@debbugs.gnu.org id=B50806.16334169954762 (code B ref 50806); Tue, 05 Oct 2021 06:57:01 +0000 Received: (at 50806) by debbugs.gnu.org; 5 Oct 2021 06:56:35 +0000 Received: from localhost ([127.0.0.1]:38858 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mXeNP-0001Ek-Fj for submit@debbugs.gnu.org; Tue, 05 Oct 2021 02:56:35 -0400 Received: from quimby.gnus.org ([95.216.78.240]:38448) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mXeNN-0001ES-Qa for 50806@debbugs.gnu.org; Tue, 05 Oct 2021 02:56:34 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnus.org; s=20200322; h=Content-Type:MIME-Version:Message-ID:In-Reply-To:Date: References:Subject:Cc:To:From:Sender:Reply-To:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=aVdPOu9xaOz7WIksGSty9RR17Jm9MZ4DvYAsj0N+vi8=; b=fN9ftYpoFRKxB76qHkaWTufxa3 +wpebUmkVihG25LepSCmaTSflkeB/NGQDRjyxS5/skTaK3XY+enO7CwrLvqKGJRMMPl6mWEGzh9ai D10/nBhkvbs+9hC1Wrs7Nn/FGTDK/Bj0MY8k1n7NRLZ4WSO6C113PlIw2KYr2FaqcJ8c=; Received: from [84.212.220.105] (helo=elva) by quimby.gnus.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mXeND-00046O-Ip; Tue, 05 Oct 2021 08:56:26 +0200 From: Lars Ingebrigtsen References: <87tui8wakb.fsf@miha-pc> <25ed8125-3f78-c9c9-9324-d75e48e702c6@gmail.com> <87fsthc21u.fsf@miha-pc> <87czolp2bd.fsf@gnus.org> <87v92df6ia.fsf@miha-pc> X-Now-Playing: Boris's _NO_: "Interlude" Date: Tue, 05 Oct 2021 08:56:23 +0200 In-Reply-To: <87v92df6ia.fsf@miha-pc> (miha@kamnitnik.top's message of "Mon, 04 Oct 2021 12:07:09 +0200") Message-ID: <87bl447yeg.fsf@gnus.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Report: Spam detection software, running on the system "quimby.gnus.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see @@CONTACT_ADDRESS@@ for details. Content preview: writes: > Yes, [PATCH] Optimize ansi-color.el (from my second e-mail) > and [PATCH 2/4] Add support for 256-color and 24bit ANSI colors in ansi-color > > are meant to be applied to Emacs 29 on top of each-oth [...] Content analysis details: (-2.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-Spam-Score: -0.3 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.3 (-) writes: > Yes, [PATCH] Optimize ansi-color.el (from my second e-mail) > and [PATCH 2/4] Add support for 256-color and 24bit ANSI colors in ansi-color > > are meant to be applied to Emacs 29 on top of each-other. Thanks; I've now applied all the patches, I think, and pushed to the trunk. -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no From debbugs-submit-bounces@debbugs.gnu.org Tue Oct 05 02:56:44 2021 Received: (at control) by debbugs.gnu.org; 5 Oct 2021 06:56:44 +0000 Received: from localhost ([127.0.0.1]:38861 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mXeNT-0001F0-MD for submit@debbugs.gnu.org; Tue, 05 Oct 2021 02:56:44 -0400 Received: from quimby.gnus.org ([95.216.78.240]:38464) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mXeNS-0001Eb-F4 for control@debbugs.gnu.org; Tue, 05 Oct 2021 02:56:38 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnus.org; s=20200322; h=Subject:From:To:Message-Id:Date:Sender:Reply-To:Cc: MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=ki+jGphck9jEOYgOiqJltMxfGn20M95A5zGaZTf5kLA=; b=MYl2LVg178ewWSIXF1BABzoV7o pH/7M7RkAi0Wa0flzKS2vP7c7eYIqouzm7rc7JLQyzGHkTrU0j2tX4L0h+v02R+kwO6UOayu80rFk wRM8M7GsuqWcD8+E5yCF4AGdme1v/C/SkfruNe4OUYj2/HH3YBbJ7AJTEPGV57k9LWhE=; Received: from [84.212.220.105] (helo=elva) by quimby.gnus.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mXeNK-00046c-Nn for control@debbugs.gnu.org; Tue, 05 Oct 2021 08:56:32 +0200 Date: Tue, 05 Oct 2021 08:56:30 +0200 Message-Id: <87a6jo7ye9.fsf@gnus.org> To: control@debbugs.gnu.org From: Lars Ingebrigtsen Subject: control message for bug #50806 X-Spam-Report: Spam detection software, running on the system "quimby.gnus.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see @@CONTACT_ADDRESS@@ for details. Content preview: close 50806 29.1 quit Content analysis details: (-2.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) close 50806 29.1 quit From unknown Wed Aug 20 03:37:10 2025 X-Loop: help-debbugs@gnu.org Subject: bug#50806: 27.2; [PATCH] Optimize ansi-color.el Resent-From: Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 05 Oct 2021 11:15:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 50806 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Lars Ingebrigtsen Cc: Jim Porter , 50806@debbugs.gnu.org Received: via spool by 50806-submit@debbugs.gnu.org id=B50806.16334324739097 (code B ref 50806); Tue, 05 Oct 2021 11:15:02 +0000 Received: (at 50806) by debbugs.gnu.org; 5 Oct 2021 11:14:33 +0000 Received: from localhost ([127.0.0.1]:39185 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mXiP3-0002Mf-2W for submit@debbugs.gnu.org; Tue, 05 Oct 2021 07:14:33 -0400 Received: from kamnitnik.top ([209.250.245.214]:47020) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mXiP0-0002MU-8R for 50806@debbugs.gnu.org; Tue, 05 Oct 2021 07:14:31 -0400 Received: from localhost (BSN-77-156-43.static.siol.net [193.77.156.43]) by kamnitnik.top (Postfix) with ESMTPSA id BA42F9C707; Tue, 5 Oct 2021 11:14:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kamnitnik.top; s=mail; t=1633432468; bh=1jRgct1BDLnwr/NLfnZg+/L1Ciq2iJfMbAQIOTBYfus=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From; b=DL8QIGj6uHSf/jqIIdIzZMYj7gVZez7+jwu8A2Q1Hpva0POcMiEV4969VRmV3MQ8H GD9t1Kr6mLlr2/p2ANGZzy0sFD+dd7VvhU/RDT88sGQ0b6szN1ZC4KAV+SLuUK/Qs3 YrN/woWdrhZ5fM3IslU55Gv4LNh2UY1HOYVUhBwgAVNWHdgqtMwp/kBiCZp2GIzVKJ flhnln3neS3CGAGPq6sDVgzfRe4+/Ap20uzT9e2YnvSmXXtj61mGPgEzxX2o/lmJGH cBXrRoU8IcHZD3QTr4VpJd7pWQDnd5EIFaVKSqo4Vut0kUwUuOYucJFoFcd5U8QT2A 5Xql6KDy5Kqow== From: In-Reply-To: <87bl447yeg.fsf@gnus.org> References: <87tui8wakb.fsf@miha-pc> <25ed8125-3f78-c9c9-9324-d75e48e702c6@gmail.com> <87fsthc21u.fsf@miha-pc> <87czolp2bd.fsf@gnus.org> <87v92df6ia.fsf@miha-pc> <87bl447yeg.fsf@gnus.org> Date: Tue, 05 Oct 2021 13:18:02 +0200 Message-ID: <87h7dv7mad.fsf@miha-pc> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="==-=-="; micalg=pgp-sha256; protocol="application/pgp-signature" X-Spam-Score: 2.5 (++) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Lars Ingebrigtsen writes: > writes: > >> Yes, [PATCH] Optimize ansi-color.el (from my second e-mail) >> and [PATCH 2/4] Add support for 256-color and 24bit ANSI colors in ansi-color >> >> are meant to be a [...] Content analysis details: (2.5 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 2.0 PDS_OTHER_BAD_TLD Untrustworthy TLDs [URI: kamnitnik.top (top)] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record 0.5 FROM_SUSPICIOUS_NTLD From abused NTLD X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 2.5 (++) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Lars Ingebrigtsen writes: > writes: > >> Yes, [PATCH] Optimize ansi-color.el (from my second e-mail) >> and [PATCH 2/4] Add support for 256-color and 24bit ANSI colors in ansi-color >> >> are meant to be a [...] Content analysis details: (2.5 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 2.0 PDS_OTHER_BAD_TLD Untrustworthy TLDs [URI: kamnitnik.top (top)] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record 0.5 FROM_SUSPICIOUS_NTLD From abused NTLD 1.0 BULK_RE_SUSP_NTLD Precedence bulk and RE: from a suspicious TLD -1.0 MAILING_LIST_MULTI Multiple indicators imply a widely-seen list manager --==-=-= Content-Type: multipart/mixed; boundary="=-=-=" --=-=-= Content-Type: text/plain Lars Ingebrigtsen writes: > writes: > >> Yes, [PATCH] Optimize ansi-color.el (from my second e-mail) >> and [PATCH 2/4] Add support for 256-color and 24bit ANSI colors in ansi-color >> >> are meant to be applied to Emacs 29 on top of each-other. > > Thanks; I've now applied all the patches, I think, and pushed to the > trunk. > Thanks. Here, I attach two more patches, one with minor documentation fixes and one with a new test for incomplete ANSI escape sequences. Thanks and best regards. --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-Documentation-fixes-for-recent-ansi-color-additions.patch Content-Transfer-Encoding: quoted-printable From=20a5dcb656893330cfed57ccadc48bfa9c96321a55 Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?Miha=3D20Rihtar=3DC5=3DA1i=3DC4=3D8D?=3D Date: Tue, 5 Oct 2021 11:14:22 +0200 Subject: [PATCH 1/2] Documentation fixes for recent ansi-color additions * lisp/ansi-color.el (ansi-color-context-region): Improve formatting. * lisp/term.el (term-ansi-face-already-done): (term-handle-colors-array): Fix obsoleting version (bug#50806). =2D-- lisp/ansi-color.el | 4 ++-- lisp/term.el | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lisp/ansi-color.el b/lisp/ansi-color.el index aaaf60cd00..2e51264ec3 100644 =2D-- a/lisp/ansi-color.el +++ b/lisp/ansi-color.el @@ -656,9 +656,9 @@ ansi-color-context-region "Context saved between two calls to `ansi-color-apply-on-region'. This is a list of the form (FACE-VEC MARKER) or nil. FACE-VEC represents the state the last call to `ansi-color-apply-on-region' =2Dended with, currently a list of the form +ended with, currently a list of the form: =20 =2D(BASIC-FACES FG BG). + (BASIC-FACES FG BG). =20 BASIC-FACES is a bool-vector that specifies which basic faces from `ansi-color-basic-faces-vector' to apply. FG and BG are diff --git a/lisp/term.el b/lisp/term.el index ce086c379b..0e36e877e6 100644 =2D-- a/lisp/term.el +++ b/lisp/term.el @@ -723,7 +723,7 @@ term-ansi-current-reverse (defvar term-ansi-current-invisible nil) =20 (make-obsolete-variable 'term-ansi-face-already-done =2D "it doesn't have any effect." "28.1") + "it doesn't have any effect." "29.1") =20 ;;; Faces (defvar ansi-term-color-vector @@ -3346,7 +3346,7 @@ term--color-as-hex ;; have any bold/underline/fg/bg/reverse combination. -mm =20 (defun term-handle-colors-array (parameter) =2D (declare (obsolete term--handle-colors-list "28.1")) + (declare (obsolete term--handle-colors-list "29.1")) (term--handle-colors-list (list parameter))) =20 (defun term--handle-colors-list (parameters) =2D-=20 2.33.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0002-Add-tests-for-incomplete-escape-sequences-in-ansi-co.patch Content-Transfer-Encoding: quoted-printable From=20c73b559cc705ef3f01eb04ad62947a59ed316657 Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?Miha=3D20Rihtar=3DC5=3DA1i=3DC4=3D8D?=3D Date: Tue, 5 Oct 2021 12:20:45 +0200 Subject: [PATCH 2/2] Add tests for incomplete escape sequences in ansi-color-tests * test/lisp/ansi-color-tests.el (ansi-color-tests-equal-props): New function. (ansi-color-incomplete-sequences-test): New ert test (bug#50806). =2D-- test/lisp/ansi-color-tests.el | 82 +++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/test/lisp/ansi-color-tests.el b/test/lisp/ansi-color-tests.el index 16a1ba4a89..14a14ca4f0 100644 =2D-- a/test/lisp/ansi-color-tests.el +++ b/test/lisp/ansi-color-tests.el @@ -24,6 +24,7 @@ ;;; Code: =20 (require 'ansi-color) +(eval-when-compile (require 'cl-lib)) =20 (defvar ansi-color-tests--strings (let ((bright-yellow (face-foreground 'ansi-color-bright-yellow nil 'def= ault)) @@ -61,6 +62,17 @@ ansi-color-tests--strings ("\e[48;2;135;255;255;1mHello World\e[0m" "Hello World" (ansi-color-bold (:background ,custom-color)))))) =20 +(defun ansi-color-tests-equal-props (o1 o2) + "Return t if two Lisp objects have similar structure and contents. +While `equal-including-properties' compares text properties of +strings with `eq', this function compares them with `equal'." + (or (equal-including-properties o1 o2) + (and (stringp o1) + (equal o1 o2) + (cl-loop for i below (length o1) + always (equal (text-properties-at i o1) + (text-properties-at i o2)))))) + (ert-deftest ansi-color-apply-on-region-test () (pcase-dolist (`(,input ,text ,face) ansi-color-tests--strings) (with-temp-buffer @@ -91,6 +103,76 @@ ansi-color-apply-on-region-preserving-test (ansi-color-apply-on-region (point-min) (point-max) t) (should (equal (buffer-string) (car pair)))))) =20 +(ert-deftest ansi-color-incomplete-sequences-test () + (let* ((strs (list "\e[" "2;31m Hello World " + "\e" "[108;5;12" "3m" "Greetings" + "\e[0m\e[35;6m" "Hello")) + (complete-str (apply #'concat strs)) + (filtered-str) + (propertized-str) + (ansi-color-apply-face-function + #'ansi-color-apply-text-property-face) + (ansi-filt (lambda (str) (ansi-color-filter-apply + (copy-sequence str)))) + (ansi-app (lambda (str) (ansi-color-apply + (copy-sequence str))))) + + (with-temp-buffer + (setq filtered-str + (replace-regexp-in-string "\e\\[.*?m" "" complete-str)) + (setq propertized-str (funcall ansi-app complete-str)) + + (should-not (ansi-color-tests-equal-props + filtered-str propertized-str)) + (should (equal filtered-str propertized-str))) + + ;; Tests for `ansi-color-filter-apply' + (with-temp-buffer + (should (equal-including-properties + filtered-str + (funcall ansi-filt complete-str)))) + + (with-temp-buffer + (should (equal-including-properties + filtered-str + (mapconcat ansi-filt strs "")))) + + ;; Tests for `ansi-color-filter-region' + (with-temp-buffer + (insert complete-str) + (ansi-color-filter-region (point-min) (point-max)) + (should (equal-including-properties + filtered-str (buffer-string)))) + + (with-temp-buffer + (dolist (str strs) + (let ((opoint (point))) + (insert str) + (ansi-color-filter-region opoint (point)))) + (should (equal-including-properties + filtered-str (buffer-string)))) + + ;; Test for `ansi-color-apply' + (with-temp-buffer + (should (ansi-color-tests-equal-props + propertized-str + (mapconcat ansi-app strs "")))) + + ;; Tests for `ansi-color-apply-on-region' + (with-temp-buffer + (insert complete-str) + (ansi-color-apply-on-region (point-min) (point-max)) + (should (ansi-color-tests-equal-props + propertized-str (buffer-string)))) + + (with-temp-buffer + (dolist (str strs) + (let ((opoint (point))) + (insert str) + (ansi-color-apply-on-region opoint (point)))) + (should (ansi-color-tests-equal-props + propertized-str (buffer-string)))))) + (provide 'ansi-color-tests) =20 ;;; ansi-color-tests.el ends here =2D-=20 2.33.0 --=-=-=-- --==-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQJHBAEBCAAxFiEEmxVnesoT5rQXvVXnswkaGpIVmT8FAmFcNGoTHG1paGFAa2Ft bml0bmlrLnRvcAAKCRCzCRoakhWZP9C1D/sH+2iktD83lYTmo4TGRKTRi125PGWA vDUGcKHTzEKn5vpwJYVyU0V5UV/clhdgT1M+Wib3hVslQwbWbQd0/VwNfYYUlP4W bUrq8MCcyBtStRvISai1dAvmjpRDsGBi6lXzxS7IQDyUMzbyObhHfbDFCwxAHEyR agawn5Is18sfBFDMsPL8F3NSiQQLrg8WJ2qDUJtaCavOaeGKV/yr1aQN7VrO5U7j xAzjjSnIdAKPKEBc8ZxmxdwDgXznHFtqqdLvdUfhcFlJ0hHAmUBmznNXeoPkiodu Uv6nnvGBYr+3MzQWbw6rEJNKHfl9AC/OzBbJwZtiA9pje+phb2KrdbRkEU5M4kN+ U126Zij19QH1u0O322/rLNahTknUllAB/oiTDRRbPEe0nl0aZnw2C7/jEk6nDRwl vP6Cd5X0tpa90FC0fOy4XIkFw4h0O0fxLrqa596dVv0TmbmYaiRQ8ahyGPhgLPmB a5om5bfzLJbHm4NNJ10oJFecrlV124NF3gbgrkQoREtrKD4DKX8M4t+zldr8j7A/ VU/fPt88vV3NCYmcl3PkjpWpc8lLKZd6WOAvWppsyk7pxjGmTJJXv8TdxHhzhkH8 IqNOD1PHckXldehkFCzoG0SF5RhOsGiQQ08Jm32wKK1uNb2/zT0R/J3vvDNWy+Mq dF5ctg0s+eNECQ== =/47p -----END PGP SIGNATURE----- --==-=-=-- From unknown Wed Aug 20 03:37:10 2025 X-Loop: help-debbugs@gnu.org Subject: bug#50806: 27.2; [PATCH] Optimize ansi-color.el Resent-From: Lars Ingebrigtsen Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 06 Oct 2021 08:52:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 50806 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Cc: Jim Porter , 50806@debbugs.gnu.org Received: via spool by 50806-submit@debbugs.gnu.org id=B50806.163351029015402 (code B ref 50806); Wed, 06 Oct 2021 08:52:02 +0000 Received: (at 50806) by debbugs.gnu.org; 6 Oct 2021 08:51:30 +0000 Received: from localhost ([127.0.0.1]:42468 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mY2eA-00040M-Ej for submit@debbugs.gnu.org; Wed, 06 Oct 2021 04:51:30 -0400 Received: from quimby.gnus.org ([95.216.78.240]:51136) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mY2e6-000405-Ow for 50806@debbugs.gnu.org; Wed, 06 Oct 2021 04:51:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnus.org; s=20200322; h=Content-Type:MIME-Version:Message-ID:In-Reply-To:Date: References:Subject:Cc:To:From:Sender:Reply-To:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=t6ETcgl6kMqVsl4DQmVOZqxiDL8VTjPfPckYqm6C+Cs=; b=mJ4o8pUXzcnV0QHnzs8i0alwdO SrQBqM9fIQalopsZ6zdxRpEmYtEm1UP6Ds0Mo0IxIUftLFBAz9bZi1MDSNzOK2Cvs2qe+W/ey3j2M Qzfu9jYL7jayfTl9EY75AqJeYOyLP9oAGNe38qBDLFaCPeEu/ajN2uuN+nGPFAALas4g=; Received: from [84.212.220.105] (helo=elva) by quimby.gnus.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mY2dx-00008K-8r; Wed, 06 Oct 2021 10:51:20 +0200 From: Lars Ingebrigtsen References: <87tui8wakb.fsf@miha-pc> <25ed8125-3f78-c9c9-9324-d75e48e702c6@gmail.com> <87fsthc21u.fsf@miha-pc> <87czolp2bd.fsf@gnus.org> <87v92df6ia.fsf@miha-pc> <87bl447yeg.fsf@gnus.org> <87h7dv7mad.fsf@miha-pc> X-Now-Playing: DJ Screw's _All Work, No Play_: "DJ Screw Lil Keke Fat Pat Herschelwood Hardheadz CD LP s feat Lil Keke Fat Pat Herschelwo" Date: Wed, 06 Oct 2021 10:51:15 +0200 In-Reply-To: <87h7dv7mad.fsf@miha-pc> (miha@kamnitnik.top's message of "Tue, 05 Oct 2021 13:18:02 +0200") Message-ID: <87o882fse4.fsf@gnus.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Report: Spam detection software, running on the system "quimby.gnus.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see @@CONTACT_ADDRESS@@ for details. Content preview: writes: > Here, I attach two more patches, one with minor documentation fixes and > one with a new test for incomplete ANSI escape sequences. Thanks; applied to Emacs 29. Content analysis details: (-2.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-Spam-Score: -0.3 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.3 (-) writes: > Here, I attach two more patches, one with minor documentation fixes and > one with a new test for incomplete ANSI escape sequences. Thanks; applied to Emacs 29. -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no