commit f185f6bfc9edb9468959b3793c0c15ed77b6e2db
Author: Jürgen Spitzmüller <sp...@lyx.org>
Date:   Thu Jan 16 10:00:20 2025 +0100

    Reimplement error-next (#2775)
---
 lib/RELEASE-NOTES            |  3 +++
 lib/bind/cua.bind            |  1 +
 lib/ui/stdmenus.inc          |  1 +
 src/FuncCode.h               |  1 +
 src/LyXAction.cpp            |  7 ++++++
 src/frontends/qt/GuiView.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++
 src/frontends/qt/GuiView.h   |  9 +++++++
 status.24x                   |  4 +++-
 8 files changed, 82 insertions(+), 1 deletion(-)

diff --git a/lib/RELEASE-NOTES b/lib/RELEASE-NOTES
index a7363e1a04..028e9ede58 100644
--- a/lib/RELEASE-NOTES
+++ b/lib/RELEASE-NOTES
@@ -95,6 +95,9 @@
   sgmltools has been removed, this new support is always enabled.
   Having sgmltools installed or not will not change anything in LyX.
 
+* The re-introduced function error-next moves the cursor to the next
+  LaTeX error in the current buffer.
+
 * Postscript -> PDF convertor (ps2pdf) uses -dALLOWPSTRANSPARENCY by
   default now (implemented since ghostscript 9.53.3, see bug #12303).
 
diff --git a/lib/bind/cua.bind b/lib/bind/cua.bind
index 9d3f386091..d40a42c573 100644
--- a/lib/bind/cua.bind
+++ b/lib/bind/cua.bind
@@ -129,6 +129,7 @@ Format 5
 \bind "S-F6"                   "tab-group-previous"
 \bind "C-F6"                   "buffer-next"
 \bind "C-S-F6"                 "buffer-previous"
+\bind "C-g"                    "error-next"
 \bind "F7"                     "dialog-show spellchecker"
 \bind "S-F7"                   "thesaurus-entry"
 
diff --git a/lib/ui/stdmenus.inc b/lib/ui/stdmenus.inc
index 229d351801..9e71be5f56 100644
--- a/lib/ui/stdmenus.inc
+++ b/lib/ui/stdmenus.inc
@@ -603,6 +603,7 @@ Menuset
 #
        Menu "navigate"
                Submenu "Bookmarks|B" "navigate_bookmarks"
+               Item "Next Error|E" "error-next"
                Item "Next Note|N" "note-next"
                Item "Next Change|C" "change-next"
                Item "Next Cross-Reference|R" "reference-next"
diff --git a/src/FuncCode.h b/src/FuncCode.h
index b8e2e0a0ac..c955f5d2c9 100644
--- a/src/FuncCode.h
+++ b/src/FuncCode.h
@@ -512,6 +512,7 @@ enum FuncCode
        LFUN_REFERENCE_INSERT,          // spitz, 20240728
        // 400
        LFUN_REFERENCE_TO_PARAGRAPH,    // spitz, 20240728
+       LFUN_ERROR_NEXT,                // spitz, 20200101,
        LFUN_LASTACTION                 // end of the table
 };
 
diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp
index d5462d5048..615625c963 100644
--- a/src/LyXAction.cpp
+++ b/src/LyXAction.cpp
@@ -1579,6 +1579,13 @@ void LyXAction::init()
  */
                { LFUN_ENVIRONMENT_SPLIT, "environment-split", Noop, Layout },
 
+/*!
+ * \var lyx::FuncCode lyx::LFUN_ERROR_NEXT
+ * \li Action: Moves the cursor to the beginning of next LaTeX error.
+ * \li Syntax: error-next
+ * \endvar
+ */
+               { LFUN_ERROR_NEXT, "error-next", ReadOnly, Edit },
 
 /*!
  * \var lyx::FuncCode lyx::LFUN_ERT_INSERT
diff --git a/src/frontends/qt/GuiView.cpp b/src/frontends/qt/GuiView.cpp
index c270a24190..9b13736b88 100644
--- a/src/frontends/qt/GuiView.cpp
+++ b/src/frontends/qt/GuiView.cpp
@@ -2188,6 +2188,41 @@ void GuiView::errors(string const & error_type, bool 
from_master)
 }
 
 
+int GuiView::nextError(string const & error_type, bool from_master,
+                      bool navigateto, bool atcursor)
+{
+       BufferView const * const bv = currentBufferView();
+       if (!bv)
+               return -1;
+
+       Buffer const & buf = from_master
+                       ? *(bv->buffer().masterBuffer())
+                       : bv->buffer();
+
+       ErrorList const & el = buf.errorList(error_type);
+
+       if (el.empty())
+               return -1;
+
+       int item = 0;
+       for (auto const & err : el) {
+               if (TexRow::isNone(err.start)
+                   || (atcursor && 
TexRow::getDocIteratorsFromEntries(err.start, err.end, buf).first < 
bv->cursor())
+                   || (!atcursor && 
TexRow::getDocIteratorsFromEntries(err.start, err.end, buf).first <= 
bv->cursor())) {
+                       ++item;
+                       continue;
+               }
+               if (navigateto) {
+                       DispatchResult dr;
+                       dispatch(TexRow::goToFunc(err.start, err.end), dr);
+               }
+               return item;
+       }
+
+       return -1;
+}
+
+
 void GuiView::updateTocItem(string const & type, DocIterator const & dit)
 {
        d.toc_models_.updateItem(toqstr(type), dit);
@@ -2669,6 +2704,18 @@ bool GuiView::getStatus(FuncRequest const & cmd, 
FuncStatus & flag)
                break;
        }
 
+       case LFUN_ERROR_NEXT: {
+               if (!buf || (buf->errorList(d.last_export_format).empty()
+                            && 
buf->masterBuffer()->errorList(d.last_export_format).empty())) {
+                       enable = false;
+                       break;
+               }
+               // We guess it's from master if the single buffer list is empty
+               bool const from_master = 
currentBufferView()->buffer().errorList(d.last_export_format).empty();
+               enable = nextError(d.last_export_format, from_master) != -1;
+               break;
+       }
+
        case LFUN_COMMAND_EXECUTE:
        case LFUN_MESSAGE:
        case LFUN_MENU_OPEN:
@@ -4913,6 +4960,16 @@ void GuiView::dispatch(FuncRequest const & cmd, 
DispatchResult & dr)
                        break;
                }
 
+               case LFUN_ERROR_NEXT: {
+                       // We guess it's from master if the single buffer list 
is empty
+                       bool const from_master = 
bv->buffer().errorList(d.last_export_format).empty();
+                       if (nextError(d.last_export_format, from_master, true) 
!= -1) {
+                               dr.forceBufferUpdate();
+                               dr.screenUpdate(Update::Force);
+                       }
+                       break;
+               }
+
                case LFUN_MESSAGE:
                        dr.setMessage(cmd.argument());
                        break;
diff --git a/src/frontends/qt/GuiView.h b/src/frontends/qt/GuiView.h
index b7726e0230..e00b21a681 100644
--- a/src/frontends/qt/GuiView.h
+++ b/src/frontends/qt/GuiView.h
@@ -179,6 +179,15 @@ public:
        void updateTocItem(std::string const &, DocIterator const &) override;
        //@}
 
+       /** Find the next error from current cursor position.
+        *  \return the error item position in the error list
+        *  with \param navigateto the cursor moves to the error
+        *  with \param atcursor the error at current cursor position
+        *  is considered as well, otherwise only those who follow.
+        */
+       int nextError(std::string const & error_type, bool from_master = false,
+                     bool navigateto = false, bool atcursor = false);
+
        ///
        TocModels & tocModels();
 
diff --git a/status.24x b/status.24x
index e8b34ea3a4..86742b7a92 100644
--- a/status.24x
+++ b/status.24x
@@ -27,7 +27,9 @@ What's new
 
 * USER INTERFACE
 
-
+- LyX now (again) has a function (error-next) and a menu entry (Navigate→Next 
Error)
+  to quickly jump to the next compilation error. This re-introduces a feature 
we
+  lost 20 years ago with LyX 1.4 (bug 2775)!
 
 
 * DOCUMENTATION AND LOCALIZATION
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
https://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to