From 5901b98c68fed292fa68cf4a15efd3220b9dcc7e Mon Sep 17 00:00:00 2001 From: mgrojo Date: Fri, 10 Apr 2026 22:44:19 +0200 Subject: [PATCH] Add Ada syntax highlighting --- src/CMakeLists.txt | 2 + src/SeerAdaSourceHighlighter.cpp | 90 ++++++++++++++++++++++++++++++++ src/SeerAdaSourceHighlighter.h | 18 +++++++ src/SeerHighlighterSettings.cpp | 13 +++++ src/SeerHighlighterSettings.h | 3 ++ src/SeerSourceHighlighter.cpp | 6 +++ 6 files changed, 132 insertions(+) create mode 100644 src/SeerAdaSourceHighlighter.cpp create mode 100644 src/SeerAdaSourceHighlighter.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fc933cf..f0bc063 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -147,6 +147,7 @@ set(HEADER_FILES SeerWatchpointCreateDialog.h SeerWatchpointsBrowserWidget.h SeerSourceHighlighter.h + SeerAdaSourceHighlighter.h SeerCppSourceHighlighter.h SeerOdinSourceHighlighter.h SeerRustSourceHighlighter.h @@ -259,6 +260,7 @@ set(SOURCE_FILES SeerWatchpointCreateDialog.cpp SeerWatchpointsBrowserWidget.cpp SeerSourceHighlighter.cpp + SeerAdaSourceHighlighter.cpp SeerCppSourceHighlighter.cpp SeerOdinSourceHighlighter.cpp SeerRustSourceHighlighter.cpp diff --git a/src/SeerAdaSourceHighlighter.cpp b/src/SeerAdaSourceHighlighter.cpp new file mode 100644 index 0000000..209da74 --- /dev/null +++ b/src/SeerAdaSourceHighlighter.cpp @@ -0,0 +1,90 @@ +// SPDX-FileCopyrightText: 2024 Ernie Pasveer +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "SeerAdaSourceHighlighter.h" + +SeerAdaSourceHighlighter::SeerAdaSourceHighlighter(QTextDocument *parent) : SeerSourceHighlighter(parent) { + + // Set to default formats. + setHighlighterSettings(SeerHighlighterSettings::populate("")); +} + +void SeerAdaSourceHighlighter::setHighlighterSettings(const SeerHighlighterSettings &settings) { + + _highlighterSettings = settings; + + _classFormat = _highlighterSettings.get("Class"); + _quotationFormat = _highlighterSettings.get("Quotation"); + _functionFormat = _highlighterSettings.get("Function"); + _singleLineCommentFormat = _highlighterSettings.get("Comment"); + _multiLineCommentFormat = _highlighterSettings.get("Multiline Comment"); + _keywordFormat = _highlighterSettings.get("Keyword"); + + const QString keywordPatterns[] = { + QStringLiteral("\\babort\\b"), QStringLiteral("\\babs\\b"), QStringLiteral("\\babstract\\b"), + QStringLiteral("\\baccept\\b"), QStringLiteral("\\baccess\\b"), QStringLiteral("\\baliased\\b"), + QStringLiteral("\\ball\\b"), QStringLiteral("\\band\\b"), QStringLiteral("\\barray\\b"), + QStringLiteral("\\bat\\b"), QStringLiteral("\\bbegin\\b"), QStringLiteral("\\bbody\\b"), + QStringLiteral("\\bcase\\b"), QStringLiteral("\\bconstant\\b"), QStringLiteral("\\bdeclare\\b"), + QStringLiteral("\\bdelay\\b"), QStringLiteral("\\bdelta\\b"), QStringLiteral("\\bdigits\\b"), + QStringLiteral("\\bdo\\b"), QStringLiteral("\\belse\\b"), QStringLiteral("\\belsif\\b"), + QStringLiteral("\\bend\\b"), QStringLiteral("\\bentry\\b"), QStringLiteral("\\bexception\\b"), + QStringLiteral("\\bexit\\b"), QStringLiteral("\\bfor\\b"), QStringLiteral("\\bfunction\\b"), + QStringLiteral("\\bgeneric\\b"), QStringLiteral("\\bgoto\\b"), QStringLiteral("\\bif\\b"), + QStringLiteral("\\bin\\b"), QStringLiteral("\\binterface\\b"), QStringLiteral("\\bis\\b"), + QStringLiteral("\\blimited\\b"), QStringLiteral("\\bloop\\b"), QStringLiteral("\\bmod\\b"), + QStringLiteral("\\bnew\\b"), QStringLiteral("\\bnot\\b"), QStringLiteral("\\bnull\\b"), + QStringLiteral("\\bof\\b"), QStringLiteral("\\bor\\b"), QStringLiteral("\\bothers\\b"), + QStringLiteral("\\bout\\b"), QStringLiteral("\\boverriding\\b"), QStringLiteral("\\bpackage\\b"), + QStringLiteral("\\bpragma\\b"), QStringLiteral("\\bprivate\\b"), QStringLiteral("\\bprocedure\\b"), + QStringLiteral("\\bprotected\\b"), QStringLiteral("\\braise\\b"), QStringLiteral("\\brange\\b"), + QStringLiteral("\\brecord\\b"), QStringLiteral("\\brem\\b"), QStringLiteral("\\brenames\\b"), + QStringLiteral("\\brequeue\\b"), QStringLiteral("\\breturn\\b"), QStringLiteral("\\breverse\\b"), + QStringLiteral("\\bselect\\b"), QStringLiteral("\\bseparate\\b"), QStringLiteral("\\bsome\\b"), + QStringLiteral("\\bsubtype\\b"), QStringLiteral("\\bsynchronized\\b"),QStringLiteral("\\btagged\\b"), + QStringLiteral("\\btask\\b"), QStringLiteral("\\bterminate\\b"), QStringLiteral("\\bthen\\b"), + QStringLiteral("\\btype\\b"), QStringLiteral("\\buntil\\b"), QStringLiteral("\\buse\\b"), + QStringLiteral("\\bwhen\\b"), QStringLiteral("\\bwhile\\b"), QStringLiteral("\\bwith\\b"), + QStringLiteral("\\bxor\\b"), + }; + + _highlightingRules.clear(); // Clear old rules. + + HighlightingRule rule; + + // Set class format and expression. + // (Ada typically doesn't have a distinguished class case convention, but we can reuse uppercase Start) + rule.pattern = QRegularExpression(QStringLiteral("\\b[A-Z][A-z0-9_]*\\b")); + rule.format = _classFormat; + _highlightingRules.append(rule); + + // Set function format and expression. + // This won't highlight parameterless subprograms, but it's still useful for most cases. + rule.pattern = QRegularExpression(QStringLiteral("\\b[A-Za-z0-9_!]+(?=\\s*\\()")); + rule.format = _functionFormat; + _highlightingRules.append(rule); + + // Set keywords format and expression (must have precedence over functions) + // Ada is case insensitive, so we use case insensitive option. + for (const QString &pattern : keywordPatterns) { + rule.pattern = QRegularExpression(pattern, QRegularExpression::CaseInsensitiveOption); + rule.format = _keywordFormat; + _highlightingRules.append(rule); + } + + // Set quote format and expression. + rule.pattern = QRegularExpression(QStringLiteral("\".*\"")); + rule.format = _quotationFormat; + _highlightingRules.append(rule); + + // Set single line comment format and expression. (Ada uses --) + rule.pattern = QRegularExpression(QStringLiteral("--[^\n]*")); + rule.format = _singleLineCommentFormat; + _highlightingRules.append(rule); + + // Multi-line comments are not possible in Ada. + // Using a regex that matches nothing to avoid any unintended highlighting. + _commentStartExpression = QRegularExpression(QStringLiteral("(?!)")); + _commentEndExpression = QRegularExpression(QStringLiteral("(?!)")); +} diff --git a/src/SeerAdaSourceHighlighter.h b/src/SeerAdaSourceHighlighter.h new file mode 100644 index 0000000..5f7c9ec --- /dev/null +++ b/src/SeerAdaSourceHighlighter.h @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2024 Ernie Pasveer +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "SeerHighlighterSettings.h" +#include "SeerSourceHighlighter.h" + +class SeerAdaSourceHighlighter : public SeerSourceHighlighter { + + Q_OBJECT + + public: + SeerAdaSourceHighlighter(QTextDocument *parent = 0); + + virtual void setHighlighterSettings (const SeerHighlighterSettings &settings) override; +}; diff --git a/src/SeerHighlighterSettings.cpp b/src/SeerHighlighterSettings.cpp index 7f37517..da87033 100644 --- a/src/SeerHighlighterSettings.cpp +++ b/src/SeerHighlighterSettings.cpp @@ -19,6 +19,7 @@ SeerHighlighterSettings& SeerHighlighterSettings::operator= (const SeerHighlight _keys = rhs._keys; _formats = rhs._formats; + _adaSourceSuffixes = rhs._adaSourceSuffixes; _cppSourceSuffixes = rhs._cppSourceSuffixes; _rustSourceSuffixes = rhs._rustSourceSuffixes; _odinSourceSuffixes = rhs._odinSourceSuffixes; @@ -72,6 +73,11 @@ int SeerHighlighterSettings::count () const { return _keys.size(); } +void SeerHighlighterSettings::setAdaSourceSuffixes (const QString& suffixes) { + + _adaSourceSuffixes = suffixes; +} + void SeerHighlighterSettings::setCppSourceSuffixes (const QString& suffixes) { _cppSourceSuffixes = suffixes; @@ -102,6 +108,11 @@ const QString& SeerHighlighterSettings::rustSourceSuffixes () { return _rustSourceSuffixes; } +const QString& SeerHighlighterSettings::adaSourceSuffixes () { + + return _adaSourceSuffixes; +} + QStringList SeerHighlighterSettings::themeNames() { QStringList names; @@ -212,6 +223,7 @@ SeerHighlighterSettings SeerHighlighterSettings::populate_light () { f.setBackground(QColor("#ffffff")); languageSettings.add("Keyword", f); + languageSettings.setAdaSourceSuffixes(".ada|.adb|.ads"); languageSettings.setCppSourceSuffixes(".c|.C|.cpp|.CPP|.cxx|.CXX|.h|.H|.hpp|.hxx|.Hxx|.HXX"); languageSettings.setOdinSourceSuffixes(".odin"); languageSettings.setRustSourceSuffixes(".rs"); @@ -309,6 +321,7 @@ SeerHighlighterSettings SeerHighlighterSettings::populate_dark () { f.setBackground(QColor("#232629")); languageSettings.add("Keyword", f); + languageSettings.setAdaSourceSuffixes(".ada|.adb|.ads"); languageSettings.setCppSourceSuffixes(".c|.C|.cpp|.CPP|.cxx|.CXX|.h|.H|.hpp|.hxx|.Hxx|.HXX"); languageSettings.setOdinSourceSuffixes(".odin"); languageSettings.setRustSourceSuffixes(".rs"); diff --git a/src/SeerHighlighterSettings.h b/src/SeerHighlighterSettings.h index 9be12f1..8445341 100644 --- a/src/SeerHighlighterSettings.h +++ b/src/SeerHighlighterSettings.h @@ -23,9 +23,11 @@ class SeerHighlighterSettings { QTextCharFormat get (const QString& name) const; void add (const QString& name, QTextCharFormat& format); int count () const; + void setAdaSourceSuffixes (const QString& suffixes); void setCppSourceSuffixes (const QString& suffixes); void setOdinSourceSuffixes (const QString& suffixes); void setRustSourceSuffixes (const QString& suffixes); + const QString& adaSourceSuffixes (); const QString& cppSourceSuffixes (); const QString& odinSourceSuffixes (); const QString& rustSourceSuffixes (); @@ -38,6 +40,7 @@ class SeerHighlighterSettings { private: QList _keys; QList _formats; + QString _adaSourceSuffixes; QString _cppSourceSuffixes; QString _odinSourceSuffixes; QString _rustSourceSuffixes; diff --git a/src/SeerSourceHighlighter.cpp b/src/SeerSourceHighlighter.cpp index e3a8ec0..2c7c876 100644 --- a/src/SeerSourceHighlighter.cpp +++ b/src/SeerSourceHighlighter.cpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later #include "SeerSourceHighlighter.h" +#include "SeerAdaSourceHighlighter.h" #include "SeerOdinSourceHighlighter.h" #include "SeerCppSourceHighlighter.h" #include "SeerRustSourceHighlighter.h" @@ -15,6 +16,11 @@ const SeerHighlighterSettings& SeerSourceHighlighter::highlighterSettings() { SeerSourceHighlighter* SeerSourceHighlighter::getSourceHighlighter(QString const& file, SeerHighlighterSettings settings) { + QRegularExpression ada_re("(?:" + settings.adaSourceSuffixes() + ")$"); + if (file.contains(ada_re)) { + return new SeerAdaSourceHighlighter(0); + } + QRegularExpression cpp_re("(?:" + settings.cppSourceSuffixes() + ")$"); if (file.contains(cpp_re)) { return new SeerCppSourceHighlighter(0);