diff options
| author | Eike Ziller <git@eikeziller.de> | 2017-04-29 16:17:11 +0200 |
|---|---|---|
| committer | Eike Ziller <git@eikeziller.de> | 2017-10-01 20:11:08 +0200 |
| commit | 5798e33d742c0f413d2d865fdb75739b4374ce98 (patch) | |
| tree | e7d36edf5de22ab74ed4b56e2e2b22be24f50ef6 /plugins/haskell/haskellhighlighter.cpp | |
| parent | 2f69373309cfe88084c5777baeff6bb46eecd071 (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.cpp | 152 |
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 |
