[frameworks/ktexteditor] src/vimode: vi-mode: Fix checks for setting user marks

Christoph Cullmann <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit d8f41b7b4fc9d227a8c23d9df605251a1178fe3e by Christoph Cullmann, on behalf of Ismael Asensio.
Committed on 15/08/2026 at 15:32.
Pushed by cullmann into branch 'master'.

vi-mode: Fix checks for setting user marks

When setting a user mark ("m"), there was no check for a valid character
(a-z), so it would trigger the assertion in the setter. When using the
command bar (":mark") there was a check, but it still allowed several
non-valid mark characters ("_", "+", "*").

Add a small public checker method and simplify the logic to fix this

BUG: 520734
FIXED-IN: 6.30

M  +1    -1    src/vimode/cmds.cpp
M  +6    -11   src/vimode/marks.cpp
M  +2    -1    src/vimode/marks.h
M  +5    -3    src/vimode/modes/normalvimode.cpp

https://invent.kde.org/frameworks/ktexteditor/-/commit/d8f41b7b4fc9d227a8c23d9df605251a1178fe3e

diff --git a/src/vimode/cmds.cpp b/src/vimode/cmds.cpp
index dc53c7585..436c7e876 100644
--- a/src/vimode/cmds.cpp
+++ b/src/vimode/cmds.cpp
@@ -148,7 +148,7 @@ bool Commands::exec(KTextEditor::View *view, const QString &_cmd, QString &msg,
         } else if (args.count() == 1) {
             QChar r = args.at(0).at(0);
             int line;
-            if ((r >= QLatin1Char('a') && r <= QLatin1Char('z')) || r == QLatin1Char('_') || r == QLatin1Char('+') || r == QLatin1Char('*')) {
+            if (Marks::isUserMark(r)) {
                 if (range.isValid()) {
                     line = qMax(range.end().line(), range.start().line());
                 } else {
diff --git a/src/vimode/marks.cpp b/src/vimode/marks.cpp
index a530f5080..06d77eab9 100644
--- a/src/vimode/marks.cpp
+++ b/src/vimode/marks.cpp
@@ -24,14 +24,9 @@ const QChar LastChange = QLatin1Char('.');
 const QChar InsertStopped = QLatin1Char('^');
 const QChar SelectionBegin = QLatin1Char('<');
 const QChar SelectionEnd = QLatin1Char('>');
-const QChar FirstUserMark = QLatin1Char('a');
-const QChar LastUserMark = QLatin1Char('z');
 const QChar BeforeJump = QLatin1Char('\'');
 const QChar BeforeJumpAlter = QLatin1Char('`');
-const QChar UserMarks[] = {QLatin1Char('a'), QLatin1Char('b'), QLatin1Char('c'), QLatin1Char('d'), QLatin1Char('e'), QLatin1Char('f'), QLatin1Char('g'),
-                           QLatin1Char('h'), QLatin1Char('i'), QLatin1Char('j'), QLatin1Char('k'), QLatin1Char('l'), QLatin1Char('m'), QLatin1Char('n'),
-                           QLatin1Char('o'), QLatin1Char('p'), QLatin1Char('q'), QLatin1Char('r'), QLatin1Char('s'), QLatin1Char('t'), QLatin1Char('u'),
-                           QLatin1Char('v'), QLatin1Char('w'), QLatin1Char('x'), QLatin1Char('y'), QLatin1Char('z')};
+const QString UserMarks = QStringLiteral("abcdefghijklmnopqrstuvwxyz");
 }
 
 Marks::Marks(InputModeManager *imm)
@@ -106,7 +101,7 @@ void Marks::setMark(const QChar &_mark, const KTextEditor::Cursor pos)
     }
 
     // Showing what mark we set, can be skipped if we did not change the line
-    if (isShowable(mark)) {
+    if (isUserMark(mark)) {
         if (needToAdjustVisibleMark && !(m_doc->mark(pos.line()) & KTextEditor::Document::markType01)) {
             m_doc->addMark(pos.line(), KTextEditor::Document::markType01);
         }
@@ -200,7 +195,7 @@ void Marks::syncViMarksAndBookmarks()
     auto ks = std::views::keys(m_marks);
     const std::vector<QChar> keys{ks.begin(), ks.end()};
     for (QChar markChar : keys) {
-        if (!isShowable(markChar)) {
+        if (!isUserMark(markChar)) {
             continue;
         }
 
@@ -239,9 +234,9 @@ QString Marks::getMarksOnTheLine(int line) const
     return res;
 }
 
-bool Marks::isShowable(const QChar &mark)
+bool Marks::isUserMark(const QChar &mark)
 {
-    return FirstUserMark <= mark && mark <= LastUserMark;
+    return charInList(mark, UserMarks);
 }
 
 void Marks::setStartEditYanked(const KTextEditor::Cursor pos)
@@ -276,7 +271,7 @@ void Marks::setSelectionFinish(const KTextEditor::Cursor pos)
 
 void Marks::setUserMark(const QChar &mark, const KTextEditor::Cursor pos)
 {
-    Q_ASSERT(FirstUserMark <= mark && mark <= LastUserMark);
+    Q_ASSERT(charInList(mark, UserMarks));
     setMark(mark, pos);
 }
 
diff --git a/src/vimode/marks.h b/src/vimode/marks.h
index ce2d6a8e4..9a6e1e2bf 100644
--- a/src/vimode/marks.h
+++ b/src/vimode/marks.h
@@ -50,9 +50,10 @@ public:
 
     QString getMarksOnTheLine(int line) const;
 
+    static bool isUserMark(const QChar &mark);
+
 private:
     void syncViMarksAndBookmarks();
-    static bool isShowable(const QChar &mark);
 
     void setMark(const QChar &mark, const KTextEditor::Cursor pos);
 
diff --git a/src/vimode/modes/normalvimode.cpp b/src/vimode/modes/normalvimode.cpp
index 6e8f4c0f0..f54488653 100644
--- a/src/vimode/modes/normalvimode.cpp
+++ b/src/vimode/modes/normalvimode.cpp
@@ -1485,9 +1485,11 @@ bool NormalViMode::commandSetMark()
     KTextEditor::Cursor c(m_view->cursorPosition());
 
     QChar mark = m_keys.at(m_keys.size() - 1);
-    m_viInputModeManager->marks()->setUserMark(mark, c);
-
-    return true;
+    if (Marks::isUserMark(mark)) {
+        m_viInputModeManager->marks()->setUserMark(mark, c);
+        return true;
+    }
+    return false;
 }
 
 bool NormalViMode::commandIndentLine()
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.