* vc.el: asynchronous annotations
@ 2007-07-15 23:20 David Kastrup
2007-07-16 15:42 ` Stefan Monnier
0 siblings, 1 reply; 6+ messages in thread
From: David Kastrup @ 2007-07-15 23:20 UTC (permalink / raw)
To: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 905 bytes --]
Hi,
I've tried getting asynchronous annotations to work, and basically it
is a whole bunch of ...
I have gone through with an example backend of my own as well as with
vc-cvs (which inexplicably still works synchronously here), so both
the asynchronous as well as the synchronous operation should be
covered by now.
I am not sure I like the behavior when doing P or N or similar in the
annotation buffer: since the buffer is reused, it is cleared and
filled with new material while being displayed on the screen.
There are two ways around that, I guess. One way would be to switch
back to the source buffer while the operation progresses. Another way
would be to _not_ reuse the buffer but instead delete the old buffer
once the new one is complete.
Anyway, here is a patch regarding the current working state at my end.
Stefan, what do you say?
--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 5416 bytes --]
*** vc.el 09 Jul 2007 23:10:04 +0200 1.432
--- vc.el 16 Jul 2007 01:09:39 +0200
***************
*** 3123,3129 ****
use; you may override this using the second optional arg MODE."
(interactive)
(if mode (setq vc-annotate-display-mode mode))
! (pop-to-buffer (or buffer (current-buffer)))
(cond ((null vc-annotate-display-mode)
;; The ratio is global, thus relative to the global color-map.
(kill-local-variable 'vc-annotate-color-map)
--- 3123,3129 ----
use; you may override this using the second optional arg MODE."
(interactive)
(if mode (setq vc-annotate-display-mode mode))
! (if buffer (set-buffer buffer))
(cond ((null vc-annotate-display-mode)
;; The ratio is global, thus relative to the global color-map.
(kill-local-variable 'vc-annotate-color-map)
***************
*** 3183,3193 ****
(vc-ensure-vc-buffer)
(setq vc-annotate-display-mode display-mode) ;Not sure why. --Stef
(let* ((temp-buffer-name (format "*Annotate %s (rev %s)*" (buffer-name) rev))
! (temp-buffer-show-function 'vc-annotate-display-select)
! ;; If BUF is specified, we presume the caller maintains current line,
! ;; so we don't need to do it here. This implementation may give
! ;; strange results occasionally in the case of REV != WORKFILE-REV.
! (current-line (unless buf (line-number-at-pos))))
(message "Annotating...")
;; If BUF is specified it tells in which buffer we should put the
;; annotations. This is used when switching annotations to another
--- 3183,3189 ----
(vc-ensure-vc-buffer)
(setq vc-annotate-display-mode display-mode) ;Not sure why. --Stef
(let* ((temp-buffer-name (format "*Annotate %s (rev %s)*" (buffer-name) rev))
! (current-line (line-number-at-pos)))
(message "Annotating...")
;; If BUF is specified it tells in which buffer we should put the
;; annotations. This is used when switching annotations to another
***************
*** 3196,3221 ****
(rename-buffer temp-buffer-name t)
;; In case it had to be uniquified.
(setq temp-buffer-name (buffer-name))))
! (with-output-to-temp-buffer temp-buffer-name
! (vc-call annotate-command file (get-buffer temp-buffer-name) rev)
! ;; we must setup the mode first, and then set our local
! ;; variables before the show-function is called at the exit of
! ;; with-output-to-temp-buffer
! (with-current-buffer temp-buffer-name
! (if (not (equal major-mode 'vc-annotate-mode))
! (vc-annotate-mode))
! (set (make-local-variable 'vc-annotate-backend) (vc-backend file))
! (set (make-local-variable 'vc-annotate-parent-file) file)
! (set (make-local-variable 'vc-annotate-parent-rev) rev)
! (set (make-local-variable 'vc-annotate-parent-display-mode)
! display-mode)))
!
! (vc-exec-after
! `(progn
! (when ,current-line
! (goto-line ,current-line ,temp-buffer-name))
! (unless (active-minibuffer-window)
! (message "Annotating... done"))))))
(defun vc-annotate-prev-version (prefix)
"Visit the annotation of the version previous to this one.
--- 3192,3215 ----
(rename-buffer temp-buffer-name t)
;; In case it had to be uniquified.
(setq temp-buffer-name (buffer-name))))
! (vc-call annotate-command file temp-buffer-name rev)
! ;; we must setup the mode first, and then set our local
! ;; variables before the show-function is called
! (with-current-buffer temp-buffer-name
! (if (not (equal major-mode 'vc-annotate-mode))
! (vc-annotate-mode))
! (set (make-local-variable 'vc-annotate-backend) (vc-backend file))
! (set (make-local-variable 'vc-annotate-parent-file) file)
! (set (make-local-variable 'vc-annotate-parent-rev) rev)
! (set (make-local-variable 'vc-annotate-parent-display-mode)
! display-mode)
! (vc-annotate-display-select temp-buffer-name)
! (vc-exec-after
! `(progn
! (goto-line ,current-line ,temp-buffer-name)
! (pop-to-buffer ,temp-buffer-name)
! (unless (active-minibuffer-window)
! (message "Annotating... done")))))))
(defun vc-annotate-prev-version (prefix)
"Visit the annotation of the version previous to this one.
***************
*** 3312,3318 ****
(if (not (equal major-mode 'vc-annotate-mode))
(message "Cannot be invoked outside of a vc annotate buffer")
(let* ((buf (current-buffer))
- (oldline (line-number-at-pos))
(revspeccopy revspec)
(newrev nil))
(cond
--- 3306,3311 ----
***************
*** 3339,3348 ****
(when newrev
(vc-annotate vc-annotate-parent-file newrev
vc-annotate-parent-display-mode
! buf)
! (goto-line (min oldline (progn (goto-char (point-max))
! (previous-line)
! (line-number-at-pos))) buf)))))
(defun vc-annotate-compcar (threshold a-list)
"Test successive cons cells of A-LIST against THRESHOLD.
--- 3332,3338 ----
(when newrev
(vc-annotate vc-annotate-parent-file newrev
vc-annotate-parent-display-mode
! buf)))))
(defun vc-annotate-compcar (threshold a-list)
"Test successive cons cells of A-LIST against THRESHOLD.
[-- Attachment #3: Type: text/plain, Size: 142 bytes --]
_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: vc.el: asynchronous annotations
2007-07-15 23:20 vc.el: asynchronous annotations David Kastrup
@ 2007-07-16 15:42 ` Stefan Monnier
2007-07-16 16:15 ` David Kastrup
0 siblings, 1 reply; 6+ messages in thread
From: Stefan Monnier @ 2007-07-16 15:42 UTC (permalink / raw)
To: David Kastrup; +Cc: emacs-devel
> I have gone through with an example backend of my own as well as with
> vc-cvs (which inexplicably still works synchronously here),
Can you give me more information about your setup? The CVS annotate is only
asynchronous if the repository is remote and if vc-stay-local is t.
Maybe your test repository is local?
> I am not sure I like the behavior when doing P or N or similar in the
> annotation buffer: since the buffer is reused, it is cleared and
> filled with new material while being displayed on the screen.
It's not ideal, but there isn't much we can do about it. The best is to
provide an option for the user to choose something else (e.g. to force
synchronous behavior).
> There are two ways around that, I guess. One way would be to switch
> back to the source buffer while the operation progresses.
What do you mean "switch"? As in `switch-to-buffer'? That will fail if the
window is dedicated.
> Another way would be to _not_ reuse the buffer but instead delete the old
> buffer once the new one is complete.
Again, this will fail if the window is dedicated.
OTOH it reminds me of a proposed feature: make it possible to exchange the
text (plus related data like text-properties, markers, overlays) of
two buffers.
With such a feature, we could indeed run the async process in another buffer
and then bring the result into the old buffer. The original motivation for
such a feature was tar-mode where we'd like to move the tarball bytes into
an auxiliary buffer (kept in unibyte mode) and have the "main" buffer only
contain the tar listing (in multibyte mode). This would save us from
constantly switching between multibyte and unibyte modes and would clean up
the code.
> Anyway, here is a patch regarding the current working state at my end.
> Stefan, what do you say?
> *** vc.el 09 Jul 2007 23:10:04 +0200 1.432
> --- vc.el 16 Jul 2007 01:09:39 +0200
> ***************
> *** 3123,3129 ****
> use; you may override this using the second optional arg MODE."
> (interactive)
> (if mode (setq vc-annotate-display-mode mode))
> ! (pop-to-buffer (or buffer (current-buffer)))
> (cond ((null vc-annotate-display-mode)
> ;; The ratio is global, thus relative to the global color-map.
> (kill-local-variable 'vc-annotate-color-map)
> --- 3123,3129 ----
> use; you may override this using the second optional arg MODE."
> (interactive)
> (if mode (setq vc-annotate-display-mode mode))
> ! (if buffer (set-buffer buffer))
> (cond ((null vc-annotate-display-mode)
> ;; The ratio is global, thus relative to the global color-map.
> (kill-local-variable 'vc-annotate-color-map)
I strongly dislike this part. The buffer should be shown immediately.
Just as is the case when you do N and P (so any problem from which this may
suffer has to be fixed anyway for other cases).
Or are you saying that it is shown anyway because of the call to
vc-annotate-display-select?
> --- 3192,3215 ----
> (rename-buffer temp-buffer-name t)
> ;; In case it had to be uniquified.
> (setq temp-buffer-name (buffer-name))))
> ! (vc-call annotate-command file temp-buffer-name rev)
> ! ;; we must setup the mode first, and then set our local
> ! ;; variables before the show-function is called
> ! (with-current-buffer temp-buffer-name
> ! (if (not (equal major-mode 'vc-annotate-mode))
> ! (vc-annotate-mode))
> ! (set (make-local-variable 'vc-annotate-backend) (vc-backend file))
> ! (set (make-local-variable 'vc-annotate-parent-file) file)
> ! (set (make-local-variable 'vc-annotate-parent-rev) rev)
> ! (set (make-local-variable 'vc-annotate-parent-display-mode)
> ! display-mode)
> ! (vc-annotate-display-select temp-buffer-name)
I'm not sure why you moved the vc-call outside of the
with-output-to-temp-buffer. It seems harmless, but it also seems pointless,
so unless it's just an accident (resulting for other temporary attempts at
something) I'd like to know why this was done.
Similarly, what was the motivation for moving the call to
vc-annotate-display-select?
> ! (vc-exec-after
> ! `(progn
> ! (goto-line ,current-line ,temp-buffer-name)
> ! (pop-to-buffer ,temp-buffer-name)
> ! (unless (active-minibuffer-window)
> ! (message "Annotating... done")))))))
Doing a pop-to-buffer from a process sentinel is a problem: it works, but
can be very annoying for the user (especially, but not only, if she's
looking at her keyboard while typing).
Stefan
In-Reply-To: <85k5t12qzs.fsf@lola.goethe.zz> (David Kastrup's message of "Mon, 16 Jul 2007 01:20:55 +0200")
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1.50 (gnu/linux)
Date: Mon, 16 Jul 2007 11:42:26 -0400
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: vc.el: asynchronous annotations
2007-07-16 15:42 ` Stefan Monnier
@ 2007-07-16 16:15 ` David Kastrup
2007-07-16 17:29 ` Stefan Monnier
0 siblings, 1 reply; 6+ messages in thread
From: David Kastrup @ 2007-07-16 16:15 UTC (permalink / raw)
To: Stefan Monnier; +Cc: emacs-devel
Stefan Monnier <monnier@iro.umontreal.ca> writes:
>> I have gone through with an example backend of my own as well as with
>> vc-cvs (which inexplicably still works synchronously here),
>
> Can you give me more information about your setup? The CVS annotate is only
> asynchronous if the repository is remote and if vc-stay-local is t.
> Maybe your test repository is local?
Nope. And vc-stay-local returns t. No idea, I'll look more closely.
>> I am not sure I like the behavior when doing P or N or similar in the
>> annotation buffer: since the buffer is reused, it is cleared and
>> filled with new material while being displayed on the screen.
>
> It's not ideal, but there isn't much we can do about it. The best is to
> provide an option for the user to choose something else (e.g. to force
> synchronous behavior).
It is extremely distracting. One nuisance is that the correct line
can only be jumped to once the annotation is complete. One could
possibly do this in the filter routine, switching from
insert-before-markers to insert once the correct line has been
reached, but I doubt it would be much prettier.
>> There are two ways around that, I guess. One way would be to switch
>> back to the source buffer while the operation progresses.
>
> What do you mean "switch"? As in `switch-to-buffer'? That will fail if the
> window is dedicated.
Which is not necessarily the rule. Anyway, that's not the solution I like.
>> Another way would be to _not_ reuse the buffer but instead delete the old
>> buffer once the new one is complete.
>
> Again, this will fail if the window is dedicated.
>
> OTOH it reminds me of a proposed feature: make it possible to exchange the
> text (plus related data like text-properties, markers, overlays) of
> two buffers.
That would not require much Lisp, I guess. It would probably be
easiest to just append the new stuff at the end of the current buffer
in an invisible overlay, then move the point, delete the old material
and make the new stuff visible. Perhaps some recentering will occur.
> With such a feature, we could indeed run the async process in
> another buffer and then bring the result into the old buffer. The
> original motivation for such a feature was tar-mode where we'd like
> to move the tarball bytes into an auxiliary buffer (kept in unibyte
> mode) and have the "main" buffer only contain the tar listing (in
> multibyte mode). This would save us from constantly switching
> between multibyte and unibyte modes and would clean up the code.
Shadow-buffers don't help in this case?
>> Anyway, here is a patch regarding the current working state at my end.
>> Stefan, what do you say?
>
>> *** vc.el 09 Jul 2007 23:10:04 +0200 1.432
>> --- vc.el 16 Jul 2007 01:09:39 +0200
>> ***************
>> *** 3123,3129 ****
>> use; you may override this using the second optional arg MODE."
>> (interactive)
>> (if mode (setq vc-annotate-display-mode mode))
>> ! (pop-to-buffer (or buffer (current-buffer)))
>> (cond ((null vc-annotate-display-mode)
>> ;; The ratio is global, thus relative to the global color-map.
>> (kill-local-variable 'vc-annotate-color-map)
>> --- 3123,3129 ----
>> use; you may override this using the second optional arg MODE."
>> (interactive)
>> (if mode (setq vc-annotate-display-mode mode))
>> ! (if buffer (set-buffer buffer))
>> (cond ((null vc-annotate-display-mode)
>> ;; The ratio is global, thus relative to the global color-map.
>> (kill-local-variable 'vc-annotate-color-map)
>
> I strongly dislike this part. The buffer should be shown immediately.
> Just as is the case when you do N and P (so any problem from which this may
> suffer has to be fixed anyway for other cases).
> Or are you saying that it is shown anyway because of the call to
> vc-annotate-display-select?
No, I've taken the pop-to-buffer out as you can see. You are
basically proposing to exchange the one case where the behavior is
tolerable with intolerable behavior throughout, for consistency's
sake. I'd rather like it the other way round...
>> --- 3192,3215 ----
>> (rename-buffer temp-buffer-name t)
>> ;; In case it had to be uniquified.
>> (setq temp-buffer-name (buffer-name))))
>> ! (vc-call annotate-command file temp-buffer-name rev)
>> ! ;; we must setup the mode first, and then set our local
>> ! ;; variables before the show-function is called
>> ! (with-current-buffer temp-buffer-name
>> ! (if (not (equal major-mode 'vc-annotate-mode))
>> ! (vc-annotate-mode))
>> ! (set (make-local-variable 'vc-annotate-backend) (vc-backend file))
>> ! (set (make-local-variable 'vc-annotate-parent-file) file)
>> ! (set (make-local-variable 'vc-annotate-parent-rev) rev)
>> ! (set (make-local-variable 'vc-annotate-parent-display-mode)
>> ! display-mode)
>> ! (vc-annotate-display-select temp-buffer-name)
>
> I'm not sure why you moved the vc-call outside of the
> with-output-to-temp-buffer.
I removed the with-output-to-temp-buffer altogether. I think that the
motivation was that with-output-to-temp-buffer made it very obscure
for annotate-command to influence the encoding in which the command
output was interpreted from the annotate command, and in which it was
written out.
> It seems harmless, but it also seems pointless, so unless it's just
> an accident (resulting for other temporary attempts at something)
> I'd like to know why this was done.
>
> Similarly, what was the motivation for moving the call to
> vc-annotate-display-select?
vc-annotate-display-select is written in a manner that sets up the
highlighting immediately in some cases, and delays it with
vc-exec-after in some other cases. Moving it made it do the right
thing in both synchronous and asynchronous calls.
>> ! (vc-exec-after
>> ! `(progn
>> ! (goto-line ,current-line ,temp-buffer-name)
>> ! (pop-to-buffer ,temp-buffer-name)
>> ! (unless (active-minibuffer-window)
>> ! (message "Annotating... done")))))))
>
> Doing a pop-to-buffer from a process sentinel is a problem: it
> works, but can be very annoying for the user (especially, but not
> only, if she's looking at her keyboard while typing).
Don't commands like man and woman also do that?
--
David Kastrup
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: vc.el: asynchronous annotations
2007-07-16 16:15 ` David Kastrup
@ 2007-07-16 17:29 ` Stefan Monnier
2007-07-16 20:57 ` David Kastrup
0 siblings, 1 reply; 6+ messages in thread
From: Stefan Monnier @ 2007-07-16 17:29 UTC (permalink / raw)
To: David Kastrup; +Cc: emacs-devel
>> OTOH it reminds me of a proposed feature: make it possible to exchange the
>> text (plus related data like text-properties, markers, overlays) of
>> two buffers.
> That would not require much Lisp, I guess.
No, that would be implemented at the C level.
> It would probably be easiest to just append the new stuff at the end of
> the current buffer in an invisible overlay, then move the point, delete
> the old material and make the new stuff visible.
Sounds like a good way to get into trouble: invisible text is still visible
to most Lisp code (e.g. save etc...).
>> With such a feature, we could indeed run the async process in
>> another buffer and then bring the result into the old buffer. The
>> original motivation for such a feature was tar-mode where we'd like
>> to move the tarball bytes into an auxiliary buffer (kept in unibyte
>> mode) and have the "main" buffer only contain the tar listing (in
>> multibyte mode). This would save us from constantly switching
>> between multibyte and unibyte modes and would clean up the code.
> Shadow-buffers don't help in this case?
What are shadow buffers? The issue is basically that we start with the tar
file's content in buffer "foo.tar", but we want in the end to have there
only the listing of the contents. Currently we do what you propose above
(with narrowing instead of invisible), but that's a bit delicate at times
and requires switching regularly from unibyte to multibyte which is an
operation whose cost is proportional to the size of the buffer. What we'd
want instead is to have two buffers, one multibyte and the other unibyte,
but the one buffer that has to have the multibyte content is the one that we
receive with the unibyte content. So we'd need to exchange the contents of
the two buffers. We can do it with just an `insert-buffer-substring', but
if the buffer is very large (as can happen often with tar buffers), this can
be a problem. A primitive "buffer-exchange-text" would be a lot
more efficient.
>> I strongly dislike this part. The buffer should be shown immediately.
>> Just as is the case when you do N and P (so any problem from which this may
>> suffer has to be fixed anyway for other cases).
>> Or are you saying that it is shown anyway because of the call to
>> vc-annotate-display-select?
> No, I've taken the pop-to-buffer out as you can see. You are
> basically proposing to exchange the one case where the behavior is
> tolerable with intolerable behavior throughout, for consistency's
> sake. I'd rather like it the other way round...
No, I'm saying that I don't want a half fix. I want to fix the N and
P cases as well, so there's no point trying to hack around the problem at
the one place where it can be done more easily.
>> I'm not sure why you moved the vc-call outside of the
>> with-output-to-temp-buffer.
> I removed the with-output-to-temp-buffer altogether. I think that the
> motivation was that with-output-to-temp-buffer made it very obscure
> for annotate-command to influence the encoding in which the command
> output was interpreted from the annotate command, and in which it was
> written out.
Hmm... I'm not in love with with-output-to-temp-buffer, so I can agree with
the idea, but then we have to be careful to check that it doesn't change too
much of the behavior. E.g. IIRC with-output-to-temp-buffer puts the buffer
in view-mode and marks it as unmodified.
>>> ! (vc-exec-after
>>> ! `(progn
>>> ! (goto-line ,current-line ,temp-buffer-name)
>>> ! (pop-to-buffer ,temp-buffer-name)
>>> ! (unless (active-minibuffer-window)
>>> ! (message "Annotating... done")))))))
>>
>> Doing a pop-to-buffer from a process sentinel is a problem: it
>> works, but can be very annoying for the user (especially, but not
>> only, if she's looking at her keyboard while typing).
> Don't commands like man and woman also do that?
That doesn't mean it's a feature.
Stefan
PS: My local version of man.el was hacked to not do that, BTW.
I haven't submitted a patch for it yet because it's an ugly hack.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: vc.el: asynchronous annotations
2007-07-16 17:29 ` Stefan Monnier
@ 2007-07-16 20:57 ` David Kastrup
2007-07-17 3:42 ` Stefan Monnier
0 siblings, 1 reply; 6+ messages in thread
From: David Kastrup @ 2007-07-16 20:57 UTC (permalink / raw)
To: Stefan Monnier; +Cc: emacs-devel
Stefan Monnier <monnier@iro.umontreal.ca> writes:
>>> OTOH it reminds me of a proposed feature: make it possible to exchange the
>>> text (plus related data like text-properties, markers, overlays) of
>>> two buffers.
>
>> That would not require much Lisp, I guess.
>
> No, that would be implemented at the C level.
>
>> It would probably be easiest to just append the new stuff at the end of
>> the current buffer in an invisible overlay, then move the point, delete
>> the old material and make the new stuff visible.
>
> Sounds like a good way to get into trouble: invisible text is still visible
> to most Lisp code (e.g. save etc...).
>
>>> With such a feature, we could indeed run the async process in
>>> another buffer and then bring the result into the old buffer. The
>>> original motivation for such a feature was tar-mode where we'd like
>>> to move the tarball bytes into an auxiliary buffer (kept in unibyte
>>> mode) and have the "main" buffer only contain the tar listing (in
>>> multibyte mode). This would save us from constantly switching
>>> between multibyte and unibyte modes and would clean up the code.
>
>> Shadow-buffers don't help in this case?
>
> What are shadow buffers?
Ok, wrong term.
(info "(elisp) Indirect Buffers")
But they are rather for the same content under different
circumstances. I doubt that one could give them different
multibyteness.
Anyway, I don't see the big problem with supplanting buffers (probably
because I am stupid). set-window-buffer should make it reasonably
easy to swap out buffers on the screen.
--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: vc.el: asynchronous annotations
2007-07-16 20:57 ` David Kastrup
@ 2007-07-17 3:42 ` Stefan Monnier
0 siblings, 0 replies; 6+ messages in thread
From: Stefan Monnier @ 2007-07-17 3:42 UTC (permalink / raw)
To: David Kastrup; +Cc: emacs-devel
> Anyway, I don't see the big problem with supplanting buffers (probably
> because I am stupid). set-window-buffer should make it reasonably
> easy to swap out buffers on the screen.
Can't do: find-file-noselect first load the tarball data into buffer 1 then
calls tar-mode in it then returns buffer 1 which is then displayed by
find-file. There's nowhere for tar-mode to tell find-file-noselect to use
buffer 2 instead.
Stefan
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2007-07-17 3:42 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-15 23:20 vc.el: asynchronous annotations David Kastrup
2007-07-16 15:42 ` Stefan Monnier
2007-07-16 16:15 ` David Kastrup
2007-07-16 17:29 ` Stefan Monnier
2007-07-16 20:57 ` David Kastrup
2007-07-17 3:42 ` Stefan Monnier
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.