From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp12.migadu.com ([2001:41d0:403:4876::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms8.migadu.com with LMTPS id AJXpF1XjV2VEbwAAauVa8A:P1 (envelope-from ) for ; Fri, 17 Nov 2023 23:04:05 +0100 Received: from aspmx1.migadu.com ([2001:41d0:403:4876::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp12.migadu.com with LMTPS id AJXpF1XjV2VEbwAAauVa8A (envelope-from ) for ; Fri, 17 Nov 2023 23:04:05 +0100 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 0F94825869 for ; Fri, 17 Nov 2023 23:04:05 +0100 (CET) Authentication-Results: aspmx1.migadu.com; dkim=fail ("body hash did not verify") header.d=gmail.com header.s=20230601 header.b=LrdpcfuH; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org"; dmarc=fail reason="SPF not aligned (relaxed)" header.from=gmail.com (policy=none) ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1700258645; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:in-reply-to:in-reply-to: references:references:list-id:list-help:list-unsubscribe: list-subscribe:list-post:dkim-signature; bh=5JcbPO+lVEPp6qkqQQBYk8gaH7c9DqmX0hXCsGT3daI=; b=aS8Pv27xncNAneTYm6HFTeSP7u/MSaEoN4w6Ln1OHUwuQi0gv0AdbFF0gjFFDrcTiyRXv6 gQ7f/xLEdmU+9mJKp1ktsWWMqK/AGqBAfXR+jZyC4yPDA4vAGimqCmdeDcaAIbjdIBC3sS tNwmNwUKJyqwOh7XiO3S1t+aiQtewOWGE42hGnUhEzDI0gAdYK+qHfU/MIyjaN2j35KST+ j96qgCGb0/dCTsovD/gYifH/ZrzyDG4ISKinz98qS1mlD8QBrlGO8WWBO8y3WHrP0X9W7B UTroz8pU5mm4b3dHt33t0hCJrQDDX9EBnGGIf7uaIFTOpjbt/F2jlsOBZwT1jQ== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=fail ("body hash did not verify") header.d=gmail.com header.s=20230601 header.b=LrdpcfuH; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org"; dmarc=fail reason="SPF not aligned (relaxed)" header.from=gmail.com (policy=none) ARC-Seal: i=1; s=key1; d=yhetil.org; t=1700258645; a=rsa-sha256; cv=none; b=tNepTFfxzJz4KR5pBkaKwR11FESghycy4jNBRRoIEvAQWr+C8m9TeEPP/xbJS3fE/ZB2vc APNV8od6ucS5fSR374RRBHo1+6QdFKXOAm59Hetgid38gtQjd5jvdqNXBPnjT9qEE0TsjV hbvbB0oCe4UqC6sDSlg4st/z7CE3Xc4M7CCG/fliUHtyzTK48SGa19377wWqovW+6UKv5Z TUtvuNR14c4Z87Szpa5iOtxBIA+O9wPkRknRbQC6vHhK9L47M/J+OSCls7tUWGRkbAIT1n EGeuQ7KiVkFjCuiLHse1iTxrkfzPYJSURQGfljDRgqIYDJc5mjNvOYT0bP65Aw== Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1r46Ly-0006Rf-0W; Fri, 17 Nov 2023 16:26:18 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1r46Lw-0006RW-TJ for emacs-orgmode@gnu.org; Fri, 17 Nov 2023 16:26:16 -0500 Received: from mail-il1-x132.google.com ([2607:f8b0:4864:20::132]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1r46Ls-0006qT-Qx for emacs-orgmode@gnu.org; Fri, 17 Nov 2023 16:26:16 -0500 Received: by mail-il1-x132.google.com with SMTP id e9e14a558f8ab-3593f3ef420so2517825ab.1 for ; Fri, 17 Nov 2023 13:26:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700256370; x=1700861170; darn=gnu.org; h=mime-version:message-id:in-reply-to:date:subject:cc:to:from :user-agent:references:from:to:cc:subject:date:message-id:reply-to; bh=Pvj6/Virh/0x1MsZKkPgZyX+f/xEnIgziZ4zujcQ2fo=; b=LrdpcfuHfBLXZyA03qTgV+qxHmITHju7zyMYFjoISlAk6UPaBNtHIC9bLNT3LnuFMn UfmAOdmkGoHfsVmcMBTyPhN7Uuznmsb7JzkFrgO7nlBPmvl736WRSdRmBsQ4yKxdtxw2 hdR5B2fNwAGNLL2vURpGLMrCq6mSp2wgPFBR8AsojZfjPDyi6KzN+soc8Ml9GPuRjxQE HDWMNhLEBccNzHHrWiNBPI9qetrWHfO84KR2ra4hDEhbOd2HUWW8fIgCSyoyxLOya8sp Df4KT3ZVzH9evMwhoE3TWaCiF8zGZRYt7QUcGRAFLJmKp6ggoS76ZN6Dv5GTCV5YCIjS /OQw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700256370; x=1700861170; h=mime-version:message-id:in-reply-to:date:subject:cc:to:from :user-agent:references:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Pvj6/Virh/0x1MsZKkPgZyX+f/xEnIgziZ4zujcQ2fo=; b=ACYe+89wdxtUQGYr9HvPPLNSbc+4+l+QcuZwBO67Vqoa7M3tuQmisJgDwV6joG+HX6 XifkApJefkZTcP5FnOv9T9DQvfFEGvPIobMjOMefeEzpMQypNuw53dfNhs+GqFsOSb0e ls8YqweFH8fOblzXHEYgQOlrW3iZpZkT2kyBXoR+HUHoWFYEG3LSuJXYzI8VJH11nRo4 WAnah2RZTf2qNf3b3ny4poGVAyrTV0Hdd8koT9KekNNIPT+RvW+frUmsS9/OT3Nz+piV 9wJsfDIEmfwHS0zKdWP0ESALNE71YDl8VEzoT3IirQKOJxXO7DkTphwIozZqfIuhl/3b JvLA== X-Gm-Message-State: AOJu0YzIimXsqEbd40I4DeCLrtjH//9dV++78wdrg9ftbnLJHwePqRaT ztL9Y3+esNKQ6rAqq3i4N/a1nDY9CaF1FQ== X-Google-Smtp-Source: AGHT+IFUkLAg9hLBe9d5jHJk/iluj7ngW6yxtcgfmSTsFcDLsppoj7N3cyp9s2AmZwgDu/frmu4cLg== X-Received: by 2002:a92:502:0:b0:35a:eff8:a06e with SMTP id q2-20020a920502000000b0035aeff8a06emr824911ile.0.1700256370470; Fri, 17 Nov 2023 13:26:10 -0800 (PST) Received: from entropy ([2601:243:283:930::91dc]) by smtp.gmail.com with ESMTPSA id y6-20020a056e02118600b0035acf801fe5sm715870ili.64.2023.11.17.13.26.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Nov 2023 13:26:09 -0800 (PST) References: <874jpuijpc.fsf@gmail.com> <87y1n6igvo.fsf@localhost> <878rev1q0k.fsf@gmail.com> <877cueonkj.fsf@localhost> <87zg6dez93.fsf@gmail.com> <871qjobhwa.fsf@localhost> <877ct5fzt6.fsf@gmail.com> <87a5y1mnj0.fsf@localhost> User-agent: mu4e 1.8.13; emacs 30.0.50 From: Nathaniel Nicandro To: Ihor Radchenko Cc: Nathaniel Nicandro , emacs-orgmode Subject: Re: [PATCH] Highlight ANSI sequences in the whole buffer (was [PATCH] ANSI color on example blocks and fixed width elements) Date: Fri, 17 Nov 2023 15:18:33 -0600 In-reply-to: <87a5y1mnj0.fsf@localhost> Message-ID: <87msvcgjgv.fsf@gmail.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Received-SPF: pass client-ip=2607:f8b0:4864:20::132; envelope-from=nathanielnicandro@gmail.com; helo=mail-il1-x132.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: emacs-orgmode-bounces+larch=yhetil.org@gnu.org X-Migadu-Country: US X-Migadu-Flow: FLOW_IN X-Migadu-Spam-Score: -3.39 X-Spam-Score: -3.39 X-Migadu-Queue-Id: 0F94825869 X-Migadu-Scanner: mx10.migadu.com X-TUID: IvWXz5IRIZOB --=-=-= Content-Type: text/plain Ihor Radchenko writes: > I think that the most reasonable approach to fontify ANSI sequences will > be the following: > > 1. We will consider ANSI within (a) all greater elements and lesser > elements that have RESULTS affiliated keyword (indicating that they > are result of code block evaluation); (b) otherwise, just lesser > elements, like paragraph, src block, example block, export block, > etc., but _not_ tables (c) otherwise, within verbatim-like objects, > like code, export-snippet, inline-src-block, table-cell, verbatim. > > The three groups above should be declared via variables, so that > users can tweak them as necessary. > > 2. If ANSI sequence is encountered inside a verbatim-like object and we > did not see any ANSI sequences within parent element or greater > element, limit ANSI triggers to the current object. > > Example: > > #+RESULTS: > Lorem upsum =valor=. Some more text. > > (only "valor" will be affected) > > 3. If the first ANSI sequence is encountered inside element and outside > verbatim-like object, the rest of the element is affected, including > all the objects. > > Example: > > #+RESULTS: > Lorem upsum =valor=. Some more text. > > (the first ANSI affects everything, including verbatim; the second > ANSI also affects everything) > > 4. If the first ANSI sequence is encountered inside greater element with > RESULTS affiliated keyword, all the lesser elements inside will be > affected. > > Example: > > #+RESULTS: > :drawer: > Lorem upsum =valor=. Some more text. > > Another paragraph inside drawer. > :end: > > (everything down to :end: is affected) > > or > > #+RESULTS: > - list > - one > - two > - three > Hello Ihor, Attached is the updated version of the patch. I've also attached an updated file that I've been using for testing the feature. What I have is essentially a function, org-fontify-ansi-sequences, that scans the buffer for an ANSI sequence and depending on the element-context processes the region that should be affected according to the rules you stated (see above). The org-fontify-ansi-sequences-1 function scans the buffer element-wise and processes the appropriate regions of the elements, even if no sequences appear in those regions, according to an ansi-context. This is to support the fourth rule you mentioned. Note that modifications to highlighted regions hasn't really been considered so if you have a scenario like #+RESULTS: - Paragraph one - Paragraph two Line 3 where the sequence affects everything down to "Line 3" and you make a modification to line three, the fontification due to the sequence disappears on that line. Also note that lesser elements contained in greater elements that don't have a RESULTS keyword are handled at the lesser element level so if you have something like #+begin_center Paragraph one. Paragraph two. #+end_center It would be the same as if you just had the paragraphs without the greater element. Please review the code and let me know what you think and how you think we can move forward on this feature. Thanks in advance. --=-=-= Content-Type: text/x-org Content-Disposition: attachment; filename=test-ansi.org Content-Transfer-Encoding: 8bit Content-Description: Example Org file #+TITLE: Test Section 1 * Greater elements :PROPERTIES: :CUSTOM_ID: 123 :END: #+begin_center Inner paragraph one Inner paragraph two #+end_center :drawer: Inner paragraph one Inner paragraph two :end: #+BEGIN: dblock1 :scope subtree :maxlevel 2 - Item 1 - Item 2 - Item 3 - Item 4 #+END: [fn:1] Footnote definition *************** TODO Inline task 1 Inner contents *************** END *************** TODO Inline task 2 - Paragraph one - Paragraph two - Paragraph three - Paragraph four | cell 1 | cell 2 | | cell 3 | cell 4 | #+begin_quote open  #+end_quote should not be highlighted #+begin_quote close  #+end_quote * Lesser elements :PROPERTIES: :DESCRIPTION: value :END: #+CALL: fn(str="text") # Line one #+begin_comment Line one Line two #+end_comment %%(diary-anniversary 10 31 1948) Arthur's Birthday #+begin_example Line one Line two #+end_example #+begin_export latex Line one Line two #+end_export : Line one : Line two #+AUTHOR: First Last \begin{quote} Line one Line two \end{quote} Paragraph one Line two #+begin_src python for x in y: print(x + "test") #+end_src * Object contexts =verbatim= one Lorem upsum =valor=. Some more text. This is a paragraph src_python{return "testing"} {{{results(=testing=)}}} with multiple inline src_python{return 5*4} {{{results(=20=)}}} source blocks. An inline source block src_python{return 1+ 1 without an end. src_python{return "testing"}.  Paragraph =one= _underlined  text *bold  text * underlined  text_ _underlined  text_ plain text _underlined  text_ _underlined  text *bold  te /italic/ xt  end* underlined  text_ _underlined  text *bold  te /italic/ xt* underlined  text_ _underlined  text_ plain _underlined  text_ * Greater elements with RESULTS keyword #+RESULTS: :drawer: Lorem upsum =valor=. Some more text. Another paragraph inside drawer. :end: #+RESULTS: :RESULTS: Paragraph one. #+begin_example - test - test #+end_example Paragraph two. :END: #+RESULTS: - list - one - three - two - three #+RESULTS: - [ ] Checkbox - - #+RESULTS: - List item - [@5] List item :drawer: Interior - list inner - one two three four five six :end: - tag :: description #+RESULTS: - Item 1 - Item 2 | cell 1 | cell 2 | | cell 3 | cell 4 | --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Highlight-ANSI-escape-sequences.patch Content-Description: Patch >From 66baf6e1d435974fb4c51cc47eb5b3ace3feb22c Mon Sep 17 00:00:00 2001 From: Nathaniel Nicandro Date: Tue, 9 May 2023 19:58:11 -0500 Subject: [PATCH] Highlight ANSI escape sequences * etc/ORG-NEWS: Describe the new feature. * org.el (org-fontify-ansi-sequences): New customization variable and function which does the work of fontifying the sequences. (org-ansi-highlightable-elements) (org-ansi-highlightable-objects): New customization variables. (org-ansi-new-context, org-ansi-process-region) (org-ansi-process-block, org-ansi-process-paragraph) (org-ansi-process-fixed-width) (org-fontify-ansi-sequences-1): New functions. (org-set-font-lock-defaults): Add the `org-fontify-ansi-sequences` function to the font-lock keywords. (org-ansi-mode): New minor mode to enable/disable highlighting of the sequences. Enabled in Org buffers by default. --- etc/ORG-NEWS | 12 +++ lisp/org.el | 236 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 248 insertions(+) diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 1207d6f..76a81e3 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -492,6 +492,18 @@ Currently implemented options are: iCalendar programs support this usage. ** New features +*** ANSI escape sequences are now highlighted in the whole buffer + +A new customization ~org-fontify-ansi-sequences~ is available which +tells Org to highlight all ANSI sequences in the buffer if non-nil and +the new minor mode ~org-ansi-mode~ is enabled. + +To disable highlighting of the sequences you can either +disable ~org-ansi-mode~ or set ~org-fontify-ansi-sequences~ to ~nil~ +and =M-x org-mode-restart RET=. Doing the latter will disable +highlighting of sequences in all newly opened Org buffers whereas +doing the former disables highlighting locally to the current buffer. + *** =ob-plantuml.el=: Support tikz file format output =ob-plantuml.el= now output =tikz= :file format via diff --git a/lisp/org.el b/lisp/org.el index d2cd0b9..64a853c 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -81,6 +81,7 @@ (eval-when-compile (require 'gnus-sum)) (require 'calendar) (require 'find-func) (require 'format-spec) +(require 'ansi-color) (condition-case nil (load (concat (file-name-directory load-file-name) @@ -3608,6 +3609,12 @@ (defcustom org-fontify-whole-block-delimiter-line t :group 'org-appearance :type 'boolean) +(defcustom org-fontify-ansi-sequences t + "Non-nil means to highlight ANSI escape sequences." + :group 'org-appearance + :type 'boolean + :package-version '(Org . "9.7")) + (defcustom org-highlight-latex-and-related nil "Non-nil means highlight LaTeX related syntax in the buffer. When non-nil, the value should be a list containing any of the @@ -5598,6 +5605,208 @@ (defun org-fontify-extend-region (beg end _old-len) (cons beg (or (funcall extend "end" "]" 1) end))) (t (cons beg end)))))) +(defcustom org-ansi-highlightable-elements + '(plain-list drawer + example-block export-block fixed-width paragraph) + "A list of element types that will have ANSI sequences processed." + :type '(list (symbol :tag "Element Type")) + :version "9.7" + :group 'org-appearance) + +(defcustom org-ansi-highlightable-objects + '(bold code export-snippet italic macro + strike-through table-cell underline verbatim) + "A list of object types that will have ANSI sequences processed." + :type '(list (symbol :tag "Object Type")) + :version "9.7" + :group 'org-appearance) + +(defun org-ansi-new-context (pos) + (list (list (make-bool-vector 8 nil) + nil nil) + (copy-marker pos))) + +(defun org-ansi-process-region (beg end &optional context) + (or context (setq context (org-ansi-new-context beg))) + (move-marker (cadr context) beg) + (let ((ansi-color-context-region context) + (ansi-color-apply-face-function + (lambda (beg end face) + (font-lock-prepend-text-property beg end 'face face)))) + (ansi-color-apply-on-region beg end t))) + +(defun org-ansi-process-block (el &optional context) + (let ((beg (org-element-property :begin el)) + (end (org-element-property :end el))) + (save-excursion + (goto-char beg) + (while (org-at-keyword-p) + (forward-line)) + (setq beg (line-beginning-position 2))) + (save-excursion + (goto-char end) + (skip-chars-backward " \t\n") + (setq end (line-beginning-position))) + (org-ansi-process-region beg end context))) + +(defun org-ansi-process-paragraph (el &optional context) + ;; Compute the regions of the paragraph excluding inline + ;; source blocks. + (let ((pend (org-element-property :contents-end el)) beg end) + (push (point) beg) + (while (re-search-forward + "\\