commit c8189f2a1323577ffa8eac805d81347f4cb861c2
Author: Juergen Spitzmueller <[email protected]>
Date:   Fri Jun 5 10:51:10 2026 +0200

    Improve performance of macro validation (#13321)
    
    The creation of a dedicated set is not needed here and costly.
    
    Co-production with Guillaume.
    
    (cherry picked from commit 7d295d29e50fdabe21f7a84936523489205353de)
---
 src/Buffer.cpp                | 32 ++++++++++++++++++++++++++++++++
 src/Buffer.h                  |  2 ++
 src/mathed/InsetMathMacro.cpp | 10 ++++------
 3 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index 18a0279e2d..11d3f59121 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -85,6 +85,7 @@
 #include "frontends/WorkAreaManager.h"
 
 #include "support/lassert.h"
+#include "support/Changer.h"
 #include "support/convert.h"
 #include "support/debug.h"
 #include "support/docstring_list.h"
@@ -4112,6 +4113,37 @@ void Buffer::listMacroNames(MacroNameSet & macros) const
 }
 
 
+bool Buffer::hasMacroName(docstring const & name) const
+{
+       // mark this buffer as already visited to avoid recursive loop
+       if (d->macro_lock)
+               return false;
+
+       // temporal macro lock that will be set false
+       // upon return
+       Changer dummy = changeVar(d->macro_lock, true);
+
+       // loop over macro names
+       if (d->macros.find(name) != d->macros.end())
+               return true;
+
+       // loop over children
+       for (auto const & p : d->children_positions) {
+               Buffer * child = const_cast<Buffer *>(p.first);
+               // The buffer might have been closed (see #10766).
+               if (theBufferList().isLoaded(child) && 
child->hasMacroName(name))
+                       return true;
+       }
+
+       // call parent
+       Buffer const * const pbuf = d->parent();
+       if (pbuf)
+               return pbuf->hasMacroName(name);
+
+       return false;
+}
+
+
 void Buffer::listParentMacros(MacroSet & macros, LaTeXFeatures & features) 
const
 {
        Buffer const * const pbuf = d->parent();
diff --git a/src/Buffer.h b/src/Buffer.h
index c8dffc3cfc..897e673421 100644
--- a/src/Buffer.h
+++ b/src/Buffer.h
@@ -618,6 +618,8 @@ public:
 
        /// List macro names of this buffer, the parent and the children
        void listMacroNames(MacroNameSet & macros) const;
+       /// Check whether this buffer, its parent or a child, has a specific 
macro
+       bool hasMacroName(docstring const & name) const;
        /// Collect macros of the parent and its children in front of this 
buffer.
        void listParentMacros(MacroSet & macros, LaTeXFeatures & features) 
const;
 
diff --git a/src/mathed/InsetMathMacro.cpp b/src/mathed/InsetMathMacro.cpp
index ece9bfd39d..43ddb3b084 100644
--- a/src/mathed/InsetMathMacro.cpp
+++ b/src/mathed/InsetMathMacro.cpp
@@ -983,13 +983,11 @@ void InsetMathMacro::validate(LaTeXFeatures & features) 
const
        // in this case the definition is only used for screen display.
        MathWordList const & words = mathedWordList();
        MathWordList::const_iterator it = words.find(name());
-       MacroNameSet macros;
-       buffer().listMacroNames(macros);
        if (it == words.end() || it->second.inset != "macro"
-           || macros.find(name()) != macros.end()) {
-               if (displayMode() == DISPLAY_NORMAL) {
-                               d->definition_.validate(features);
-               } else if (displayMode() == DISPLAY_INIT) {
+           || buffer().hasMacroName(name())) {
+               if (displayMode() == DISPLAY_NORMAL)
+                       d->definition_.validate(features);
+               else if (displayMode() == DISPLAY_INIT) {
                        if (MacroData const * data = buffer().getMacro(name())) 
{
                                MathData md(const_cast<Buffer *>(&buffer()));
                                asMathData(data->definition(), md);
-- 
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to