* OSC control sequences in comint @ 2021-08-22 17:31 Augusto Stoffel 2021-08-22 22:38 ` Lars Ingebrigtsen 0 siblings, 1 reply; 9+ messages in thread From: Augusto Stoffel @ 2021-08-22 17:31 UTC (permalink / raw) To: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1412 bytes --] I would like to suggest adding some (optional) support for "Operating System Commands" [1] to comint. (This is unrelated to having Emacs talk OSC codes with the terminal inside of which its running.) This class of control sequences serves various random purposes, for instance adding clickable hyperlinks in terminal applications. As an example, compare `ls --hyperlink' in the Emacs shell versus some other "modern" terminal emulator. Now, I don't particularly care about those hyperlinks or any other established use of OSC sequences, and I guess a well-made program will avoid outputting them to Emacs, since it advertises itself as a dumb terminal. But OSCs seem to be good a way to create ad-hoc communication protocols between Emacs and other programs, say to display images in a REPL buffer (see [3] for a precedent). Thus, concretely, the suggestion is to add the `comint-osc-process-output' function attached below to comint.el or some other appropriate place. It would not be added to `comint-output-filter-functions' by default. The hyperlink handler is added as an example, it might be kept or removed. Anyway, as an illustration, after evaluating the attached file and calling (add-hook 'comint-output-filter-functions 'comint-osc-process-output nil t) in a shell buffer, `ls --hyperlink' should produce clickable hyperlinks, as it does in other capable terminals. What do you think? [-- Attachment #2: comint-osc.el --] [-- Type: text/plain, Size: 2322 bytes --] ;; -*- lexical-binding: t -*- (defvar-local comint-osc-handlers '(("8" . comint-osc-8-handler)) "Alist of handlers for OSC escape sequences. See `comint-osc-process-output' for details.") (defvar-local comint-osc--marker nil) (defun comint-osc-process-output (_) "Interpret OSC control sequences in comint output. This function is intended to be added to `comint-output-filter-functions' and interprets control sequences of the forms `\\e]<name>;<text>\\a' `\\e]<name>;<text>\\e\\' Specifically, every occurrence of such control sequences is removed from the buffer. Then, if the alist `comint-osc-handlers' contains an entry <name>, the corresponding value, which should be a function, is called with <name> and <text> as arguments, with point where the escape sequence was located." (let ((bound (process-mark (get-buffer-process (current-buffer))))) (save-excursion (goto-char (or comint-osc--marker (and (markerp comint-last-output-start) (eq (marker-buffer comint-last-output-start) (current-buffer)) comint-last-output-start) (point-min))) (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)))))))) ;;; Hyperlink handling (defvar-local comint-osc-8--state nil) (defun comint-osc-8-handler (_ text) (when comint-osc-8--state (let ((start (car comint-osc-8--state)) (uri (cdr comint-osc-8--state))) (require 'shr) (shr-urlify start uri))) (setq comint-osc-8--state (and (string-match ";\\(.+\\)" text) (cons (point-marker) (match-string-no-properties 1 text))))) [-- Attachment #3: Type: text/plain, Size: 213 bytes --] [1]: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands [2]: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda [3]: https://iterm2.com/documentation-images.html ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: OSC control sequences in comint 2021-08-22 17:31 OSC control sequences in comint Augusto Stoffel @ 2021-08-22 22:38 ` Lars Ingebrigtsen 2021-08-23 16:46 ` Augusto Stoffel 0 siblings, 1 reply; 9+ messages in thread From: Lars Ingebrigtsen @ 2021-08-22 22:38 UTC (permalink / raw) To: Augusto Stoffel; +Cc: emacs-devel Augusto Stoffel <arstoffel@gmail.com> writes: > Anyway, as an illustration, after evaluating the attached file and calling > > (add-hook 'comint-output-filter-functions 'comint-osc-process-output nil t) > > in a shell buffer, `ls --hyperlink' should produce clickable > hyperlinks, as it does in other capable terminals. > > What do you think? I think it sounds like a good idea. Could you format it up as a patch? -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: OSC control sequences in comint 2021-08-22 22:38 ` Lars Ingebrigtsen @ 2021-08-23 16:46 ` Augusto Stoffel 2021-08-25 10:32 ` Lars Ingebrigtsen 0 siblings, 1 reply; 9+ messages in thread From: Augusto Stoffel @ 2021-08-23 16:46 UTC (permalink / raw) To: Lars Ingebrigtsen; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1246 bytes --] On Mon, 23 Aug 2021 at 00:38, Lars Ingebrigtsen <larsi@gnus.org> wrote: > I think it sounds like a good idea. Could you format it up as a patch? All right, I have attached a patch. Since a comint buffer is editable, I chose an unobtrusive but less convenient keymap to the hyperlink buttons, based on bug-reference.el: 'C-c RET' opens the links. Note that there's a call to (autoload 'browse-url-button-open "browse-url.el") in the patch, which is probably not the best procedure. Should that function be autoloaded in browse-url.el? Finally, in case anyone wants to test or play around, a handler for the OSC 1337 escape (for inline images) could look like this: (defun comint-osc-1337-handler (_ text) (when (string-match ":" text) (insert-image (create-image (base64-decode-string (substring text (match-end 0))) nil t)))) Then one can say (add-hook 'comint-output-filter-functions 'comint-osc-process-output nil t) (push '("1337" . comint-osc-1337-handler) comint-osc-handlers) and use https://iterm2.com/utilities/imgcat to show (small...) images in the shell. However, I don't think it makes sense to provide this handler in Emacs itself, since it is rather nonstandard. Best, Augusto [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Add-support-for-OSC-escape-sequences-in-comint.patch --] [-- Type: text/x-patch, Size: 5466 bytes --] From 290107a10b638e41a73509d346336566791e6525 Mon Sep 17 00:00:00 2001 From: Augusto Stoffel <arstoffel@gmail.com> Date: Mon, 23 Aug 2021 18:03:39 +0200 Subject: [PATCH] Add support for OSC escape sequences in comint * lisp/comint.el (comint-osc-handlers, comint-osc--marker, comint-osc-process-output): New general infrastructure to handle OSC escape sequences. (comint-osc-hyperlink-map, comint-osc-hyperlink--state, comint-osc-hyperlink-handler): New functions and variables to handle OSC 8 (hyperlinks). --- etc/NEWS | 10 ++++++ lisp/comint.el | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/etc/NEWS b/etc/NEWS index b008c46291..ac8bec244d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -3019,6 +3019,16 @@ default are unaffected.) states to be maintained if 'so-long-mode' replaces the original major mode. By default, these new options support 'view-mode'. +** Comint + +*** Support for OSC escape sequences +Adding the new 'comint-osc-process-output' to +'comint-output-filter-functions' enables the interpretation of OSC +escape sequences in comint buffers. By default, only OSC 8, for +hyperlinks, is acted upon. Adding more entries to +`comint-osc-handlers' allows a customized treatment of further escape +sequences. + \f * New Modes and Packages in Emacs 28.1 diff --git a/lisp/comint.el b/lisp/comint.el index 7af8e8fd2a..b924029a3b 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -3887,6 +3887,93 @@ comint-redirect-results-list-from-process ;; don't advance, so ensure forward progress. (forward-line 1))) (nreverse results)))) + +\f +;;; OSC escape sequences (operating system commands) +;;============================================================================ +;; Adding `comint-osc-process-output' to `comint-output-filter-functions' +;; enables the interpretation of OSC escape sequences. By default, only +;; OSC 8, for hyperlinks, is acted upon. Adding more entries to +;; `comint-osc-handlers' allows a customized treatment of further sequences. + +(defvar-local comint-osc-handlers '(("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) + +(defun comint-osc-process-output (_) + "Interpret OSC escape sequences in comint output. + +This function is intended to be added to +`comint-output-filter-functions' in order to interpret escape +sequences of the forms + + ESC ] command ; text BEL + ESC ] command ; text ESC \\ + +Specifically, every occurrence of such escape sequences is +removed from the buffer. Then, if `command' is a key of the +`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 + (goto-char (or comint-osc--marker + (and (markerp comint-last-output-start) + (eq (marker-buffer comint-last-output-start) + (current-buffer)) + comint-last-output-start) + (point-min))) + (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)))))))) + +;; Hyperlink handling (OSC 8) + +(autoload 'browse-url-button-open "browse-url.el") + +(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))))) + \f ;;; Converting process modes to use comint mode ;;============================================================================ -- 2.31.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: OSC control sequences in comint 2021-08-23 16:46 ` Augusto Stoffel @ 2021-08-25 10:32 ` Lars Ingebrigtsen 2021-08-26 7:44 ` Augusto Stoffel 0 siblings, 1 reply; 9+ messages in thread From: Lars Ingebrigtsen @ 2021-08-25 10:32 UTC (permalink / raw) To: Augusto Stoffel; +Cc: emacs-devel Augusto Stoffel <arstoffel@gmail.com> writes: > All right, I have attached a patch. Since a comint buffer is editable, > I chose an unobtrusive but less convenient keymap to the hyperlink > buttons, based on bug-reference.el: 'C-c RET' opens the links. Thanks; applied to Emacs 28. Seems to work great with "ls --hyperlink". :-) (I added a short entry to the Emacs manual.) > Note that there's a call to > > (autoload 'browse-url-button-open "browse-url.el") > > in the patch, which is probably not the best procedure. Should that > function be autoloaded in browse-url.el? Yup; I've amended the patch to do that instead. > Finally, in case anyone wants to test or play around, a handler for the > OSC 1337 escape (for inline images) could look like this: > > (defun comint-osc-1337-handler (_ text) > (when (string-match ":" text) > (insert-image > (create-image (base64-decode-string (substring text (match-end 0))) nil t)))) > > Then one can say > > (add-hook 'comint-output-filter-functions 'comint-osc-process-output nil t) > (push '("1337" . comint-osc-1337-handler) comint-osc-handlers) > > and use https://iterm2.com/utilities/imgcat to show (small...) images in > the shell. > > However, I don't think it makes sense to provide this handler in Emacs > itself, since it is rather nonstandard. Hm... well, if it becomes popular (or more standard), then we should add it, because it sounds pretty cool. :-) -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: OSC control sequences in comint 2021-08-25 10:32 ` Lars Ingebrigtsen @ 2021-08-26 7:44 ` Augusto Stoffel 2021-08-26 14:06 ` Lars Ingebrigtsen 0 siblings, 1 reply; 9+ messages in thread From: Augusto Stoffel @ 2021-08-26 7:44 UTC (permalink / raw) To: Lars Ingebrigtsen; +Cc: emacs-devel On Wed, 25 Aug 2021 at 12:32, Lars Ingebrigtsen <larsi@gnus.org> wrote: > Thanks; applied to Emacs 28. Seems to work great with "ls --hyperlink". :-) > Great! Another useful addition might be OSC 7 to report the working directory. This would be much simpler and more reliable than 'shell-dirtrack-mode', but needs a small configuration in the shell as well (append some stuff to $PS1 or $PROMPT_COMMAND) >> However, I don't think it makes sense to provide this handler >> [i.e., graphics] in Emacs itself, since it is rather nonstandard. > > Hm... well, if it becomes popular (or more standard), then we should > add it, because it sounds pretty cool. :-) There are several long discussion about a image protocol for the terminal [1], but unfortunately nothing seems to be settled. I'll try adding graphical capabilities to the Python shell using a private protocol (since some hacking on the Python side is needed as well). If this woks well, it might be a good fit for an ELPA package. [1]: https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/26 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: OSC control sequences in comint 2021-08-26 7:44 ` Augusto Stoffel @ 2021-08-26 14:06 ` Lars Ingebrigtsen 2021-08-28 15:15 ` [PATCH] OSC 7 handler (alternative to shell-dirtrack-mode) Augusto Stoffel 0 siblings, 1 reply; 9+ messages in thread From: Lars Ingebrigtsen @ 2021-08-26 14:06 UTC (permalink / raw) To: Augusto Stoffel; +Cc: emacs-devel Augusto Stoffel <arstoffel@gmail.com> writes: > Great! Another useful addition might be OSC 7 to report the working > directory. This would be much simpler and more reliable than > 'shell-dirtrack-mode', but needs a small configuration in the shell as > well (append some stuff to $PS1 or $PROMPT_COMMAND) Yes, that sounds quite useful. > I'll try adding graphical capabilities to the Python shell using a > private protocol (since some hacking on the Python side is needed as > well). If this woks well, it might be a good fit for an ELPA package. Yup. -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] OSC 7 handler (alternative to shell-dirtrack-mode) 2021-08-26 14:06 ` Lars Ingebrigtsen @ 2021-08-28 15:15 ` Augusto Stoffel 2021-08-29 8:06 ` Michael Albinus 2021-08-29 18:56 ` Lars Ingebrigtsen 0 siblings, 2 replies; 9+ messages in thread From: Augusto Stoffel @ 2021-08-28 15:15 UTC (permalink / raw) To: Lars Ingebrigtsen; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1309 bytes --] On Thu, 26 Aug 2021 at 16:06, Lars Ingebrigtsen <larsi@gnus.org> wrote: > Augusto Stoffel <arstoffel@gmail.com> writes: > >> Great! Another useful addition might be OSC 7 to report the working >> directory. This would be much simpler and more reliable than >> 'shell-dirtrack-mode', but needs a small configuration in the shell as >> well (append some stuff to $PS1 or $PROMPT_COMMAND) > > Yes, that sounds quite useful. > I've attached a patch to handle OSC 7, which is a protocol for the inferior process to tell the terminal about directory changes. This replaces the functionality of shell-dirtrack-mode and dirtrack-mode, perhaps in a less hacky way. Unfortunately, it needs a bit of configuration on the shell side too (no system will be preconfigured to emit OSCs to a dumb terminal). A slightly naive approach is run PROMPT_COMMAND='printf "\e]7;file://%s%s\e\\" "$HOSTNAME" "$PWD"' or add this to the bashrc file. On my system bash comes with a `__vte_osc7' function which is similar but slightly more robust (it urlencodes the PWD). (I've also removed some borderline paranoid checks on the variable `comint-last-output-start' which I had copied from ansi-color. On closer inspection, those checks are working around a bug in gdb-mi. Good opportunity to check if that bug was fixed.) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Add-support-for-OSC-7-in-comint-current-directory-tr.patch --] [-- Type: text/x-patch, Size: 3007 bytes --] From 2e6127373f9fbd4126beeb136e86f2f8e7d1e3d6 Mon Sep 17 00:00:00 2001 From: Augusto Stoffel <arstoffel@gmail.com> Date: Sat, 28 Aug 2021 15:47:49 +0200 Subject: [PATCH] Add support for OSC 7 in comint (current directory tracking) * lisp/comint.el (comint-osc-directory-tracker, comint-osc-handlers): Define and register a handler for OSC 7. (comint-osc-process-output): Do fewer checks on 'comint-last-output-start'. --- lisp/comint.el | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/lisp/comint.el b/lisp/comint.el index b924029a3b..be1c0fbf24 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -3896,7 +3896,8 @@ comint-redirect-results-list-from-process ;; OSC 8, for hyperlinks, is acted upon. Adding more entries to ;; `comint-osc-handlers' allows a customized treatment of further sequences. -(defvar-local comint-osc-handlers '(("8" . comint-osc-hyperlink-handler)) +(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.") @@ -3919,12 +3920,8 @@ comint-osc-process-output arguments, with point where the escape sequence was located." (let ((bound (process-mark (get-buffer-process (current-buffer))))) (save-excursion - (goto-char (or comint-osc--marker - (and (markerp comint-last-output-start) - (eq (marker-buffer comint-last-output-start) - (current-buffer)) - comint-last-output-start) - (point-min))) + ;; 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)) @@ -3940,6 +3937,27 @@ comint-osc-process-output (put-text-property pos0 bound 'invisible t) (setq comint-osc--marker (copy-marker pos0)))))))) +;; Current directory tracking (OSC 7) + +(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) (autoload 'browse-url-button-open "browse-url.el") -- 2.31.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] OSC 7 handler (alternative to shell-dirtrack-mode) 2021-08-28 15:15 ` [PATCH] OSC 7 handler (alternative to shell-dirtrack-mode) Augusto Stoffel @ 2021-08-29 8:06 ` Michael Albinus 2021-08-29 18:56 ` Lars Ingebrigtsen 1 sibling, 0 replies; 9+ messages in thread From: Michael Albinus @ 2021-08-29 8:06 UTC (permalink / raw) To: Augusto Stoffel; +Cc: Lars Ingebrigtsen, emacs-devel Augusto Stoffel <arstoffel@gmail.com> writes: Hi Augusto, > Unfortunately, it needs a bit of configuration on the shell side too (no > system will be preconfigured to emit OSCs to a dumb terminal). A > slightly naive approach is run > > PROMPT_COMMAND='printf "\e]7;file://%s%s\e\\" "$HOSTNAME" "$PWD"' > > or add this to the bashrc file. I don't want to stop your effort (I like the idea), but we shall have in mind that such shell prompts might ruin Tramp. Best regards, Michael. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] OSC 7 handler (alternative to shell-dirtrack-mode) 2021-08-28 15:15 ` [PATCH] OSC 7 handler (alternative to shell-dirtrack-mode) Augusto Stoffel 2021-08-29 8:06 ` Michael Albinus @ 2021-08-29 18:56 ` Lars Ingebrigtsen 1 sibling, 0 replies; 9+ messages in thread From: Lars Ingebrigtsen @ 2021-08-29 18:56 UTC (permalink / raw) To: Augusto Stoffel; +Cc: emacs-devel Augusto Stoffel <arstoffel@gmail.com> writes: > I've attached a patch to handle OSC 7, which is a protocol for the > inferior process to tell the terminal about directory changes. This > replaces the functionality of shell-dirtrack-mode and dirtrack-mode, > perhaps in a less hacky way. Thanks; applied to Emacs 28. -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2021-08-29 18:56 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2021-08-22 17:31 OSC control sequences in comint Augusto Stoffel 2021-08-22 22:38 ` Lars Ingebrigtsen 2021-08-23 16:46 ` Augusto Stoffel 2021-08-25 10:32 ` Lars Ingebrigtsen 2021-08-26 7:44 ` Augusto Stoffel 2021-08-26 14:06 ` Lars Ingebrigtsen 2021-08-28 15:15 ` [PATCH] OSC 7 handler (alternative to shell-dirtrack-mode) Augusto Stoffel 2021-08-29 8:06 ` Michael Albinus 2021-08-29 18:56 ` Lars Ingebrigtsen
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.