>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