GNU bug report logs -
#78693
14.0.9; Folding of math macros with a function spec is broken
Previous Next
To reply to this bug, email your comments to 78693 AT debbugs.gnu.org.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Wed, 04 Jun 2025 08:49:04 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
Rahguzar <rahguzar <at> mailbox.org>
:
New bug report received and forwarded. Copy sent to
bug-auctex <at> gnu.org
.
(Wed, 04 Jun 2025 08:49:04 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Dear AucTeX maintainers,
The commits
d0a57d8d Fix math macro folding to not consume subsequent brackets
33f9eb07 Fix TeX macro end detection in some edge cases
break the folding of math macros with a function spec.
E.g. evaluate
(setq TeX-fold-math-spec-list `((,(lambda (text) (propertize text 'face '(underline))) ("underline"))))
and open the attached file. Do `M-x TeX-fold-mode RET` followed by `M-x
TeX-fold-buffer RET`. This results in
[Error: no content or function found]
getting displayed instead of \underline.
My config has many folding specs which are functions and all of them
exhibit the same behavior.
Reverting the commits above fixes the issue.
Thanks,
Rahguzar
Emacs : GNU Emacs 30.1 (build 1, aarch64-redhat-linux-gnu, GTK+ Version 3.24.49, cairo version 1.18.2)
of 2025-04-08
Package: 14.0.9
current state:
==============
(setq
window-system 'pgtk
LaTeX-version "2e"
TeX-style-path '("/home/azeem/.local/state/emacs/auctex/" "/home/azeem/.local/state/emacs/elpaca/builds/auctex/style" "/home/azeem/.local/state/emacs/auctex/auto"
"/home/azeem/.local/state/emacs/auctex/style" "auto" "style")
TeX-auto-save nil
TeX-parse-self nil
TeX-master t
TeX-command-list '(("TeX" "%(PDF)%(tex) %(file-line-error) %`%(extraopts) %S%(PDFout)%(mode)%' %(output-dir) %t" TeX-run-TeX nil (plain-TeX-mode AmSTeX-mode Texinfo-mode) :help "Run plain TeX")
("LaTeX" "%`%l%(mode)%' %T" TeX-run-TeX nil (LaTeX-mode docTeX-mode) :help "Run LaTeX")
("Makeinfo" "makeinfo %(extraopts) %(o-dir) %t" TeX-run-compile nil (Texinfo-mode) :help "Run Makeinfo with Info output")
("Makeinfo HTML" "makeinfo %(extraopts) %(o-dir) --html %t" TeX-run-compile nil (Texinfo-mode) :help "Run Makeinfo with HTML output")
("AmSTeX" "amstex %(PDFout) %`%(extraopts) %S%(mode)%' %(output-dir) %t" TeX-run-TeX nil (AmSTeX-mode) :help "Run AMSTeX")
("ConTeXt" "%(cntxcom) --once %(extraopts) %(execopts)%t" TeX-run-TeX nil (ConTeXt-mode) :help "Run ConTeXt once")
("ConTeXt Full" "%(cntxcom) %(extraopts) %(execopts)%t" TeX-run-TeX nil (ConTeXt-mode) :help "Run ConTeXt until completion")
("BibTeX" "bibtex %(O?aux)" TeX-run-BibTeX nil (plain-TeX-mode LaTeX-mode docTeX-mode AmSTeX-mode Texinfo-mode ConTeXt-mode) :help "Run BibTeX")
("Biber" "biber %(output-dir) %s" TeX-run-Biber nil (plain-TeX-mode LaTeX-mode docTeX-mode AmSTeX-mode Texinfo-mode) :help "Run Biber")
("Texindex" "texindex %s.??" TeX-run-command nil (Texinfo-mode) :help "Run Texindex")
("Texi2dvi" "%(PDF)texi2dvi %t" TeX-run-command nil (Texinfo-mode) :help "Run Texi2dvi or Texi2pdf") ("View" "%V" TeX-run-discard-or-function t t :help "Run Viewer")
("Print" "%p" TeX-run-command t t :help "Print the file") ("Queue" "%q" TeX-run-background nil t :help "View the printer queue" :visible TeX-queue-command)
("File" "%(o?)dvips %d -o %f " TeX-run-dvips t (plain-TeX-mode LaTeX-mode docTeX-mode AmSTeX-mode Texinfo-mode) :help "Generate PostScript file")
("Dvips" "%(o?)dvips %d -o %f " TeX-run-dvips nil (plain-TeX-mode LaTeX-mode docTeX-mode AmSTeX-mode Texinfo-mode) :help "Convert DVI file to PostScript")
("Dvipdfmx" "dvipdfmx -o %(O?pdf) %d" TeX-run-dvipdfmx nil (plain-TeX-mode LaTeX-mode docTeX-mode AmSTeX-mode Texinfo-mode) :help "Convert DVI file to PDF with dvipdfmx")
("Ps2pdf" "ps2pdf %f %(O?pdf)" TeX-run-ps2pdf nil (plain-TeX-mode LaTeX-mode docTeX-mode AmSTeX-mode Texinfo-mode) :help "Convert PostScript file to PDF")
("LaTeXMk" "latexmk %(latexmk-out) %(file-line-error) %(output-dir) %`%(extraopts) %S%(mode)%' %t" TeX-run-TeX nil (LaTeX-mode docTeX-mode) :help "Run LaTeXMk")
("Glossaries" "makeglossaries %(d-dir) %s" TeX-run-command nil (plain-TeX-mode LaTeX-mode docTeX-mode AmSTeX-mode Texinfo-mode) :help
"Run makeglossaries to create glossary file")
("Index" "makeindex %(O?idx)" TeX-run-index nil (plain-TeX-mode LaTeX-mode docTeX-mode AmSTeX-mode Texinfo-mode) :help "Run makeindex to create index file")
("upMendex" "upmendex %(O?idx)" TeX-run-index t (plain-TeX-mode LaTeX-mode docTeX-mode AmSTeX-mode Texinfo-mode) :help "Run upmendex to create index file")
("Xindy" "texindy %s" TeX-run-command nil (plain-TeX-mode LaTeX-mode docTeX-mode AmSTeX-mode Texinfo-mode) :help "Run xindy to create index file")
("Check" "lacheck %s" TeX-run-compile nil (LaTeX-mode) :help "Check LaTeX file for correctness")
("ChkTeX" "chktex -v6 %s" TeX-run-compile nil (LaTeX-mode) :help "Check LaTeX file for common mistakes")
("Spell" "(TeX-ispell-document \"\")" TeX-run-function nil t :help "Spell-check the document")
("Clean" "TeX-clean" TeX-run-function nil t :help "Delete generated intermediate files")
("Clean All" "(TeX-clean t)" TeX-run-function nil t :help "Delete generated intermediate and output files") ("Other" "" TeX-run-command t t :help "Run an arbitrary command"))
)
[test.tex (application/x-tex, attachment)]
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Wed, 04 Jun 2025 10:33:01 GMT)
Full text and
rfc822 format available.
Message #8 received at submit <at> debbugs.gnu.org (full text, mbox):
Thanks Raghuzar. The issue is the result of this change:
--8<---------------cut here---------------start------------->8---
diff --git a/tex-fold.el b/tex-fold.el
index 766270ef..78e5b822 100644
--- a/tex-fold.el
+++ b/tex-fold.el
@@ -901,6 +901,12 @@ TYPE can be either `env' for environments, `macro' for macros or
(goto-char (1+ start))
(LaTeX-find-matching-end)
(point))
+ ((eq type 'math)
+ (goto-char (1+ start))
+ (if (zerop (skip-chars-forward "A-Za-z@"))
+ (forward-char)
+ (skip-chars-forward "*"))
+ (point))
(t
(goto-char start)
(TeX-find-macro-end)))))
--8<---------------cut here---------------end--------------->8---
The intent here was that "math macros" built-in to tex-fold don't take
arguments, but this is not the case for the custom one you provide.
> (setq TeX-fold-math-spec-list `((,(lambda (text) (propertize text 'face '(underline))) ("underline"))))
Is there a reason to prefer this vs. the same with
TeX-fold-macro-spec-list in place of TeX-fold-math-spec-list?
Paul
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Fri, 06 Jun 2025 09:40:01 GMT)
Full text and
rfc822 format available.
Message #11 received at 78693 <at> debbugs.gnu.org (full text, mbox):
Hi Raghuzar, thanks for your suggestions.
Regarding (1) and (2), I searched my shared tex projects and found
examples that those approaches would not fold correctly:
> 1) Assume that there is no white-space between the macro name and the
> brackets enclosing the arguments. This is probably not how TeX syntax
> works but I think (not too sure about this) it is the usual style. This
> behavior can be controlled by a custom variable.
"\in[0,1]"
I also worry that style like
\includegraphics
[width=0.8\textwidth]
{result.pdf}
is not too uncommon.
> 2) Since the problem is with optional arguments we can allow { after the
> macro name but not [.
"\in{\rm SL}_2"
> 3) Another option can be to introduce a new spec alist for macros
> without optional args.
Maybe call it TeX-fold-unargumented-spec-list. Then, we would have:
TeX-fold-macro-spec-list
TeX-fold-math-spec-list
TeX-fold-env-spec-list
TeX-fold-unargumented-spec-list
The defaults for *math* would move to *unargumented* and *macro*/*math*
would behave identically. This seems a bit complicated.
Moreover, none of the above solutions address related (but rarer) issues
with argumented macros. For instance, if one includes \mathbf in
*macro*/*math*, then the following folds incorrectly:
$\mathbf{text} [0,1]$
(I feel like I've seen similar examples occur organically over the
years, but can't quickly think of one.)
----------------------------------------------------------------------
Here's a proposed solution that seems more robust to me. Recall that
*macro*/*math* are lists consisting of items
(SPEC (M1 M2 ...)),
where SPEC is a display specification (an integer, a string or a
function) and M1, M2, ... are macro names as strings. We could enhance
the display specification to allow
((SPEC . SIG) (M1 M2 ...)),
where SIG is a "signature" that restricts the number of args:
- nil means no restriction,
- an integer n means at most n total args (so 0 means unargumented), and
- a cons cell (p . q) means at most p optional and q required args.
With that enhancement, we could revert d0a57d8d and tag the defaults for
LaTeX-fold-math-spec-list with "0", e.g.,
("∈" ("in")) -> (("∈" . 0) ("in"))
That would fix the original "\in [0,1]" issue as well as the issue
raised by Raghuzar. It would also make it easy to fix related issues,
like the one with \mathbf noted above. Thoughts?
----------------------------------------------------------------------
I also thought I'd link the original proposal [1] for TeX-fold
math-spec-list. My reading is that the purpose of the *macro*/*math*
split was just to better organize the defaults.
[1]
https://lists.gnu.org/archive/html/auctex-devel/2007-01/msg00078.html
----------------------------------------------------------------------
Finally, I noticed that we've been CC'ing bug-auctex rather than the
specific bug number, which is generating duplicated bugs at
https://lists.gnu.org/archive/html/bug-auctex/2025-06/threads.html.
I've tried to fix that here.
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Sat, 07 Jun 2025 17:34:03 GMT)
Full text and
rfc822 format available.
Message #14 received at 78693 <at> debbugs.gnu.org (full text, mbox):
Hi Paul,
"Paul D. Nelson" <ultrono <at> gmail.com> writes:
> Here's a proposed solution that seems more robust to me. Recall that
> *macro*/*math* are lists consisting of items
>
> (SPEC (M1 M2 ...)),
>
> where SPEC is a display specification (an integer, a string or a
> function) and M1, M2, ... are macro names as strings. We could enhance
> the display specification to allow
>
> ((SPEC . SIG) (M1 M2 ...)),
>
> where SIG is a "signature" that restricts the number of args:
>
> - nil means no restriction,
>
> - an integer n means at most n total args (so 0 means unargumented), and
>
> - a cons cell (p . q) means at most p optional and q required args.
>
> With that enhancement, we could revert d0a57d8d and tag the defaults for
> LaTeX-fold-math-spec-list with "0", e.g.,
>
> ("∈" ("in")) -> (("∈" . 0) ("in"))
>
> That would fix the original "\in [0,1]" issue as well as the issue
> raised by Raghuzar. It would also make it easy to fix related issues,
> like the one with \mathbf noted above. Thoughts?
I like this proposal. It is backward compatible I think it should also
allow us to deal with optional arguments in a function spec. Currently
if the spec is a function it only receives the mandatory arguments. If
the number of arguments is part of the spec we can allow it to receive
up to p+q args without breaking existing code.
> Finally, I noticed that we've been CC'ing bug-auctex rather than the
> specific bug number, which is generating duplicated bugs at
> https://lists.gnu.org/archive/html/bug-auctex/2025-06/threads.html.
> I've tried to fix that here.
Thanks for catching this. I was surprised by emails about those new bugs.
Rahguzar
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Sat, 07 Jun 2025 18:34:02 GMT)
Full text and
rfc822 format available.
Message #17 received at 78693 <at> debbugs.gnu.org (full text, mbox):
Hi Raghuzar,
> I like this proposal. It is backward compatible I think it should also
> allow us to deal with optional arguments in a function spec.
OK, great. I'll try fleshing it out when I get the chance.
> Currently if the spec is a function it only receives the mandatory
> arguments. If the number of arguments is part of the spec we can allow
> it to receive up to p+q args without breaking existing code.
Regarding optional arguments, I am in the habit of extracting those
using TeX-fold-macro-nth-arg. This is possible because (with recent
enough AUCTeX) the function display spec is always called with point at
the beginning of the macro to be folded. See for instance the
implementation of TeX-fold-cite-display.
For this reason, I'm inclined to first implement the proposal without
changing how optional args are used - we could change that later, if
desired.
Thanks, best,
Paul
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Mon, 09 Jun 2025 18:04:01 GMT)
Full text and
rfc822 format available.
Message #20 received at 78693 <at> debbugs.gnu.org (full text, mbox):
Hi Paul,
"Paul D. Nelson" <ultrono <at> gmail.com> writes:
> Hi Raghuzar,
>
>> Currently if the spec is a function it only receives the mandatory
>> arguments. If the number of arguments is part of the spec we can allow
>> it to receive up to p+q args without breaking existing code.
>
> Regarding optional arguments, I am in the habit of extracting those
> using TeX-fold-macro-nth-arg. This is possible because (with recent
> enough AUCTeX) the function display spec is always called with point at
> the beginning of the macro to be folded. See for instance the
> implementation of TeX-fold-cite-display.
>
> For this reason, I'm inclined to first implement the proposal without
> changing how optional args are used - we could change that later, if
> desired.
I think the difference between passing optional arg now vs later would
be backward compatibility. Since the the signature part of spec is new
there are no backward compatibility concerns. However if people start
using the feature assuming no optional arguments are passed to the
function and we start passing them later there can be breakage.
I think passing the arguments directly to the function is more user
friendly. However, I think documenting TeX-fold-macro-nth-arg as the way
to access optional arguments is also good enough.
>
> Thanks, best,
> Paul
Best,
Rahguzar
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Wed, 11 Jun 2025 07:34:01 GMT)
Full text and
rfc822 format available.
Message #23 received at submit <at> debbugs.gnu.org (full text, mbox):
forcemerge 78693 78696 78698
thanks
Rahguzar via bug-auctex via Bug reporting list for AUCTeX <bug-auctex <at> gnu.org> writes:
> Dear AucTeX maintainers,
>
> The commits
>
> d0a57d8d Fix math macro folding to not consume subsequent brackets
> 33f9eb07 Fix TeX macro end detection in some edge cases
>
> break the folding of math macros with a function spec.
Gents,
somehow 3 bug reports where opened for this report which I'm merging
now. Please try to avoid this in future. TIA.
Best, Arash
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Wed, 11 Jun 2025 07:34:02 GMT)
Full text and
rfc822 format available.
Forcibly Merged 78693 78696 78698.
Request was from
Arash Esbati <arash <at> gnu.org>
to
control <at> debbugs.gnu.org
.
(Wed, 11 Jun 2025 07:34:02 GMT)
Full text and
rfc822 format available.
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Wed, 11 Jun 2025 07:37:02 GMT)
Full text and
rfc822 format available.
Message #31 received at 78693 <at> debbugs.gnu.org (full text, mbox):
Arash Esbati <arash <at> gnu.org> writes:
> somehow 3 bug reports where opened for this report which I'm merging
> now. Please try to avoid this in future. TIA.
Thanks. For future reference, the issue is that I was CC'd on the
original bug (and responded to that message, causing a cascade of new
bugs), but the correct approach (as I've now learned) is to use the
X-Debbugs-CC pseudo-header (https://www.debian.org/Bugs/Reporting).
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Wed, 11 Jun 2025 07:37:03 GMT)
Full text and
rfc822 format available.
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Sun, 15 Jun 2025 10:30:02 GMT)
Full text and
rfc822 format available.
Message #37 received at 78693 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Hi Raghuzar and all,
Please see the attached patch which implements signature support for
macro folds, following the plan outlined in my earlier email. This
should address both the issue in your report and that in my earlier bug.
We also need to update the manual, but I'll do that later once the
general shape of the proposal is agreed upon. If you get the chance,
please let me know what you think.
Thanks, best,
Paul
[0001-Add-signature-support-for-macro-folding.patch (text/x-patch, attachment)]
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Sat, 21 Jun 2025 09:56:06 GMT)
Full text and
rfc822 format available.
Message #40 received at 78693 <at> debbugs.gnu.org (full text, mbox):
Hi Paul,
"Paul D. Nelson" <ultrono <at> gmail.com> writes:
> Hi Raghuzar and all,
>
> Please see the attached patch which implements signature support for
> macro folds, following the plan outlined in my earlier email. This
> should address both the issue in your report and that in my earlier bug.
> We also need to update the manual, but I'll do that later once the
> general shape of the proposal is agreed upon. If you get the chance,
> please let me know what you think.
I have tested the patch and resolve the original issue. I haven't tested
the new functionality using the SPEC.
One question about it: One problem I have had is that, if I have
something like
\begin{align}
[\hat{X},\hat{P}] = i\hbar
\end{align}
the commutator gets folded as an optional argument to the \begin.
It is possible to not have this effect with new machinery without
specifying \begin as not taking any optional arguments?
I have only seen optional arguments before mandatory ones but I don't
know if that can be relied upon in general.
> Thanks, best,
>
> Paul
Best,
Rahguzar
> [2. text/x-patch; 0001-Add-signature-support-for-macro-folding.patch]...
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Sat, 21 Jun 2025 10:08:06 GMT)
Full text and
rfc822 format available.
Message #43 received at 78693 <at> debbugs.gnu.org (full text, mbox):
Hi Raghuzar,
> I have tested the patch and resolve the original issue. I haven't tested
> the new functionality using the SPEC.
Thanks.
> One question about it: One problem I have had is that, if I have
> something like
>
> \begin{align}
> [\hat{X},\hat{P}] = i\hbar
> \end{align}
>
> the commutator gets folded as an optional argument to the \begin.
> It is possible to not have this effect with new machinery without
> specifying \begin as not taking any optional arguments?
Could you please share your tex folding config, or better, the part
relevant for folding \begin{align}?
> I have only seen optional arguments before mandatory ones but I don't
> know if that can be relied upon in general.
What about "\begin{theorem}[My Favorite Theorem]"?
Paul
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Sun, 22 Jun 2025 07:16:02 GMT)
Full text and
rfc822 format available.
Message #46 received at 78693 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Hi Paul,
"Paul D. Nelson" <ultrono <at> gmail.com> writes:
> Hi Raghuzar,
>
>> I have tested the patch and resolve the original issue. I haven't tested
>> the new functionality using the SPEC.
>
> Thanks.
>
>> One question about it: One problem I have had is that, if I have
>> something like
>>
>> \begin{align}
>> [\hat{X},\hat{P}] = i\hbar
>> \end{align}
>>
>> the commutator gets folded as an optional argument to the \begin.
>> It is possible to not have this effect with new machinery without
>> specifying \begin as not taking any optional arguments?
>
> Could you please share your tex folding config, or better, the part
> relevant for folding \begin{align}?
It is this:
(setq TeX-fold-macro-spec-list
`(("⬖ {1}" ("begin"))
("⬗ {1}" ("end"))))
and I have included a test.tex file which you can use to see the effect.
>> I have only seen optional arguments before mandatory ones but I don't
>> know if that can be relied upon in general.
>
> What about "\begin{theorem}[My Favorite Theorem]"?
>
> Paul
In my corner (theoretical physics) we don't do much theorem proving :)
I have used environments for theorems but very rarely. I expected optional
arguments after mandatory ones to be possible. For the example you give
my folding would be very annoying.
Rahguzar
[test.tex (application/x-tex, attachment)]
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Sun, 22 Jun 2025 07:41:02 GMT)
Full text and
rfc822 format available.
Message #49 received at 78693 <at> debbugs.gnu.org (full text, mbox):
Hi Raghuzar,
Rahguzar <rahguzar <at> mailbox.org> writes:
>>> One question about it: One problem I have had is that, if I have
>>> something like
>>>
>>> \begin{align}
>>> [\hat{X},\hat{P}] = i\hbar
>>> \end{align}
>>>
>>> the commutator gets folded as an optional argument to the \begin.
>>> It is possible to not have this effect with new machinery without
>>> specifying \begin as not taking any optional arguments?
>>
>> Could you please share your tex folding config, or better, the part
>> relevant for folding \begin{align}?
>
> It is this:
>
> (setq TeX-fold-macro-spec-list
> `(("⬖ {1}" ("begin"))
> ("⬗ {1}" ("end"))))
With the new folding signature support, you can achieve the desired
effect using either
;; At most 1 args.
(setq TeX-fold-macro-spec-list
`((("⬖ {1}" . 1) ("begin"))
(("⬗ {1}" . 1) ("end"))))
or
;; At most 0 optional, 1 required args.
(setq TeX-fold-macro-spec-list
`((("⬖ {1}" . (0 . 1)) ("begin"))
(("⬗ {1}" . (0 . 1)) ("end"))))
---
Another approach here would be prettification, assuming you're OK with
specifying each environment. I use something like:
(with-eval-after-load 'tex-mode
(mapc
(lambda (sym) (add-to-list 'tex--prettify-symbols-alist sym))
'(("\\begin{equation}" . ?↴)
("\\end{equation}" . ?↲)
("\\begin{align}" . ?⌈)
("\\end{align}" . ?⌋)
("\\begin{multline}" . ?⎧)
("\\end{multline}" . ?⎭))))
Paul
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Sun, 22 Jun 2025 10:38:01 GMT)
Full text and
rfc822 format available.
Message #52 received at 78693 <at> debbugs.gnu.org (full text, mbox):
Hi Paul,
"Paul D. Nelson" <ultrono <at> gmail.com> writes:
> Hi Raghuzar,
>
> Rahguzar <rahguzar <at> mailbox.org> writes:
>
>>>> One question about it: One problem I have had is that, if I have
>>>> something like
>>>>
>>>> \begin{align}
>>>> [\hat{X},\hat{P}] = i\hbar
>>>> \end{align}
>>>>
>>>> the commutator gets folded as an optional argument to the \begin.
>>>> It is possible to not have this effect with new machinery without
>>>> specifying \begin as not taking any optional arguments?
>>>
>>> Could you please share your tex folding config, or better, the part
>>> relevant for folding \begin{align}?
>>
>> It is this:
>>
>> (setq TeX-fold-macro-spec-list
>> `(("⬖ {1}" ("begin"))
>> ("⬗ {1}" ("end"))))
>
> With the new folding signature support, you can achieve the desired
> effect using either
>
> ;; At most 1 args.
> (setq TeX-fold-macro-spec-list
> `((("⬖ {1}" . 1) ("begin"))
> (("⬗ {1}" . 1) ("end"))))
>
> or
>
> ;; At most 0 optional, 1 required args.
> (setq TeX-fold-macro-spec-list
> `((("⬖ {1}" . (0 . 1)) ("begin"))
> (("⬗ {1}" . (0 . 1)) ("end"))))
>
> ---
Thanks, this works for my needs. I was worried about optional arguments
before the mandatory ones messing up the folding but those arguments
actually get swallowed by the folding. With your suggestion of using
TeX-fold-macro-nth-arg it is possible to handle optional args that come
before mandatory ones which passing a 1 or (0 . 1) as spec. A bit
confusing but it improves on the current situation and I don't think it
is possible handle folding perfectly given how "flexible" syntax in
(La)TeX is.
> Another approach here would be prettification, assuming you're OK with
> specifying each environment. I use something like:
>
> (with-eval-after-load 'tex-mode
> (mapc
> (lambda (sym) (add-to-list 'tex--prettify-symbols-alist sym))
> '(("\\begin{equation}" . ?↴)
> ("\\end{equation}" . ?↲)
> ("\\begin{align}" . ?⌈)
> ("\\end{align}" . ?⌋)
> ("\\begin{multline}" . ?⎧)
> ("\\end{multline}" . ?⎭))))
>
> Paul
Rahguzar
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Sun, 22 Jun 2025 20:43:03 GMT)
Full text and
rfc822 format available.
Message #55 received at 78693 <at> debbugs.gnu.org (full text, mbox):
Hi Rahguzar
> Thanks, this works for my needs. I was worried about optional arguments
> before the mandatory ones messing up the folding but those arguments
> actually get swallowed by the folding. With your suggestion of using
> TeX-fold-macro-nth-arg it is possible to handle optional args that come
> before mandatory ones which passing a 1 or (0 . 1) as spec. A bit
> confusing but it improves on the current situation and I don't think it
> is possible handle folding perfectly given how "flexible" syntax in
> (La)TeX is.
I'm glad it seems to be working for your needs, although I'm a bit
confused about what else you might be asking for here, i.e., what would
"perfect" folding like?
Paul
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Mon, 23 Jun 2025 07:17:01 GMT)
Full text and
rfc822 format available.
Message #58 received at 78693 <at> debbugs.gnu.org (full text, mbox):
Hi Paul,
"Paul D. Nelson" <ultrono <at> gmail.com> writes:
> Hi Rahguzar
>
>> Thanks, this works for my needs. I was worried about optional arguments
>> before the mandatory ones messing up the folding but those arguments
>> actually get swallowed by the folding. With your suggestion of using
>> TeX-fold-macro-nth-arg it is possible to handle optional args that come
>> before mandatory ones which passing a 1 or (0 . 1) as spec. A bit
>> confusing but it improves on the current situation and I don't think it
>> is possible handle folding perfectly given how "flexible" syntax in
>> (La)TeX is.
>
> I'm glad it seems to be working for your needs, although I'm a bit
> confused about what else you might be asking for here, i.e., what would
> "perfect" folding like?
Something that is able to distinguish between
\begin{theorem}[My favorite theorem]
and
\begin{equation}
[X,P]
but I really don't think that is possible except by re-implementing a
LaTeX compiler. The current situation is lot better (at least for me)
due to your effort.
Thanks!
Rahguzar
> Paul
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Mon, 23 Jun 2025 19:37:03 GMT)
Full text and
rfc822 format available.
Message #61 received at 78693 <at> debbugs.gnu.org (full text, mbox):
Hi Raghuzar,
Rahguzar <rahguzar <at> mailbox.org> writes:
> Something that is able to distinguish between
>
> \begin{theorem}[My favorite theorem]
>
> and
>
> \begin{equation}
> [X,P]
By default, tex-fold.el folds theorem environments (taking into account
their optional captions) but not equation environments. This happens
via the TeX-fold-macro-spec-list entries
(TeX-fold-begin-display ("begin"))
(TeX-fold-end-display ("end"))
and the TeX-fold-begin-end-spec-list entry for "theorem".
This approach would not correctly handle "equation" environments that
begin with commutator brackets, as you've noted, because the contains of
those brackets would be mistakenly consumed as if they were an optional
argument.
To treat such cases correctly, we could allow the signature (which with
the current version of the proposed patch can be an integer or pair of
integers, bounding the total or optional/required arguments) to be a
function. In TeX-find-macro-end-helper, we could call that function to
determine whether any additional arguments should be consumed, passing
along any arguments found thus far. We could assign the begin/end
macros a signature function that says "for \begin macros with
equation-like environments, don't accept any optional arguments". This
would allow meaningful folding of both examples, without the artifact
you have noted. On the other hand, it would require choosing good
defaults for which environments should not admit optional args, and I
don't have a clear sense there; do you?
In my own setup, I do not fold equation environments, but instead use
prettification, as described in my earlier email. This serves as a
practical workaround. Before I adopted it, I remember encountering the
same issue you described and using workarounds such as adding a blank
commented line before the commutator bracket.
Paul
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Tue, 24 Jun 2025 10:51:02 GMT)
Full text and
rfc822 format available.
Message #64 received at 78693 <at> debbugs.gnu.org (full text, mbox):
Hi Paul,
"Paul D. Nelson" <ultrono <at> gmail.com> writes:
> To treat such cases correctly, we could allow the signature (which with
> the current version of the proposed patch can be an integer or pair of
> integers, bounding the total or optional/required arguments) to be a
> function. In TeX-find-macro-end-helper, we could call that function to
> determine whether any additional arguments should be consumed, passing
> along any arguments found thus far. We could assign the begin/end
> macros a signature function that says "for \begin macros with
> equation-like environments, don't accept any optional arguments". This
> would allow meaningful folding of both examples, without the artifact
> you have noted. On the other hand, it would require choosing good
> defaults for which environments should not admit optional args, and I
> don't have a clear sense there; do you?
I think a function can be a good idea but I don't know what would be a
good design in that case? Should we pass it some arguments? I guess not
but a function without arguments would not be easiest to use. I guess it
will have to rely on TeX-fold-macro-nth-arg. One alternative I can think
of is to allow a function SPEC to return not only a string but also
(STR . BOUND) where BOUND determines the extent of the folding. In the
present case this would allow BOUND to determined by matching on the
environment name and this pattern matching wouldn't have to be
duplicated in the SPEC and SIG.
> In my own setup, I do not fold equation environments, but instead use
> prettification, as described in my earlier email. This serves as a
> practical workaround. Before I adopted it, I remember encountering the
> same issue you described and using workarounds such as adding a blank
> commented line before the commutator bracket.
I will try some more prettification the next time I mess with my config.
Thanks for that idea.
Rahguzar
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Sun, 06 Jul 2025 12:33:03 GMT)
Full text and
rfc822 format available.
Message #67 received at 78693 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Hi Rahguzar,
I thought about the further edge cases you raised. The attached patch
is what I came up with.
You mentioned the following problem: when folding \begin macros, you
want to consume optional arguments following (e.g.) \begin{theorem} but
not (e.g.) \begin{equation}, so as to avoid errors in, e.g.,
\begin{equation}
[X, Y] = Z
\end{equation}
With the attached patch, you can do so as follows:
--8<---------------cut here---------------start------------->8---
(defun my-equation-env-p (args)
"Return non-nil when ARGS describes an equation environment.
Return non-nil if the list ARGS is of the form
'(\"{env}\")
where ENV is an equation environment, such as equation, align, gather,
multline or their starred variants."
(and (= 1 (length args))
(let* ((envs (LaTeX--math-environment-list))
(re (concat "{" (regexp-opt envs) "}")))
(string-match-p re (car args)))))
(setq-local TeX-fold-macro-spec-list
`((("⬖ {1}" . my-equation-env-p) ("begin"))
(("⬗ {1}" . 1) ("end"))))
--8<---------------cut here---------------end--------------->8---
This says that when determining the folding extent of a \begin macro for
a display math environment, we stop after the first argument (which is
just the environment name).
As before, the "1" signature in the \end macro has the effect that in
\end{equation}
[blah]
we do not fold the trailing "[blah]".
Edge cases such as
\begin{equation}
\label{eq:blah} [X, Y] = Z
\end{equation}
are a bit subtler: with some packages, \label can accept optional
arguments, so we can't avoid such cases simply by restricting the number
of optional and required arguments. Instead, we use the macro spec list
entry
(("[l]" . TeX-fold-stop-after-first-required) ("label"))
with the following predicate:
(defun TeX-fold-stop-after-first-required (args)
"Return nil when final element of ARGS starts with \"{\"."
(and args (string-prefix-p "{" (car (last args)))))
With this, when we fold \label macros, we stop consuming after the first
required argument that we encounter. Thus, \label[...][...]{...} folds
correctly, while \label[...]{...}[...] stops after the {...}.
I can't think of any other edge cases. I think this patch is now ready
to ship, although I'd welcome any feedback.
Thanks, best,
Paul
[0001-Add-signature-support-for-macro-folding.patch (text/x-patch, attachment)]
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Sun, 20 Jul 2025 06:07:01 GMT)
Full text and
rfc822 format available.
Message #70 received at 78693 <at> debbugs.gnu.org (full text, mbox):
Hi Paul,
"Paul D. Nelson" <ultrono <at> gmail.com> writes:
> Hi Rahguzar,
>
> I thought about the further edge cases you raised. The attached patch
> is what I came up with.
Thanks! This solution of allowing the full power of
TeX-find-macro-boundaries in signature seems like the best one and in my
brief testing it works well and is very flexible.
> I can't think of any other edge cases. I think this patch is now ready
> to ship, although I'd welcome any feedback.
I also think that it is ready to ship. Thanks for all your work on this.
> Thanks, best,
>
> Paul
>
> [2. text/x-patch; 0001-Add-signature-support-for-macro-folding.patch]...
Best,
Rahguzar
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Sun, 03 Aug 2025 13:33:02 GMT)
Full text and
rfc822 format available.
Message #73 received at 78693 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Rahguzar <rahguzar <at> mailbox.org> writes:
> Hi Paul,
>
> "Paul D. Nelson" <ultrono <at> gmail.com> writes:
>
>> I can't think of any other edge cases. I think this patch is now ready
>> to ship, although I'd welcome any feedback.
>
> I also think that it is ready to ship. Thanks for all your work on this.
Thanks Raghuzar. Attaching an updated patch rebased to master. Since
it's a non-local change, I figure I'll wait for Arash or Ikumi to take a
quick sniff, then we can push and close.
Paul
[0001-Add-signature-support-for-macro-folding.patch (text/x-patch, attachment)]
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Tue, 05 Aug 2025 08:41:01 GMT)
Full text and
rfc822 format available.
Message #76 received at 78693 <at> debbugs.gnu.org (full text, mbox):
Hi Paul,
>>>>> "Paul D. Nelson" <ultrono <at> gmail.com> writes:
> Thanks Raghuzar. Attaching an updated patch rebased to master. Since
> it's a non-local change, I figure I'll wait for Arash or Ikumi to take a
> quick sniff, then we can push and close.
I have only limited time to have look at your proposal, sorry. Here is
a very minor point I can say:
(defcustom TeX-fold-macro-spec-list
[...]
- :package-version '(auctex . "14.0.8"))
+ :package-version '(auctex . "14.0.9"))
The version number should be corrected since 14.1.0 is already released.
Regards,
Ikumi Keita
#StandWithUkraine #StopWarInUkraine
#Gaza #StopMassiveKilling #CeasefireNOW
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Wed, 03 Sep 2025 12:08:02 GMT)
Full text and
rfc822 format available.
Message #79 received at 78693 <at> debbugs.gnu.org (full text, mbox):
Gentle ping, I hope the patch can be merged soon.
Rahguzar
"Paul D. Nelson" <ultrono <at> gmail.com> writes:
> Rahguzar <rahguzar <at> mailbox.org> writes:
>
>> Hi Paul,
>>
>> "Paul D. Nelson" <ultrono <at> gmail.com> writes:
>>
>>> I can't think of any other edge cases. I think this patch is now ready
>>> to ship, although I'd welcome any feedback.
>>
>> I also think that it is ready to ship. Thanks for all your work on this.
>
> Thanks Raghuzar. Attaching an updated patch rebased to master. Since
> it's a non-local change, I figure I'll wait for Arash or Ikumi to take a
> quick sniff, then we can push and close.
>
> Paul
>
> [2. text/x-patch; 0001-Add-signature-support-for-macro-folding.patch]...
Information forwarded
to
bug-auctex <at> gnu.org
:
bug#78693
; Package
auctex
.
(Thu, 18 Sep 2025 08:04:02 GMT)
Full text and
rfc822 format available.
Message #82 received at 78693 <at> debbugs.gnu.org (full text, mbox):
Hi Paul,
"Paul D. Nelson" <ultrono <at> gmail.com> writes:
> Thanks Raghuzar. Attaching an updated patch rebased to master. Since
> it's a non-local change, I figure I'll wait for Arash or Ikumi to take a
> quick sniff, then we can push and close.
Thanks for this and sorry for my late response. I have some minor
comments (see below). I trust your patch works.
> diff --git a/doc/auctex.texi b/doc/auctex.texi
> index d0d2e41c..eb692f70 100644
> --- a/doc/auctex.texi
> +++ b/doc/auctex.texi
> @@ -2931,6 +2931,23 @@ as a replacement for the macro. Such functions typically return a string,
> but may also return the symbol @code{abort} to indicate that the macro
> should not be folded.
>
> +Each specifier may instead be a cons cell @code{(@var{spec} . @var{sig})},
> +where @var{spec} is as above and @var{sig} controls how many arguments are
> +considered part of the macro to fold:
> +@itemize @bullet
> +@item
> +@code{nil}: no limit (default).
> +@item
> +Integer @var{n}: stop after @var{n} total arguments.
> +@item
> +Cons @code{(@var{p} . @var{q})}: stop after @var{p} optional and
> +@var{q} required arguments.
I think the LaTeX parlance is "mandatory argument".
> +@item
> +Predicate function: called repeatedly with the list of argument blocks
> +encountered thus far. Returns non-@code{nil} to terminate scanning early.
> +See the doc string of @code{TeX-find-macro-boundaries} for details.
> +@end itemize
> [...]
> +
> (defcustom TeX-fold-macro-spec-list
> - '(("[f]" ("footnote" "marginpar"))
> - (TeX-fold-cite-display ("cite" "Cite"))
> - (TeX-fold-textcite-display ("textcite" "Textcite"))
> - (TeX-fold-parencite-display ("parencite" "Parencite"))
> - (TeX-fold-footcite-display ("footcite" "footcitetext"))
> - ("[l]" ("label"))
> - ("[r]" ("ref" "pageref" "eqref" "footref"))
> - ("[i]" ("index" "glossary"))
> - ("[1]:||*" ("item"))
> - ("..." ("dots"))
> - ("(C)" ("copyright"))
> - ("(R)" ("textregistered"))
> - ("TM" ("texttrademark"))
> - (TeX-fold-alert-display ("alert"))
> - (TeX-fold-textcolor-display ("textcolor"))
> + '((("[f]" . (1 . 1)) ("footnote" "marginpar"))
> + ((TeX-fold-cite-display . (2 . 1)) ("cite" "Cite"))
> + ((TeX-fold-textcite-display . (2 . 1)) ("textcite" "Textcite"))
> + ((TeX-fold-parencite-display . (2 . 1)) ("parencite" "Parencite"))
> + ((TeX-fold-footcite-display . (2 . 1)) ("footcite" "footcitetext"))
> + (("[l]" . TeX-fold-stop-after-first-required) ("label"))
> + (("[r]" . 1) ("ref" "pageref" "eqref" "footref"))
> + (("[i]" . (1 . 1)) ("index" "glossary"))
> + (("[1]:||*" . (1 . 0)) ("item"))
> + (("..." . 0) ("dots"))
> + (("(C)" . 0) ("copyright"))
> + (("(R)" . 0) ("textregistered"))
> + (("TM" . 0) ("texttrademark"))
> + ((TeX-fold-alert-display . 1) ("alert"))
> + ((TeX-fold-textcolor-display . (1 . 2)) ("textcolor"))
> (TeX-fold-begin-display ("begin"))
> - (TeX-fold-end-display ("end"))
> + ((TeX-fold-end-display . 1) ("end"))
> (1 ("part" "chapter" "section" "subsection" "subsubsection"
> "paragraph" "subparagraph"
> "part*" "chapter*" "section*" "subsection*" "subsubsection*"
> - "paragraph*" "subparagraph*"
> - "emph" "textit" "textsl" "textmd" "textrm" "textsf" "texttt"
> - "textbf" "textsc" "textup")))
> + "paragraph*" "subparagraph*"))
> + ((1 . (0 . 1)) ("emph" "textit" "textsl" "textmd" "textrm" "textsf" "texttt"
> + "textbf" "textsc" "textup")))
> "List of replacement specifiers and macros to fold.
>
> -The first element of each item can be a string, an integer or a
> -function symbol. The second element is a list of macros to fold
> -without the leading backslash.
> -
> -If the first element is a string, it will be used as a display
> -replacement for the whole macro. Numbers in braces, brackets,
> -parens or angle brackets will be replaced by the respective macro
> -argument. For example \"{1}\" will be replaced by the first
> -mandatory argument of the macro. One can also define
> -alternatives within the specifier which are used if an argument
> -is not found. Alternatives are separated by \"||\". They are
> -most useful with optional arguments. As an example, the default
> -specifier for \\item is \"[1]:||*\" which means that if there is
> -an optional argument, its value is shown followed by a colon. If
> -there is no optional argument, only an asterisk is used as the
> -display string.
> -
> -If the first element is an integer, the macro will be replaced by
> -the respective macro argument.
> -
> -If the first element is a function symbol, the function will be
> -called with all mandatory arguments of the macro and the result
> -of the function call will be used as a replacement for the macro.
> -Such functions typically return a string, but may also return the
> -symbol `abort' to indicate that the macro should not be folded.
> -
> -Setting this variable does not take effect immediately. Use
> -Customize or reset the mode."
> - :type '(repeat (group (choice (string :tag "Display String")
> - (integer :tag "Number of argument" :value 1)
> - (function :tag "Function to execute"))
> +The first element is of the form SPEC or (SPEC . SIG), where SPEC can be
> +a string, an integer or a function symbol and SIG is described below.
> +The second element is a list of macros to fold without the leading
> +backslash.
> +
> +If SPEC is a string, it will be used as a display replacement for the
> +whole macro. Numbers in braces, brackets, parens or angle brackets will
> +be replaced by the respective macro argument. For example \"{1}\" will
> +be replaced by the first mandatory argument of the macro. One can also
> +define alternatives within the specifier which are used if an argument
> +is not found. Alternatives are separated by \"||\". They are most
> +useful with optional arguments. As an example, the default specifier
> +for \\item is \"[1]:||*\" which means that if there is an optional
> +argument, its value is shown followed by a colon. If there is no
> +optional argument, only an asterisk is used as the display string.
> +
> +If SPEC is an integer, the macro will be replaced by the respective
> +macro argument.
> +
> +If SPEC is a function symbol, the function will be called with all
> +mandatory arguments of the macro and the result of the function call
> +will be used as a replacement for the macro. Such functions typically
> +return a string, but may also return the symbol `abort' to indicate that
> +the macro should not be folded.
> +
> +SIG optionally restricts how many macro arguments are consumed. It
> +should be of the form required by the SIGNATURE argument of
> +`TeX-find-macro-boundaries'. For example, if SIGNATURE is an integer n,
> +then at most n total arguments are consumed, while if it is a cons
> +cell (p . q), then at most p optional and q required arguments are
^^^^^^^^
mandatory
> +allowed.
> +
> +Setting this variable does not take effect immediately. Use Customize
> +or reset the mode."
> + :type `(repeat (group ,TeX-fold--spec-type
> (repeat :tag "Macros" (string))))
> - :package-version '(auctex . "14.0.8"))
> + :package-version '(auctex . "14.0.9"))
:package-version '(auctex . "14.1.1"))
> [...]
> diff --git a/tex.el b/tex.el
> index 18438a81..cbd0bef1 100644
> --- a/tex.el
> +++ b/tex.el
> @@ -5790,11 +5790,23 @@ If LIMIT is non-nil, do not search further up than this position
> in the buffer."
> (TeX-find-balanced-brace -1 depth limit))
>
> -(defun TeX-find-macro-boundaries (&optional lower-bound)
> +(defun TeX-find-macro-boundaries (&optional lower-bound signature)
> "Return a cons containing the start and end of a macro.
> If LOWER-BOUND is given, do not search backward further than this
> point in buffer. Arguments enclosed in brackets or braces are
> -considered part of the macro."
> +considered part of the macro.
> +
> +If SIGNATURE is given, restrict the total number of arguments. If
> +SIGNATURE is an integer N, allow at most N total arguments. If
> +SIGNATURE is a cons cell (P . Q), allow at most P optional and Q
> +required arguments.
mandatory
HTH. Best, Arash
This bug report was last modified 1 day ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.