From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Matthias Meulien Newsgroups: gmane.emacs.bugs Subject: bug#57821: 29.0.50; ANSI sequence not filtered in compilation buffer Date: Sat, 17 Sep 2022 19:21:10 +0200 Message-ID: <87tu55zzll.fsf@gmail.com> References: <87fsgt11w0.fsf@gmail.com> <87bkrg28lu.fsf@gmail.com> <877d23a7mh.fsf@gnus.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="13247"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux) Cc: 57821@debbugs.gnu.org To: Lars Ingebrigtsen Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Sep 17 19:22:15 2022 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oZbWA-0003I8-H0 for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 17 Sep 2022 19:22:14 +0200 Original-Received: from localhost ([::1]:41712 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oZbW9-0000Dz-GM for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 17 Sep 2022 13:22:13 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:47746) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oZbVy-0000Da-U1 for bug-gnu-emacs@gnu.org; Sat, 17 Sep 2022 13:22:02 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:48026) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oZbVy-0001OG-El for bug-gnu-emacs@gnu.org; Sat, 17 Sep 2022 13:22:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1oZbVy-0007JO-A7 for bug-gnu-emacs@gnu.org; Sat, 17 Sep 2022 13:22:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Matthias Meulien Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 17 Sep 2022 17:22:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 57821 X-GNU-PR-Package: emacs Original-Received: via spool by 57821-submit@debbugs.gnu.org id=B57821.166343528328041 (code B ref 57821); Sat, 17 Sep 2022 17:22:02 +0000 Original-Received: (at 57821) by debbugs.gnu.org; 17 Sep 2022 17:21:23 +0000 Original-Received: from localhost ([127.0.0.1]:47101 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oZbVK-0007IB-4C for submit@debbugs.gnu.org; Sat, 17 Sep 2022 13:21:23 -0400 Original-Received: from mail-wr1-f41.google.com ([209.85.221.41]:39607) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oZbVH-0007Hx-3j for 57821@debbugs.gnu.org; Sat, 17 Sep 2022 13:21:20 -0400 Original-Received: by mail-wr1-f41.google.com with SMTP id cc5so30928627wrb.6 for <57821@debbugs.gnu.org>; Sat, 17 Sep 2022 10:21:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:from:to:cc:subject:date; bh=ucP5sPnrFKncImbi1JD4KRM82a10FcQUoN+p/RNfgQA=; b=WvaLx/I9JCKGra2zLpgx/RiIVGH/8KXy/6MdizgreqeQfgvd7dDMNeF719y2iOAkhO h8KkwvcP6eu869LcfeFj6jK3hl/eyDp1fjFk48GjCpfehfmFvYODMUAko6KVCDg33lec vEy0/Mt0+98MAHl4ewdmCzPqgPhqt1qfd1KK8bV83FEco/UYG42mKHaBgm0m2o7dbpQh lMyjyi9eoO9naZ5nUhTGo3Uto1UtFS1KKtQP906jjJPQoc6eNdwEsFtc+AT8TQ1NBcUP 0CgHfSwXgUGMeMmY/0o58gxDYyyMtMXOCd5XOP7AkwZS60OBbtBcomOeM35QSpCXNCkg zB5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date; bh=ucP5sPnrFKncImbi1JD4KRM82a10FcQUoN+p/RNfgQA=; b=cQBIzFr3kaz/7IEaVwn2fEC0fIIPws0pfs5nSCvYUKCSmeWhW229EO2vGEFQsqz/rC P/gBlfN1vrxMeqY1iHMn27IKfxj8zYAxqyquq534M/7QC+irp9QzIGUxegv0koDOh3yL grU+PoSgaIaWMfKXBHbp/6w/TmcBPx7EpxKNokE1yRbxb2nxEdWCqNc7z9Ey+lLZRCZR bCiyXfzIa5SRaAj6DLlAQDEtJKCOPMkcroxd5utrHOsZmYj2BmvdrSA2oDwLHvib5KPJ WhyKBSKbRntCyEaPlri0oxA4WHFV1C4MyHl1cO4slFlaZIkm3VYCVsP1A8QvzFxQ28Jp QVlg== X-Gm-Message-State: ACrzQf2YX/TL7Ckuy0OF8nnKjJxImREijLKZtbIUTQMPXJGWZZRPJ1tX E6cZpwgp53OHtlAHR09urbNAEJQk1yI= X-Google-Smtp-Source: AMsMyM6Sf/sxSBwNtArYsAdTTgi20F0Ltp/AMwZA84O87Dn+x6AId+O1pWyICcAv8kmL4C4aBaYUnA== X-Received: by 2002:a05:6000:1f9d:b0:22a:e096:5a7f with SMTP id bw29-20020a0560001f9d00b0022ae0965a7fmr5007162wrb.50.1663435272951; Sat, 17 Sep 2022 10:21:12 -0700 (PDT) Original-Received: from carbon.localdomain ([2a01:e0a:245:c850:98f5:429a:aa8e:95bb]) by smtp.gmail.com with ESMTPSA id f17-20020a1cc911000000b003a61306d79dsm7572989wmb.41.2022.09.17.10.21.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 17 Sep 2022 10:21:11 -0700 (PDT) In-Reply-To: <877d23a7mh.fsf@gnus.org> (Lars Ingebrigtsen's message of "Fri, 16 Sep 2022 13:20:06 +0200") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:242890 Archived-At: --=-=-= Content-Type: text/plain Lars Ingebrigtsen writes: > Matthias Meulien writes: > >> The OSC sequences sent by flatpak-builder are meant to update the window >> title (See https://terminalguide.namepad.de/seq/osc-2/). I plan to >> provide an osc-compilation-filter (modelled on >> ansi-color-compilation-filter) to be added to compilation-filter-hook. >> >> One possible mode is to filter out all osc sequences. An other mode >> would be to call per command handlers as done by >> comint-osc-process-output. >> >> Any thought? > > The default could be to filter out all unknown OSC sequences? Here are three patchs that: - Extract current support of OSC escape sequences from comint.el - Handle OSC command to set window title - Provide an OSC escape sequences filter for compilation buffer --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-Extract-support-of-OSC-escape-sequences-from-comint.patch >From 792e592e423359f43e8420eb674ccfb328f74a2b Mon Sep 17 00:00:00 2001 From: Matthias Meulien Date: Sat, 17 Sep 2022 11:45:33 +0200 Subject: [PATCH 1/3] Extract support of OSC escape sequences from comint * lisp/comint.el (ansi-color): (comint-osc-handlers): (comint-osc--marker): (comint-osc-directory-tracker): (comint-osc-hyperlink-handler): (comint-osc-button-type): (comint-osc-hyperlink-map): (comint-osc-process-output): (url-host): (url-type): (url-filename): (comint-osc-hyperlink): (comint-osc-hyperlink--state): * lisp/osc.el (osc-handlers): (osc--marker): (osc-apply-region): (url-host): (url-type): (url-filename): (osc-directory-tracker): (osc-hyperlink-map): (osc-hyperlink): (osc-hyperlink--state): (osc-hyperlink-handler): (osc): --- lisp/comint.el | 91 ++++------------------------- lisp/osc.el | 127 +++++++++++++++++++++++++++++++++++++++++ test/lisp/osc-tests.el | 57 ++++++++++++++++++ 3 files changed, 194 insertions(+), 81 deletions(-) create mode 100644 lisp/osc.el create mode 100644 test/lisp/osc-tests.el diff --git a/lisp/comint.el b/lisp/comint.el index 696dac3d12..71ccbfc4e0 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -103,6 +103,7 @@ (require 'ring) (require 'ansi-color) +(require 'osc) (require 'regexp-opt) ;For regexp-opt-charset. (eval-when-compile (require 'subr-x)) @@ -3914,12 +3915,11 @@ comint-redirect-results-list-from-process ;; to `comint-osc-handlers' allows a customized treatment of further ;; sequences. -(defvar-local comint-osc-handlers '(("7" . comint-osc-directory-tracker) - ("8" . comint-osc-hyperlink-handler)) - "Alist of handlers for OSC escape sequences. -See `comint-osc-process-output' for details.") - -(defvar-local comint-osc--marker nil) +;; Aliases defined for reverse compatibility +(defalias 'comint-osc-directory-tracker 'osc-directory-tracker) +(defalias 'comint-osc-hyperlink-handler 'osc-hyperlink-handler) +(defalias 'comint-osc-button-type 'osc-button-type) +(defalias 'comint-osc-hyperlink-map 'osc-hyperlink-map) (defun comint-osc-process-output (_) "Interpret OSC escape sequences in comint output. @@ -3935,81 +3935,10 @@ comint-osc-process-output `comint-osc-handlers' alist, the corresponding value, which should be a function, is called with `command' and `text' as arguments, with point where the escape sequence was located." - (let ((bound (process-mark (get-buffer-process (current-buffer))))) - (save-excursion - ;; Start one char before last output to catch a possibly stray ESC - (goto-char (or comint-osc--marker (1- comint-last-output-start))) - (when (eq (char-before) ?\e) (backward-char)) - (while (re-search-forward "\e]" bound t) - (let ((pos0 (match-beginning 0)) - (code (and (re-search-forward "\\=\\([0-9A-Za-z]*\\);" bound t) - (match-string 1))) - (pos1 (point))) - (if (re-search-forward "\a\\|\e\\\\" bound t) - (let ((text (buffer-substring-no-properties - pos1 (match-beginning 0)))) - (setq comint-osc--marker nil) - (delete-region pos0 (point)) - (when-let ((fun (cdr (assoc-string code comint-osc-handlers)))) - (funcall fun code text))) - (put-text-property pos0 bound 'invisible t) - (setq comint-osc--marker (copy-marker pos0)))))))) - -;; Current directory tracking (OSC 7) - -(declare-function url-host "url/url-parse.el") -(declare-function url-type "url/url-parse.el") -(declare-function url-filename "url/url-parse.el") -(defun comint-osc-directory-tracker (_ text) - "Update `default-directory' from OSC 7 escape sequences. - -This function is intended to be included as an entry of -`comint-osc-handlers'. You should moreover arrange for your -shell to print the appropriate escape sequence at each prompt, -say with the following command: - - printf \"\\e]7;file://%s%s\\e\\\\\" \"$HOSTNAME\" \"$PWD\" - -This functionality serves as an alternative to `dirtrack-mode' -and `shell-dirtrack-mode'." - (let ((url (url-generic-parse-url text))) - (when (and (string= (url-type url) "file") - (or (null (url-host url)) - (string= (url-host url) (system-name)))) - (ignore-errors - (cd-absolute (url-unhex-string (url-filename url))))))) - -;; Hyperlink handling (OSC 8) - -(defvar comint-osc-hyperlink-map - (let ((map (make-sparse-keymap))) - (define-key map "\C-c\r" 'browse-url-button-open) - (define-key map [mouse-2] 'browse-url-button-open) - (define-key map [follow-link] 'mouse-face) - map) - "Keymap used by OSC 8 hyperlink buttons.") - -(define-button-type 'comint-osc-hyperlink - 'keymap comint-osc-hyperlink-map - 'help-echo (lambda (_ buffer pos) - (when-let ((url (get-text-property pos 'browse-url-data buffer))) - (format "mouse-2, C-c RET: Open %s" url)))) - -(defvar-local comint-osc-hyperlink--state nil) - -(defun comint-osc-hyperlink-handler (_ text) - "Create a hyperlink from an OSC 8 escape sequence. -This function is intended to be included as an entry of -`comint-osc-handlers'." - (when comint-osc-hyperlink--state - (let ((start (car comint-osc-hyperlink--state)) - (url (cdr comint-osc-hyperlink--state))) - (make-text-button start (point) - 'type 'comint-osc-hyperlink - 'browse-url-data url))) - (setq comint-osc-hyperlink--state - (and (string-match ";\\(.+\\)" text) - (cons (point-marker) (match-string-no-properties 1 text))))) + (let ((start (1- comint-last-output-start)) + ;; Start one char before last output to catch a possibly stray ESC + (bound (process-mark (get-buffer-process (current-buffer))))) + (osc-apply-on-region start bound))) ;;; Input fontification and indentation through an indirect buffer diff --git a/lisp/osc.el b/lisp/osc.el new file mode 100644 index 0000000000..224981a856 --- /dev/null +++ b/lisp/osc.el @@ -0,0 +1,127 @@ +;;; osc.el --- Support for OSC escape sequences -*- lexical-binding: t; -*- + +;; Copyright (C) 2022 Free Software Foundation, Inc. + +;; Author: Augusto Stoffel +;; Matthias Meulien +;; Maintainer: emacs-devel@gnu.org +;; Keywords: processes, terminals, services + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; Interpretation of OSC (Operating System Commands) escape +;; sequences. Handlers for OSC 7 and 8 (for current directory and +;; hyperlinks respectively) are provided. + +;;; Code: + +(defvar-local osc-handlers '(("7" . osc-directory-tracker) + ("8" . osc-hyperlink-handler)) + "Alist of handlers for OSC escape sequences. +See `osc-apply-on-region' for details.") + +(defvar-local osc--marker nil) +;; The function `osc-apply-on-region' can set `osc--marker' to the start +;; position of an escape sequence without termination. + +(defun osc-apply-on-region (begin end) + "Interpret OSC escape sequences in region. +This function search for escape sequences of the forms + + ESC ] command ; text BEL + ESC ] command ; text ESC \\ + +Every occurrence of such escape sequences is removed from the +buffer. Then, if `command' is a key of the local variable +`osc-handlers' alist, the corresponding value, which should be a +function, is called with `command' and `text' as arguments, with +point where the escape sequence was located." + (save-excursion + (goto-char (or osc--marker begin)) + (when (eq (char-before) ?\e) (backward-char)) + (while (re-search-forward "\e]" end t) + (let ((pos0 (match-beginning 0)) + (code (and (re-search-forward "\\=\\([0-9A-Za-z]*\\);" end t) + (match-string 1))) + (pos1 (point))) + (if (re-search-forward "\a\\|\e\\\\" end t) + (let ((text (buffer-substring-no-properties + pos1 (match-beginning 0)))) + (setq osc--marker nil) + (delete-region pos0 (point)) + (when-let ((fun (cdr (assoc-string code osc-handlers)))) + (funcall fun code text))) + (put-text-property pos0 end 'invisible t) + (setq osc--marker (copy-marker pos0))))))) + +;; Current directory tracking (OSC 7) + +(declare-function url-host "url/url-parse.el") +(declare-function url-type "url/url-parse.el") +(declare-function url-filename "url/url-parse.el") +(defun osc-directory-tracker (_ text) + "Update `default-directory' from OSC 7 escape sequences. + +This function is intended to be included as an entry of +`osc-handlers'. You should moreover arrange for your shell to +print the appropriate escape sequence at each prompt, say with +the following command: + + printf \"\\e]7;file://%s%s\\e\\\\\" \"$HOSTNAME\" \"$PWD\" + +This functionality serves as an alternative to `dirtrack-mode' +and `shell-dirtrack-mode'." + (let ((url (url-generic-parse-url text))) + (when (and (string= (url-type url) "file") + (or (null (url-host url)) + (string= (url-host url) (system-name)))) + (ignore-errors + (cd-absolute (url-unhex-string (url-filename url))))))) + +;; Hyperlink handling (OSC 8) + +(defvar osc-hyperlink-map + (let ((map (make-sparse-keymap))) + (define-key map "\C-c\r" 'browse-url-button-open) + (define-key map [mouse-2] 'browse-url-button-open) + (define-key map [follow-link] 'mouse-face) + map) + "Keymap used by OSC 8 hyperlink buttons.") + +(define-button-type 'osc-hyperlink + 'keymap osc-hyperlink-map + 'help-echo (lambda (_ buffer pos) + (when-let ((url (get-text-property pos 'browse-url-data buffer))) + (format "mouse-2, C-c RET: Open %s" url)))) + +(defvar-local osc-hyperlink--state nil) + +(defun osc-hyperlink-handler (_ text) + "Create a hyperlink from an OSC 8 escape sequence. +This function is intended to be included as an entry of +`osc-handlers'." + (when osc-hyperlink--state + (let ((start (car osc-hyperlink--state)) + (url (cdr osc-hyperlink--state))) + (make-text-button start (point) + 'type 'osc-hyperlink + 'browse-url-data url))) + (setq osc-hyperlink--state + (and (string-match ";\\(.+\\)" text) + (cons (point-marker) (match-string-no-properties 1 text))))) + +(provide 'osc) +;;; osc.el ends here diff --git a/test/lisp/osc-tests.el b/test/lisp/osc-tests.el new file mode 100644 index 0000000000..d53bab08d3 --- /dev/null +++ b/test/lisp/osc-tests.el @@ -0,0 +1,57 @@ +;;; osc-tests.el --- Tests for osc.el -*- lexical-binding: t; -*- + +;; Copyright (C) 2022 Free Software Foundation, Inc. + +;; Author: Matthias Meulien +;; Keywords: + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; + +;;; Code: + +(require 'osc) +(require 'ert) + +(defvar osc-tests--strings + `( + ("Hello World" "Hello World") + + ;; window title + ("Buffer \e]2;A window title\e\\content" "Buffer content") + + ;; window title + ("Unfinished \e]2;window title" "Unfinished \e]2;window title") + + ;; current directory + ("\e]7;file://127.0.0.1/tmp\e\\user@host$ " "user@host$ ") + + ;; hyperlink + ("\e]8;;http://example.com\e\\This is a link\e]8;;\e\\" "This is a link") + )) +;; Don't output those strings to stdout since they may have +;; side-effects on the environment + +(ert-deftest osc-tests-apply-region-no-handlers () + (let ((osc-handlers nil)) + (pcase-dolist (`(,input ,text) osc-tests--strings) + (with-temp-buffer + (insert input) + (osc-apply-on-region (point-min) (point-max)) + (should (equal (buffer-string) text)))))) -- 2.30.2 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0002-Handle-OSC-command-to-set-window-title.patch >From 524d7a10bf5b0db16410d00b11376bca73f69eba Mon Sep 17 00:00:00 2001 From: Matthias Meulien Date: Sat, 17 Sep 2022 17:54:24 +0200 Subject: [PATCH 2/3] Handle OSC command to set window title * lisp/osc.el (osc-handlers): (osc-window-title): (osc-window-title-handler): --- lisp/osc.el | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/lisp/osc.el b/lisp/osc.el index 224981a856..619972dab1 100644 --- a/lisp/osc.el +++ b/lisp/osc.el @@ -23,12 +23,13 @@ ;;; Commentary: ;; Interpretation of OSC (Operating System Commands) escape -;; sequences. Handlers for OSC 7 and 8 (for current directory and -;; hyperlinks respectively) are provided. +;; sequences. Handlers for OSC 2, 7 and 8 (for window title, current +;; directory and hyperlinks respectively) are provided. ;;; Code: -(defvar-local osc-handlers '(("7" . osc-directory-tracker) +(defvar-local osc-handlers '(("2" . osc-window-title-handler) + ("7" . osc-directory-tracker) ("8" . osc-hyperlink-handler)) "Alist of handlers for OSC escape sequences. See `osc-apply-on-region' for details.") @@ -67,6 +68,18 @@ osc-apply-on-region (put-text-property pos0 end 'invisible t) (setq osc--marker (copy-marker pos0))))))) +;; Window title handling (OSC 2) + +(defvar-local osc-window-title nil) +(defun osc-window-title-handler (_ text) + "Set value of `osc-window-title' from an OSC 2 escape sequence. +The variable `osc-window-title' can be referred to in +`frame-title-format' to dynamically set the frame title. + +This function is intended to be included as an entry of +`osc-handlers'." + (setq osc-window-title text)) + ;; Current directory tracking (OSC 7) (declare-function url-host "url/url-parse.el") -- 2.30.2 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0003-OSC-escape-sequences-filter-for-compilation-buffer.patch >From 1d179481023869b3216d7023713d547a3d45bcd8 Mon Sep 17 00:00:00 2001 From: Matthias Meulien Date: Sat, 17 Sep 2022 18:59:31 +0200 Subject: [PATCH 3/3] OSC escape sequences filter for compilation buffer * lisp/osc.el (osc-control-seq-regexp): (osc-filter-region): (osc-for-compilation-buffer): (osc-compilation-filter): --- lisp/osc.el | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/lisp/osc.el b/lisp/osc.el index 619972dab1..89467bc4cf 100644 --- a/lisp/osc.el +++ b/lisp/osc.el @@ -26,8 +26,26 @@ ;; sequences. Handlers for OSC 2, 7 and 8 (for window title, current ;; directory and hyperlinks respectively) are provided. +;; The function `osc-compilation-filter' can be added to +;; `compilation-filter-hook' to collect OSC sequences in compilation +;; buffers. The variable `osc-for-compilation-buffer' tells what to do +;; with collected sequences. + ;;; Code: +(defconst osc-control-seq-regexp + ;; See ECMA 48, section 8.3.89 "OSC - OPERATING SYSTEM COMMAND". + "\e\\][\x08-\x0D]*[\x20-\x7E]*\\(\a\\|\e\\\\\\)" + "Regexp matching an OSC control sequence.") + +(defun osc-filter-region (begin end) + "Filter out all OSC control sequences from region BEGIN to END." + (save-excursion + (goto-char begin) + ;; Delete escape sequences. + (while (re-search-forward osc-control-seq-regexp end t) + (delete-region (match-beginning 0) (match-end 0))))) + (defvar-local osc-handlers '(("2" . osc-window-title-handler) ("7" . osc-directory-tracker) ("8" . osc-hyperlink-handler)) @@ -136,5 +154,35 @@ osc-hyperlink-handler (and (string-match ";\\(.+\\)" text) (cons (point-marker) (match-string-no-properties 1 text))))) +(defcustom osc-for-compilation-buffer 'filter + "Determines what to do of OSC escape sequences in compilation output. +If nil, do nothing. + +If the symbol `filter', then filter out all OSC control sequences. + +If anything else (such as t), then collect OSC control sequences +and call appropriate handler as described in `osc-handlers'. + +In order for this to have any effect, `osc-compilation-filter' +must be in `compilation-filter-hook'." + :type '(choice (const :tag "Do nothing" nil) + (const :tag "Filter" filter) + (other :tag "Translate" t)) + :group 'osc + :version "29.0") + +;;;###autoload +(defun osc-compilation-filter () + "Maybe collect OSC control sequences. +This function depends on the `osc-for-compilation-buffer' +variable, and is meant to be used in `compilation-filter-hook'." + (let ((inhibit-read-only t)) + (pcase osc-for-compilation-buffer + ('nil nil) + ('filter + (osc-filter-region compilation-filter-start (point))) + (_ + (osc-apply-on-region compilation-filter-start (point)))))) + (provide 'osc) ;;; osc.el ends here -- 2.30.2 --=-=-= Content-Type: text/plain The second patch obsolete the one provided in bug#57866. Matthias --=-=-=--