aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/haskell/haskellhighlighter.cpp
diff options
context:
space:
mode:
authorEike Ziller <git@eikeziller.de>2017-04-29 16:17:11 +0200
committerEike Ziller <git@eikeziller.de>2017-10-01 20:11:08 +0200
commit5798e33d742c0f413d2d865fdb75739b4374ce98 (patch)
treee7d36edf5de22ab74ed4b56e2e2b22be24f50ef6 /plugins/haskell/haskellhighlighter.cpp
parent2f69373309cfe88084c5777baeff6bb46eecd071 (diff)
Add highlighter
See lexical structure of Haskell https://www.haskell.org/onlinereport/haskell2010/haskellch2.html
Diffstat (limited to 'plugins/haskell/haskellhighlighter.cpp')
-rw-r--r--plugins/haskell/haskellhighlighter.cpp152
1 files changed, 152 insertions, 0 deletions
diff --git a/plugins/haskell/haskellhighlighter.cpp b/plugins/haskell/haskellhighlighter.cpp
new file mode 100644
index 0000000..9899cc4
--- /dev/null
+++ b/plugins/haskell/haskellhighlighter.cpp
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "haskellhighlighter.h"
+
+#include "haskelltokenizer.h"
+
+#include <texteditor/fontsettings.h>
+#include <texteditor/texteditorconstants.h>
+#include <texteditor/texteditorsettings.h>
+
+#include <QDebug>
+#include <QVector>
+
+Q_GLOBAL_STATIC_WITH_ARGS(QSet<QString>, IMPORT_HIGHLIGHTS, ({
+ "qualified",
+ "as",
+ "hiding"
+}));
+
+using namespace TextEditor;
+
+namespace Haskell {
+namespace Internal {
+
+HaskellHighlighter::HaskellHighlighter()
+{
+ setDefaultTextFormatCategories();
+ updateFormats(TextEditorSettings::fontSettings());
+}
+
+void HaskellHighlighter::highlightBlock(const QString &text)
+{
+ const Tokens tokens = HaskellTokenizer::tokenize(text, previousBlockState());
+ setCurrentBlockState(tokens.state);
+ const Token *firstNonWS = 0;
+ const Token *secondNonWS = 0;
+ bool inType = false;
+ bool inImport = false;
+ for (const Token & token : tokens) {
+ switch (token.type) {
+ case TokenType::Variable:
+ if (inType)
+ setTokenFormat(token, C_LOCAL);
+ else if (inImport && IMPORT_HIGHLIGHTS->contains(token.text.toString()))
+ setTokenFormat(token, C_KEYWORD);
+// else
+// setTokenFormat(token, C_TEXT);
+ break;
+ case TokenType::Constructor:
+ case TokenType::OperatorConstructor:
+ setTokenFormat(token, C_TYPE);
+ break;
+ case TokenType::Operator:
+ setTokenFormat(token, C_OPERATOR);
+ break;
+ case TokenType::Whitespace:
+ setTokenFormat(token, C_VISUAL_WHITESPACE);
+ break;
+ case TokenType::Keyword:
+ if (token.text == "::" && firstNonWS && !secondNonWS) { // toplevel declaration
+ setFormat(firstNonWS->startCol, firstNonWS->length, m_toplevelDeclFormat);
+ inType = true;
+ } else if (token.text == "import") {
+ inImport = true;
+ }
+ setTokenFormat(token, C_KEYWORD);
+ break;
+ case TokenType::Integer:
+ case TokenType::Float:
+ setTokenFormat(token, C_NUMBER);
+ break;
+ case TokenType::String:
+ setTokenFormatWithSpaces(text, token, C_STRING);
+ break;
+ case TokenType::Char:
+ setTokenFormatWithSpaces(text, token, C_STRING);
+ break;
+ case TokenType::EscapeSequence:
+ setTokenFormat(token, C_PRIMITIVE_TYPE);
+ break;
+ case TokenType::SingleLineComment:
+ setTokenFormatWithSpaces(text, token, C_COMMENT);
+ break;
+ case TokenType::MultiLineComment:
+ setTokenFormatWithSpaces(text, token, C_COMMENT);
+ break;
+ case TokenType::Special:
+// setTokenFormat(token, C_TEXT);
+ break;
+ case TokenType::StringError:
+ case TokenType::CharError:
+ case TokenType::Unknown:
+ setTokenFormat(token, C_PARENTHESES_MISMATCH);
+ break;
+ }
+ if (token.type != TokenType::Whitespace) {
+ if (!firstNonWS)
+ firstNonWS = &token;
+ else if (!secondNonWS)
+ secondNonWS = &token;
+ }
+ }
+}
+
+void HaskellHighlighter::setFontSettings(const FontSettings &fontSettings)
+{
+ SyntaxHighlighter::setFontSettings(fontSettings);
+ updateFormats(fontSettings);
+}
+
+void HaskellHighlighter::updateFormats(const FontSettings &fontSettings)
+{
+ m_toplevelDeclFormat = fontSettings.toTextCharFormat(
+ TextStyles::mixinStyle(C_FUNCTION, C_DECLARATION));
+}
+
+void HaskellHighlighter::setTokenFormat(const Token &token, TextStyle style)
+{
+ setFormat(token.startCol, token.length, formatForCategory(style));
+}
+
+void HaskellHighlighter::setTokenFormatWithSpaces(const QString &text, const Token &token,
+ TextStyle style)
+{
+ setFormatWithSpaces(text, token.startCol, token.length, formatForCategory(style));
+}
+
+} // Internal
+} // Haskell