From: martin rudalics <rudalics@gmx.at>
To: Pranshu Sharma <pranshusharma366@gmail.com>
Cc: Juri Linkov <juri@linkov.net>, Eli Zaretskii <eliz@gnu.org>,
emacs-devel@gnu.org
Subject: Re: Add function to rotate/transpose all windows
Date: Sun, 27 Oct 2024 09:23:27 +0100 [thread overview]
Message-ID: <0a2f09a0-4115-4421-a391-30d27e7d0821@gmx.at> (raw)
In-Reply-To: <875xpfns32.fsf@gmail.com>
> Look in window--transpose
I see it now. You should not bind 'window-combination-limit' there.
Always bind it around a single 'split-window' call only. If you bind it
for all 'split-window' operations run by transposing, you get a binary
window tree which is certainly not what a user wants.
When with emacs -Q I set 'debug-on-error' t, do C-x 2 C-x 2 and then
call 'rotate-windows-clockwise' twice I get
Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p nil)
-(916.0 nil)
(if (eq o-split split-type) (- fflen o-size) fflen)
(let* ((split-type (funcall (if (car subtree) 'car 'cdr) conf)) (flen (if (eq o-split split-type) (- fflen o-size) fflen)) (deepest-window (seq-reduce #'(lambda (parent-win arg0) (progn (ignore ...) (let* ... ...))) (let ((ls (mapcar ... ...))) (seq-mapn 'cons (mapcar 'car ls) (cons nil (mapcar ... ls)))) cwin))) (progn (let ((upper-bound (- (length subtree) 3)) (counter 0)) (while (< counter upper-bound) (let ((_ counter)) (setq deepest-window (window-parent deepest-window))) (setq counter (1+ counter)))) deepest-window))
(let ((ilen x0) (fflen x1)) (let* ((split-type (funcall (if (car subtree) 'car 'cdr) conf)) (flen (if (eq o-split split-type) (- fflen o-size) fflen)) (deepest-window (seq-reduce #'(lambda (parent-win arg0) (progn ... ...)) (let ((ls ...)) (seq-mapn 'cons (mapcar ... ls) (cons nil ...))) cwin))) (progn (let ((upper-bound (- (length subtree) 3)) (counter 0)) (while (< counter upper-bound) (let ((_ counter)) (setq deepest-window (window-parent deepest-window))) (setq counter (1+ counter)))) deepest-window)))
(let* ((x0 (car-safe val)) (x1 (cdr-safe val))) (let ((ilen x0) (fflen x1)) (let* ((split-type (funcall (if (car subtree) 'car 'cdr) conf)) (flen (if (eq o-split split-type) (- fflen o-size) fflen)) (deepest-window (seq-reduce #'(lambda ... ...) (let (...) (seq-mapn ... ... ...)) cwin))) (progn (let ((upper-bound (- ... 3)) (counter 0)) (while (< counter upper-bound) (let (...) (setq deepest-window ...)) (setq counter (1+ counter)))) deepest-window))))
(progn (ignore (consp val)) (let* ((x0 (car-safe val)) (x1 (cdr-safe val))) (let ((ilen x0) (fflen x1)) (let* ((split-type (funcall (if ... ... ...) conf)) (flen (if (eq o-split split-type) (- fflen o-size) fflen)) (deepest-window (seq-reduce #'... (let ... ...) cwin))) (progn (let ((upper-bound ...) (counter 0)) (while (< counter upper-bound) (let ... ...) (setq counter ...))) deepest-window)))))
(let* ((val (if (car subtree) (cons (float (car (car ...))) (float (window-pixel-width cwin))) (cons (float (cdr (car ...))) (float (window-pixel-height cwin)))))) (progn (ignore (consp val)) (let* ((x0 (car-safe val)) (x1 (cdr-safe val))) (let ((ilen x0) (fflen x1)) (let* ((split-type (funcall ... conf)) (flen (if ... ... fflen)) (deepest-window (seq-reduce ... ... cwin))) (progn (let (... ...) (while ... ... ...)) deepest-window))))))
window--transpose-1((nil (916 . 1248) (#<window 7 on *scratch*> (916 . 843)) (#<window 8> (916 . 405))) #<window 7 on *scratch*> (left . below) nil #<window 7 on *scratch*> nil below)
(if (and (not size) o-size) (window--transpose-1 win parent-win conf do-not-convert-size fwin o-size o-split) (window--transpose-1 win parent-win conf do-not-convert-size fwin split-size split-type))
(if (listp win) (if (and (not size) o-size) (window--transpose-1 win parent-win conf do-not-convert-size fwin o-size o-split) (window--transpose-1 win parent-win conf do-not-convert-size fwin split-size split-type)) (if (and (not size) o-size) (split-window parent-win o-size o-split t win) (split-window parent-win split-size split-type t win)))
(let ((split-size (and size (if do-not-convert-size size (round (* flen (/ size ilen))))))) (if (listp win) (if (and (not size) o-size) (window--transpose-1 win parent-win conf do-not-convert-size fwin o-size o-split) (window--transpose-1 win parent-win conf do-not-convert-size fwin split-size split-type)) (if (and (not size) o-size) (split-window parent-win o-size o-split t win) (split-window parent-win split-size split-type t win))))
(if (eq fwin win) parent-win (let ((split-size (and size (if do-not-convert-size size (round (* flen ...)))))) (if (listp win) (if (and (not size) o-size) (window--transpose-1 win parent-win conf do-not-convert-size fwin o-size o-split) (window--transpose-1 win parent-win conf do-not-convert-size fwin split-size split-type)) (if (and (not size) o-size) (split-window parent-win o-size o-split t win) (split-window parent-win split-size split-type t win)))))
(let ((win x2) (size x3)) (if (eq fwin win) parent-win (let ((split-size (and size (if do-not-convert-size size (round ...))))) (if (listp win) (if (and (not size) o-size) (window--transpose-1 win parent-win conf do-not-convert-size fwin o-size o-split) (window--transpose-1 win parent-win conf do-not-convert-size fwin split-size split-type)) (if (and (not size) o-size) (split-window parent-win o-size o-split t win) (split-window parent-win split-size split-type t win))))))
(let* ((x2 (car-safe arg0)) (x3 (cdr-safe arg0))) (let ((win x2) (size x3)) (if (eq fwin win) parent-win (let ((split-size (and size (if do-not-convert-size size ...)))) (if (listp win) (if (and (not size) o-size) (window--transpose-1 win parent-win conf do-not-convert-size fwin o-size o-split) (window--transpose-1 win parent-win conf do-not-convert-size fwin split-size split-type)) (if (and (not size) o-size) (split-window parent-win o-size o-split t win) (split-window parent-win split-size split-type t win)))))))
(progn (ignore (consp arg0)) (let* ((x2 (car-safe arg0)) (x3 (cdr-safe arg0))) (let ((win x2) (size x3)) (if (eq fwin win) parent-win (let ((split-size (and size ...))) (if (listp win) (if (and ... o-size) (window--transpose-1 win parent-win conf do-not-convert-size fwin o-size o-split) (window--transpose-1 win parent-win conf do-not-convert-size fwin split-size split-type)) (if (and ... o-size) (split-window parent-win o-size o-split t win) (split-window parent-win split-size split-type t win))))))))
#f(lambda (parent-win arg0) [(flen 916.0) (split-type below) (ilen 1680.0) (o-split nil) (o-size nil) (fwin #<window 7 on *scratch*>) (do-not-convert-size nil) (conf (left . below))] (progn (ignore (consp arg0)) (let* ((x2 (car-safe arg0)) (x3 (cdr-safe arg0))) (let ((win x2) (size x3)) (if (eq fwin win) parent-win (let ((split-size (and size (if do-not-convert-size size (round (* flen (/ size ilen))))))) (if (listp win) (if (and (not size) o-size) (window--transpose-1 win parent-win conf do-not-convert-size fwin o-size o-split) (window--transpose-1 win parent-win conf do-not-convert-size fwin split-size split-type)) (if (and (not size) o-size) (split-window parent-win o-size o-split t win) (split-window parent-win split-size split-type t win)))))))))(#<window 7 on *scratch*> ((nil (916 . 1248) (#<window 7 on *scratch*> (916 . 843)) (#<window 8> (916 . 405)))))
#f(compiled-function (elt) #<bytecode 0x1f3b072de5930c3f>)(((nil (916 . 1248) (#<window 7 on *scratch*> (916 . 843)) (#<window 8> (916 . 405)))))
mapc(#f(compiled-function (elt) #<bytecode 0x1f3b072de5930c3f>) (((nil (916 . 1248) (#<window 7 on *scratch*> (916 . 843)) (#<window 8> (916 . 405)))) (#<window 3> . 1248)))
seq-do(#f(compiled-function (elt) #<bytecode 0x1f3b072de5930c3f>) (((nil (916 . 1248) (#<window 7 on *scratch*> (916 . 843)) (#<window 8> (916 . 405)))) (#<window 3> . 1248)))
seq-reduce(#f(lambda (parent-win arg0) [(flen 916.0) (split-type below) (ilen 1680.0) (o-split nil) (o-size nil) (fwin #<window 7 on *scratch*>) (do-not-convert-size nil) (conf (left . below))] (progn (ignore (consp arg0)) (let* ((x2 (car-safe arg0)) (x3 (cdr-safe arg0))) (let ((win x2) (size x3)) (if (eq fwin win) parent-win (let (...) (if ... ... ...))))))) (((nil (916 . 1248) (#<window 7 on *scratch*> (916 . 843)) (#<window 8> (916 . 405)))) (#<window 3> . 1248)) #<window 7 on *scratch*>)
(let* ((split-type (funcall (if (car subtree) 'car 'cdr) conf)) (flen (if (eq o-split split-type) (- fflen o-size) fflen)) (deepest-window (seq-reduce #'(lambda (parent-win arg0) (progn (ignore ...) (let* ... ...))) (let ((ls (mapcar ... ...))) (seq-mapn 'cons (mapcar 'car ls) (cons nil (mapcar ... ls)))) cwin))) (progn (let ((upper-bound (- (length subtree) 3)) (counter 0)) (while (< counter upper-bound) (let ((_ counter)) (setq deepest-window (window-parent deepest-window))) (setq counter (1+ counter)))) deepest-window))
(let ((ilen x0) (fflen x1)) (let* ((split-type (funcall (if (car subtree) 'car 'cdr) conf)) (flen (if (eq o-split split-type) (- fflen o-size) fflen)) (deepest-window (seq-reduce #'(lambda (parent-win arg0) (progn ... ...)) (let ((ls ...)) (seq-mapn 'cons (mapcar ... ls) (cons nil ...))) cwin))) (progn (let ((upper-bound (- (length subtree) 3)) (counter 0)) (while (< counter upper-bound) (let ((_ counter)) (setq deepest-window (window-parent deepest-window))) (setq counter (1+ counter)))) deepest-window)))
(let* ((x0 (car-safe val)) (x1 (cdr-safe val))) (let ((ilen x0) (fflen x1)) (let* ((split-type (funcall (if (car subtree) 'car 'cdr) conf)) (flen (if (eq o-split split-type) (- fflen o-size) fflen)) (deepest-window (seq-reduce #'(lambda ... ...) (let (...) (seq-mapn ... ... ...)) cwin))) (progn (let ((upper-bound (- ... 3)) (counter 0)) (while (< counter upper-bound) (let (...) (setq deepest-window ...)) (setq counter (1+ counter)))) deepest-window))))
(progn (ignore (consp val)) (let* ((x0 (car-safe val)) (x1 (cdr-safe val))) (let ((ilen x0) (fflen x1)) (let* ((split-type (funcall (if ... ... ...) conf)) (flen (if (eq o-split split-type) (- fflen o-size) fflen)) (deepest-window (seq-reduce #'... (let ... ...) cwin))) (progn (let ((upper-bound ...) (counter 0)) (while (< counter upper-bound) (let ... ...) (setq counter ...))) deepest-window)))))
(let* ((val (if (car subtree) (cons (float (car (car ...))) (float (window-pixel-width cwin))) (cons (float (cdr (car ...))) (float (window-pixel-height cwin)))))) (progn (ignore (consp val)) (let* ((x0 (car-safe val)) (x1 (cdr-safe val))) (let ((ilen x0) (fflen x1)) (let* ((split-type (funcall ... conf)) (flen (if ... ... fflen)) (deepest-window (seq-reduce ... ... cwin))) (progn (let (... ...) (while ... ... ...)) deepest-window))))))
window--transpose-1((nil (916 . 1680) (nil (916 . 1248) (#<window 7 on *scratch*> (916 . 843)) (#<window 8> (916 . 405))) (#<window 3> (916 . 432))) #<window 7 on *scratch*> (left . below) nil #<window 7 on *scratch*> nil)
(let* ((frame (window-frame window)) (fwin window) (selwin (frame-selected-window window)) (window-combination-limit t) (win-tree (car (window-tree-pixel-sizes window)))) (while (not (window-live-p fwin)) (setq fwin (window-child fwin))) (delete-other-windows-internal fwin) (window--transpose-1 win-tree fwin conf do-not-convert-size fwin nil) (set-frame-selected-window frame selwin))
(if (or (not window) (window-live-p window)) (message "No windows to transpose") (let* ((frame (window-frame window)) (fwin window) (selwin (frame-selected-window window)) (window-combination-limit t) (win-tree (car (window-tree-pixel-sizes window)))) (while (not (window-live-p fwin)) (setq fwin (window-child fwin))) (delete-other-windows-internal fwin) (window--transpose-1 win-tree fwin conf do-not-convert-size fwin nil) (set-frame-selected-window frame selwin)))
window--transpose(#<window 6> (left . below) nil)
(let ((window (cond (subtree (window-parent)) ((windowp frame-or-window) frame-or-window) (t (window-main-window frame-or-window))))) (old-window-alist) (window--transpose window '(left . below) nil) (new-window-alist) (save-current-buffer (set-buffer (get-buffer-create "*foo*")) (pp old-window-alist (current-buffer)) (insert "\n") (pp new-window-alist (current-buffer))))
rotate-windows-clockwise(nil)
funcall-interactively(rotate-windows-clockwise nil)
call-interactively(rotate-windows-clockwise nil nil)
command-execute(rotate-windows-clockwise)
I have no idea whether it's related. For me that backtrace is
impossible to trace. Please have a look. Once it works, I'll try to
come up with an example why what you do is wrong.
Note the following paragraph in the Elisp manual on
'window-combination-limit'.
If, as a consequence of this variable’s setting, ‘split-window’
makes a new parent window, it also calls
‘set-window-combination-limit’ (see below) on the newly-created
internal window. This affects how the window tree is rearranged
when the child windows are deleted (see below).
So when you bind 'window-combination-limit' globally, deleting windows
after transposing may behave differently from before transposing them.
The correct approach is to save the value of 'window-combination-limit'
for a parent window before splitting, split the window, and then restore
the previous value of the parent.
The problem, however, is also with finding the right parent window and
I'm afraid your algorithm doesn't get that right yet. IIUC when finding
a next sibling as the new window in a split and that sibling is an
internal window, you take that window's first live descendant - let's
call it FIRST - and pass it to 'split-window' as REFER argument. Right?
But 'split-window' has no idea of FIRST's former parent and, when it now
needs a parent because of 'window-combination-limit' being non-nil, it
will not reuse the previous parent of FIRST (some internal window down
the old window tree) but simply make a new one.
Note that if you had not set 'window-combination-limit', 'split-window'
would have set the parent to the parent of the window to split, which is
equally wrong as you probably noticed earlier. So what you have to do
here is to pass a cons as REFER to 'split-window' with the car set to
FIRST and the cdr set to the parent of FIRST it had in the window tree
_before_ you deleted the other windows. This will instruct
'split-window' to reinstall that old parent in the window tree and
things should work out as intended.
Note in this context that preserving the identities of live windows
across transpositions via the REFER argument is important to keep all
those things like window positions, margins, scroll bars, fringes,
overlays with a window property, dedicated status and parameters like
'no-other-window' or 'quit-restore' in place. Without the REFER
argument, you would have to painstakingly restore all these things
manually for each new live window from the old one it substitutes.
Preserving the identity of internal windows on the other hand is
important to keep their combination limits and any parameters stored
for them. Even here, it's much easier to reuse the old parent windows
instead of saving all these properties before deleting windows and
trying to find the identity of the parent windows that substituted the
old ones and store the appropriate properties in the new windows.
martin
next prev parent reply other threads:[~2024-10-27 8:23 UTC|newest]
Thread overview: 144+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-24 13:45 Add function to rotate/transpose all windows pranshu sharma
2024-09-24 13:53 ` Eli Zaretskii
2024-09-25 8:05 ` martin rudalics
2024-09-25 8:34 ` pranshu sharma
2024-09-25 9:31 ` martin rudalics
2024-09-25 10:50 ` pranshu sharma
2024-09-25 13:53 ` martin rudalics
2024-09-25 15:31 ` pranshu sharma
2024-09-26 14:10 ` martin rudalics
2024-09-26 14:22 ` Eli Zaretskii
2024-09-27 17:29 ` martin rudalics
2024-09-28 7:52 ` pranshu sharma
2024-09-28 9:26 ` martin rudalics
2024-09-28 10:53 ` pranshu sharma
2024-09-28 14:48 ` martin rudalics
2024-09-29 7:36 ` pranshu sharma
2024-09-29 8:40 ` martin rudalics
2024-09-29 9:23 ` pranshu sharma
2024-09-29 14:48 ` martin rudalics
2024-09-30 6:29 ` pranshu sharma
2024-09-30 8:57 ` martin rudalics
2024-10-01 9:17 ` pranshu sharma
2024-10-02 9:04 ` martin rudalics
2024-10-03 7:06 ` pranshu sharma
2024-10-03 8:17 ` martin rudalics
2024-10-03 10:09 ` pranshu sharma
2024-10-03 14:18 ` martin rudalics
2024-10-04 5:50 ` pranshu sharma
2024-10-04 8:08 ` martin rudalics
2024-10-04 15:10 ` pranshu sharma
2024-10-05 14:43 ` martin rudalics
2024-10-06 2:54 ` pranshu sharma
2024-10-06 15:02 ` martin rudalics
2024-10-06 15:52 ` pranshu sharma
2024-10-07 8:33 ` martin rudalics
2024-10-07 9:42 ` pranshu sharma
2024-10-03 15:12 ` Eli Zaretskii
2024-10-08 18:35 ` Juri Linkov
2024-10-09 6:59 ` pranshu sharma
2024-10-09 16:21 ` Juri Linkov
2024-10-10 11:49 ` pranshu sharma
2024-10-10 16:57 ` Juri Linkov
2024-10-13 5:43 ` pranshu sharma
2024-10-13 8:17 ` martin rudalics
2024-10-14 17:36 ` Juri Linkov
2024-10-15 8:34 ` pranshu sharma
2024-10-15 16:16 ` Juri Linkov
2024-10-18 14:52 ` pranshu sharma
2024-10-18 17:48 ` martin rudalics
2024-10-18 18:37 ` Eli Zaretskii
2024-10-19 1:45 ` pranshu sharma
2024-10-19 6:45 ` Eli Zaretskii
2024-10-19 18:19 ` Juri Linkov
2024-10-19 8:33 ` martin rudalics
2024-10-20 8:19 ` martin rudalics
2024-10-20 14:11 ` Pranshu Sharma
2024-10-20 17:37 ` martin rudalics
2024-10-21 5:54 ` Pranshu Sharma
2024-10-21 8:14 ` martin rudalics
2024-10-21 9:23 ` martin rudalics
2024-10-21 13:37 ` Pranshu Sharma
2024-10-22 18:12 ` martin rudalics
2024-10-24 14:38 ` Pranshu Sharma
2024-10-24 18:39 ` martin rudalics
2024-10-25 14:24 ` Pranshu Sharma
2024-10-25 17:09 ` martin rudalics
2024-10-26 9:14 ` Pranshu Sharma
2024-10-27 8:23 ` martin rudalics [this message]
2024-11-02 14:06 ` Pranshu Sharma
2024-11-05 18:01 ` martin rudalics
2024-11-08 9:23 ` Pranshu Sharma
2024-11-08 10:06 ` Pranshu Sharma
2024-11-08 15:52 ` martin rudalics
2024-11-09 2:14 ` Pranshu Sharma
2024-11-09 8:48 ` martin rudalics
2024-11-08 15:52 ` martin rudalics
2024-11-09 2:09 ` Pranshu Sharma
2024-11-09 8:48 ` martin rudalics
2024-11-09 10:55 ` Pranshu Sharma
2024-11-09 18:06 ` martin rudalics
2024-11-10 10:09 ` Pranshu Sharma
2024-11-10 16:36 ` martin rudalics
2024-11-11 14:47 ` Pranshu Sharma
2024-11-11 16:55 ` martin rudalics
2024-11-12 13:50 ` Pranshu Sharma
2024-11-12 17:46 ` martin rudalics
2024-11-16 13:36 ` Pranshu Sharma
2024-11-16 16:54 ` martin rudalics
2024-11-17 2:45 ` Pranshu Sharma
2024-11-17 10:22 ` martin rudalics
2024-11-17 15:03 ` Pranshu Sharma
2024-11-17 16:38 ` martin rudalics
2024-11-18 0:37 ` Pranshu Sharma
2024-11-18 8:55 ` martin rudalics
2024-11-19 9:34 ` Pranshu Sharma
2024-11-19 17:48 ` martin rudalics
2024-11-21 14:04 ` Pranshu Sharma
2024-11-21 17:54 ` martin rudalics
2024-11-24 13:53 ` Pranshu Sharma
2024-11-26 9:49 ` martin rudalics
2024-11-26 14:14 ` Pranshu Sharma
2024-11-27 8:29 ` Pranshu Sharma
2024-11-27 9:18 ` martin rudalics
2024-11-27 14:37 ` Pranshu Sharma
2024-11-27 17:42 ` martin rudalics
2024-11-28 2:43 ` Pranshu Sharma
2024-11-28 9:28 ` martin rudalics
2024-11-28 15:18 ` Pranshu Sharma
2024-11-30 10:07 ` martin rudalics
2024-11-30 17:41 ` Juri Linkov
2024-11-30 19:01 ` martin rudalics
2024-12-01 4:13 ` Pranshu Sharma
2024-12-03 7:30 ` Juri Linkov
2024-12-03 8:25 ` martin rudalics
2024-12-01 6:41 ` Pranshu Sharma
2024-12-01 17:20 ` martin rudalics
2024-12-02 8:06 ` Pranshu Sharma
2024-12-03 8:23 ` martin rudalics
2024-12-04 15:20 ` Pranshu Sharma
2024-12-04 17:56 ` martin rudalics
2024-12-04 19:12 ` Juri Linkov
2024-12-05 14:16 ` Pranshu Sharma
2024-12-05 17:48 ` Juri Linkov
2024-12-06 4:51 ` Pranshu Sharma
2024-12-06 7:29 ` Juri Linkov
2024-12-05 14:23 ` Pranshu Sharma
2024-12-05 15:17 ` Pranshu Sharma
2024-10-14 17:32 ` Juri Linkov
2024-09-28 7:58 ` pranshu sharma
2024-09-28 8:18 ` Eli Zaretskii
2024-09-28 9:40 ` martin rudalics
2024-09-28 11:35 ` Eli Zaretskii
2024-09-28 14:58 ` martin rudalics
2024-09-28 15:28 ` Eli Zaretskii
2024-10-07 8:33 ` martin rudalics
2024-09-28 13:22 ` pranshu sharma
2024-09-28 14:21 ` Eli Zaretskii
2024-09-28 14:49 ` martin rudalics
2024-09-27 10:06 ` pranshu sharma
2024-09-27 17:29 ` martin rudalics
2024-09-24 17:40 ` Petteri Hintsanen
2024-09-24 19:34 ` Charles Choi
2024-09-25 2:00 ` Emanuel Berg
2024-09-25 7:00 ` pranshu sharma
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=0a2f09a0-4115-4421-a391-30d27e7d0821@gmx.at \
--to=rudalics@gmx.at \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
--cc=juri@linkov.net \
--cc=pranshusharma366@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).