diff options
author | David Schulz <david.schulz@qt.io> | 2018-11-08 11:39:48 +0100 |
---|---|---|
committer | David Schulz <david.schulz@qt.io> | 2019-01-28 11:37:08 +0000 |
commit | 14834e6b0a4e7c1272ec3a1838b0634dd66e72ea (patch) | |
tree | 23caed8a748c0d38c59e1f92b448551122d11df2 | |
parent | 1c77d7e1a79f59485eb90c066d17ec7436f46a93 (diff) |
TextEditor: replace generic highlighter with ksyntaxhighlighting
Fixes: QTCREATORBUG-21029
Change-Id: I9894c4384e0e47da6bf030b7b8e07c3ad4737ff3
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
198 files changed, 16282 insertions, 9008 deletions
diff --git a/doc/src/overview/creator-acknowledgements.qdoc b/doc/src/overview/creator-acknowledgements.qdoc index 82ab47280e..e12926398f 100644 --- a/doc/src/overview/creator-acknowledgements.qdoc +++ b/doc/src/overview/creator-acknowledgements.qdoc @@ -51,6 +51,45 @@ \QC contains the following third-party components: \list + \li \b{Syntax highlighting engine for Kate syntax definitions} + + This is a stand-alone implementation of the Kate syntax highlighting engine. + It's meant as a building block for text editors as well as for simple highlighted + text rendering (e.g. as HTML), supporting both integration with a custom editor + as well as a ready-to-use QSyntaxHighlighter sub-class. + + Distributed under the: + \code + MIT License + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + \endcode + + The source code of KSyntaxHighlighting can be found + here: + \list + \li \l{https://cgit.kde.org/syntax-highlighting.git} + \li QtCreator/src/libs/3rdparty/syntax-highlighting + \li \l{https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/src/libs/3rdparty/syntax-highlighting} + \endlist + \li \b{Reference implementation for std::experimental::optional} Copyright (C) 2011-2012 Andrzej Krzemienski diff --git a/qtcreator.pri b/qtcreator.pri index 10d6dc3bef..3b77cc86a7 100644 --- a/qtcreator.pri +++ b/qtcreator.pri @@ -196,6 +196,7 @@ for(dir, QTC_PLUGIN_DIRS) { QTC_LIB_DIRS_FROM_ENVIRONMENT = $$(QTC_LIB_DIRS) QTC_LIB_DIRS += $$split(QTC_LIB_DIRS_FROM_ENVIRONMENT, $$QMAKE_DIRLIST_SEP) QTC_LIB_DIRS += $$IDE_SOURCE_TREE/src/libs +QTC_LIB_DIRS += $$IDE_SOURCE_TREE/src/libs/3rdparty for(dir, QTC_LIB_DIRS) { INCLUDEPATH += $$dir } diff --git a/src/libs/3rdparty/syntax-highlighting/.arcconfig b/src/libs/3rdparty/syntax-highlighting/.arcconfig new file mode 100644 index 0000000000..b9b60c853e --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/.arcconfig @@ -0,0 +1,3 @@ +{ + "phabricator.uri" : "https://phabricator.kde.org/project/profile/152/" +} diff --git a/src/libs/3rdparty/syntax-highlighting/.gitignore b/src/libs/3rdparty/syntax-highlighting/.gitignore new file mode 100644 index 0000000000..02ba11c78a --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/.gitignore @@ -0,0 +1,9 @@ +*.kdev4 +*.orig +*.out +*.rej +*~ +/compile.pl +CMakeLists.txt.user +callgrind.* +heaptrack.* diff --git a/src/libs/3rdparty/syntax-highlighting/.kateconfig b/src/libs/3rdparty/syntax-highlighting/.kateconfig new file mode 100644 index 0000000000..444208643c --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/.kateconfig @@ -0,0 +1 @@ +// kate: space-indent on; indent-width 4; remove-trailing-spaces modified; diff --git a/src/libs/3rdparty/syntax-highlighting/.krazy b/src/libs/3rdparty/syntax-highlighting/.krazy new file mode 100644 index 0000000000..02e434cc0f --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/.krazy @@ -0,0 +1,2 @@ +CHECKSETS kde5 +SKIP /autotests/input/ diff --git a/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt b/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt new file mode 100644 index 0000000000..49923fb26e --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt @@ -0,0 +1,134 @@ +cmake_minimum_required(VERSION 3.0) + +set(KF5_VERSION "5.52.0") +project(KSyntaxHighlighting VERSION ${KF5_VERSION}) + +find_package(ECM 5.51.0 REQUIRED NO_MODULE) +set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) +if(POLICY CMP0063) + cmake_policy(SET CMP0063 NEW) +endif() + +include(FeatureSummary) +include(GenerateExportHeader) +include(ECMSetupVersion) +include(ECMGenerateHeaders) +include(ECMGeneratePriFile) +include(CMakePackageConfigHelpers) +include(ECMPoQmTools) +include(ECMQtDeclareLoggingCategory) +include(KDEInstallDirs) +include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) +include(KDECMakeSettings) +include(ECMMarkNonGuiExecutable) +include(ECMAddQch) + + +ecm_setup_version(PROJECT + VARIABLE_PREFIX SyntaxHighlighting + VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/ksyntaxhighlighting_version.h" + PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5SyntaxHighlightingConfigVersion.cmake" +) + +# +# Dependencies +# +set(REQUIRED_QT_VERSION 5.8.0) +find_package(Qt5 ${REQUIRED_QT_VERSION} NO_MODULE REQUIRED COMPONENTS Core Network Test) +option(KSYNTAXHIGHLIGHTING_USE_GUI "Build components depending on Qt5Gui" ON) +if(KSYNTAXHIGHLIGHTING_USE_GUI) + find_package(Qt5 ${REQUIRED_QT_VERSION} NO_MODULE REQUIRED COMPONENTS Gui) +endif() +find_package(Qt5 ${REQUIRED_QT_VERSION} NO_MODULE QUIET OPTIONAL_COMPONENTS Widgets XmlPatterns) +set_package_properties(Qt5 PROPERTIES URL "http://qt-project.org/") +set_package_properties(Qt5Widgets PROPERTIES PURPOSE "Example application.") +set_package_properties(Qt5XmlPatterns PROPERTIES PURPOSE "Compile-time validation of syntax definition files.") + +find_package(Perl REQUIRED) +set_package_properties(Perl PROPERTIES PURPOSE "Auto-generate PHP syntax definition files.") + +# +# allow to install the "differently" licensed syntax xml files instead of putting them in a QRC and link them in +# +option(QRC_SYNTAX "Bundle the syntax definition files inside the library as resources" ON) +add_feature_info(SYNTAX_RESOURCE ${QRC_SYNTAX} "Bundle the syntax definition files inside the library as resources") + +# +# allow to turn of lookup for syntax files and themes via QStandardPaths +# +option(NO_STANDARD_PATHS "Skip lookup of syntax and theme definitions in QStandardPaths locations" OFF) +add_feature_info(FEATURE_NO_STANDARD_PATHS ${NO_STANDARD_PATHS} "Skip lookup of syntax and theme definitions in QStandardPaths locations") + +# +# API documentation +# +option(BUILD_QCH "Build API documentation in QCH format (for e.g. Qt Assistant, Qt Creator & KDevelop)" OFF) +add_feature_info(QCH ${BUILD_QCH} "API documentation in QCH format (for e.g. Qt Assistant, Qt Creator & KDevelop)") + +# +# Translations +# +if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/po") + ecm_install_po_files_as_qm(po) +endif() + +# tell the framework if it shall use the syntax files from the resource +if (QRC_SYNTAX) + add_definitions(-DHAS_SYNTAX_RESOURCE) +endif() + +# skip standard paths? +if (NO_STANDARD_PATHS) + add_definitions(-DNO_STANDARD_PATHS) +endif() + +# +# Actually build the stuff +# +include_directories(${CMAKE_CURRENT_BINARY_DIR}) +add_subdirectory(data) +add_subdirectory(src) +if(TARGET Qt5::Gui) + add_subdirectory(examples) +endif() + +# +# CMake package config file generation +# +set(CMAKECONFIG_INSTALL_DIR "${CMAKECONFIG_INSTALL_PREFIX}/KF5SyntaxHighlighting") + +if (BUILD_QCH) + ecm_install_qch_export( + TARGETS KF5SyntaxHighlighting_QCH + FILE KF5SyntaxHighlightingQchTargets.cmake + DESTINATION "${CMAKECONFIG_INSTALL_DIR}" + COMPONENT Devel + ) + set(PACKAGE_INCLUDE_QCHTARGETS "include(\"\${CMAKE_CURRENT_LIST_DIR}/KF5SyntaxHighlightingQchTargets.cmake\")") +endif() + +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/KF5SyntaxHighlightingConfig.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/KF5SyntaxHighlightingConfig.cmake" + INSTALL_DESTINATION "${CMAKECONFIG_INSTALL_DIR}" +) + +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/KF5SyntaxHighlightingConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/KF5SyntaxHighlightingConfigVersion.cmake" + DESTINATION "${CMAKECONFIG_INSTALL_DIR}" + COMPONENT Devel) + +if(TARGET KF5SyntaxHighlighting) + install(EXPORT KF5SyntaxHighlightingTargets + DESTINATION "${CMAKECONFIG_INSTALL_DIR}" + FILE KF5SyntaxHighlightingTargets.cmake + NAMESPACE KF5::) +endif() + +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ksyntaxhighlighting_version.h" + DESTINATION "${KDE_INSTALL_INCLUDEDIR_KF5}" + COMPONENT Devel) +install(FILES org_kde_ksyntaxhighlighting.categories DESTINATION ${KDE_INSTALL_CONFDIR}) + +feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/src/libs/3rdparty/syntax-highlighting/COPYING b/src/libs/3rdparty/syntax-highlighting/COPYING new file mode 100644 index 0000000000..6b96fea18b --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/COPYING @@ -0,0 +1,20 @@ +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/libs/3rdparty/syntax-highlighting/KF5SyntaxHighlightingConfig.cmake.in b/src/libs/3rdparty/syntax-highlighting/KF5SyntaxHighlightingConfig.cmake.in new file mode 100644 index 0000000000..0fd1778fb8 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/KF5SyntaxHighlightingConfig.cmake.in @@ -0,0 +1,6 @@ +@PACKAGE_INIT@ + +find_package(Qt5 @Qt5Core_VERSION_MAJOR@.@Qt5Core_VERSION_MINOR@ NO_MODULE REQUIRED COMPONENTS Core Gui) + +include("${CMAKE_CURRENT_LIST_DIR}/KF5SyntaxHighlightingTargets.cmake") +@PACKAGE_INCLUDE_QCHTARGETS@ diff --git a/src/libs/3rdparty/syntax-highlighting/QC_README.txt b/src/libs/3rdparty/syntax-highlighting/QC_README.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/QC_README.txt diff --git a/src/libs/3rdparty/syntax-highlighting/README.md b/src/libs/3rdparty/syntax-highlighting/README.md new file mode 100644 index 0000000000..1eedc0af7f --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/README.md @@ -0,0 +1,32 @@ +# Syntax Highlighting + +Syntax highlighting engine for Kate syntax definitions + +## Introduction + +This is a stand-alone implementation of the Kate syntax highlighting engine. +It's meant as a building block for text editors as well as for simple highlighted +text rendering (e.g. as HTML), supporting both integration with a custom editor +as well as a ready-to-use QSyntaxHighlighter sub-class. + +## Syntax Definition Files + +This library uses Kate syntax definition files for the actual highlighting, +the file format is documented [here](https://docs.kde.org/stable5/en/applications/katepart/highlight.html). + +More than 250 syntax definition files are included, additional ones are +picked up from the file system if present, so you can easily extend this +by application-specific syntax definitions for example. + +## Out of scope + +To not turn this into yet another text editor, the following things are considered +out of scope: + +* code folding, beyond providing folding range information +* auto completion +* spell checking +* user interface for configuration +* management of text buffers or documents + +If you need any of this, check out [KTextEditor](https://api.kde.org/frameworks/ktexteditor/html/). diff --git a/src/libs/3rdparty/syntax-highlighting/autogenerated/autogenerated.pri b/src/libs/3rdparty/syntax-highlighting/autogenerated/autogenerated.pri new file mode 100644 index 0000000000..aee620add9 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/autogenerated/autogenerated.pri @@ -0,0 +1,9 @@ +INCLUDEPATH *= $$PWD/src/lib +INCLUDEPATH *= $$PWD + +SOURCES += \ + $$PWD/src/lib/ksyntaxhighlighting_logging.cpp + +HEADERS += \ + $$PWD/ksyntaxhighlighting_version.h \ + $$PWD/src/lib/ksyntaxhighlighting_logging.h diff --git a/src/libs/3rdparty/syntax-highlighting/autogenerated/ksyntaxhighlighting_version.h b/src/libs/3rdparty/syntax-highlighting/autogenerated/ksyntaxhighlighting_version.h new file mode 100644 index 0000000000..bd31a4d407 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/autogenerated/ksyntaxhighlighting_version.h @@ -0,0 +1,12 @@ +// This file was generated by ecm_setup_version(): DO NOT EDIT! + +#ifndef SyntaxHighlighting_VERSION_H +#define SyntaxHighlighting_VERSION_H + +#define SyntaxHighlighting_VERSION_STRING "5.52.0" +#define SyntaxHighlighting_VERSION_MAJOR 5 +#define SyntaxHighlighting_VERSION_MINOR 52 +#define SyntaxHighlighting_VERSION_PATCH 0 +#define SyntaxHighlighting_VERSION ((5<<16)|(52<<8)|(0)) + +#endif diff --git a/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/AbstractHighlighter b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/AbstractHighlighter new file mode 100644 index 0000000000..b787873771 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/AbstractHighlighter @@ -0,0 +1 @@ +#include "abstracthighlighter.h" diff --git a/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/Definition b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/Definition new file mode 100644 index 0000000000..2c3241f841 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/Definition @@ -0,0 +1 @@ +#include "definition.h" diff --git a/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/FoldingRegion b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/FoldingRegion new file mode 100644 index 0000000000..005b829d53 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/FoldingRegion @@ -0,0 +1 @@ +#include "foldingregion.h" diff --git a/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/Format b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/Format new file mode 100644 index 0000000000..b0d6a10246 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/Format @@ -0,0 +1 @@ +#include "format.h" diff --git a/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/Repository b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/Repository new file mode 100644 index 0000000000..189dbc2f69 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/Repository @@ -0,0 +1 @@ +#include "repository.h" diff --git a/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/State b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/State new file mode 100644 index 0000000000..e148d70391 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/State @@ -0,0 +1 @@ +#include "state.h" diff --git a/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/SyntaxHighlighter b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/SyntaxHighlighter new file mode 100644 index 0000000000..b42982473b --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/SyntaxHighlighter @@ -0,0 +1 @@ +#include "syntaxhighlighter.h" diff --git a/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/Theme b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/Theme new file mode 100644 index 0000000000..34a3e98e60 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/Theme @@ -0,0 +1 @@ +#include "theme.h" diff --git a/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/ksyntaxhighlighting_logging.cpp b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/ksyntaxhighlighting_logging.cpp new file mode 100644 index 0000000000..4082ac4aff --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/ksyntaxhighlighting_logging.cpp @@ -0,0 +1,11 @@ +// This file was generated by ecm_qt_declare_logging_category(): DO NOT EDIT! + +#include "ksyntaxhighlighting_logging.h" + + namespace KSyntaxHighlighting { +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) +Q_LOGGING_CATEGORY(Log, "org.kde.ksyntaxhighlighting", QtInfoMsg) +#else +Q_LOGGING_CATEGORY(Log, "org.kde.ksyntaxhighlighting") +#endif +} diff --git a/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/ksyntaxhighlighting_logging.h b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/ksyntaxhighlighting_logging.h new file mode 100644 index 0000000000..c351b2cb92 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/ksyntaxhighlighting_logging.h @@ -0,0 +1,11 @@ +// This file was generated by ecm_qt_declare_logging_category(): DO NOT EDIT! + +#ifndef ECM_QLOGGINGCATEGORY_KSYNTAXHIGHLIGHTING_LOG_KSYNTAXHIGHLIGHTING_LOGGING_H +#define ECM_QLOGGINGCATEGORY_KSYNTAXHIGHLIGHTING_LOG_KSYNTAXHIGHLIGHTING_LOGGING_H + +#include <QLoggingCategory> + namespace KSyntaxHighlighting { +Q_DECLARE_LOGGING_CATEGORY(Log) +} + +#endif diff --git a/src/libs/3rdparty/syntax-highlighting/data/CMakeLists.txt b/src/libs/3rdparty/syntax-highlighting/data/CMakeLists.txt new file mode 100644 index 0000000000..73adbe6d20 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/CMakeLists.txt @@ -0,0 +1,61 @@ +# generate PHP definitions +macro(generate_php_syntax_definition targetFile srcFile) + execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/syntax) + execute_process(COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/generators/generate-php.pl + INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/syntax/${srcFile} + OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/syntax/${targetFile}) +endmacro() + +generate_php_syntax_definition(javascript-php.xml javascript.xml) +generate_php_syntax_definition(css-php.xml css.xml) +generate_php_syntax_definition(html-php.xml html.xml) + +# find all definitions +file(GLOB src_defs "${CMAKE_CURRENT_SOURCE_DIR}/syntax/*.xml") +set(defs + ${src_defs} + ${CMAKE_CURRENT_BINARY_DIR}/syntax/html-php.xml + ${CMAKE_CURRENT_BINARY_DIR}/syntax/css-php.xml + ${CMAKE_CURRENT_BINARY_DIR}/syntax/javascript-php.xml +) + +# theme data resource +qt5_add_resources(themes_QRC ${CMAKE_CURRENT_SOURCE_DIR}/themes/theme-data.qrc) + +# do we want syntax files bundled in the library? +if (QRC_SYNTAX) + # generate the resource file + set(qrc_file ${CMAKE_CURRENT_BINARY_DIR}/syntax-data.qrc) + set(qrc_body "") + foreach(def ${defs}) + get_filename_component(def_name ${def} NAME) + string(APPEND qrc_body "<file alias=\"${def_name}\">${def}</file>\n") + endforeach() + set(SYNTAX_DATA_QRC_FILES_STRING ${qrc_body}) + configure_file(syntax-data.qrc.in ${qrc_file} @ONLY) + + # generate the index file + add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/index.katesyntax" + COMMAND katehighlightingindexer "${CMAKE_CURRENT_BINARY_DIR}/index.katesyntax" "${CMAKE_CURRENT_SOURCE_DIR}/schema/language.xsd" "${CMAKE_CURRENT_BINARY_DIR}/syntax-data.qrc" + DEPENDS ${defs} ${CMAKE_CURRENT_SOURCE_DIR}/schema/language.xsd ${CMAKE_CURRENT_BINARY_DIR}/syntax-data.qrc + ) + + # generate the qrc file manually, to make dependencies on generated files work... + add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/qrc_syntax-data.cpp" + COMMAND ${Qt5Core_RCC_EXECUTABLE} --name syntax_data -o "${CMAKE_CURRENT_BINARY_DIR}/qrc_syntax-data.cpp" "${CMAKE_CURRENT_BINARY_DIR}/syntax-data.qrc" + DEPENDS ${defs} ${CMAKE_CURRENT_BINARY_DIR}/index.katesyntax + ) + set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/qrc_syntax-data.cpp" PROPERTIES SKIP_AUTOMOC ON) + + # object library to make cross-folder dependencies work, themes + syntax files + add_library(SyntaxHighlightingData OBJECT ${themes_QRC} ${CMAKE_CURRENT_BINARY_DIR}/qrc_syntax-data.cpp) +else() + # install the syntax files as normal files into the prefix + install (FILES ${defs} DESTINATION share/org.kde.syntax-highlighting/syntax) + + # object library to make cross-folder dependencies work, only themes + add_library(SyntaxHighlightingData OBJECT ${themes_QRC}) +endif() + +# set PIC to allow use in static and shared libs +set_property(TARGET SyntaxHighlightingData PROPERTY POSITION_INDEPENDENT_CODE 1) diff --git a/src/libs/3rdparty/syntax-highlighting/data/data.pro b/src/libs/3rdparty/syntax-highlighting/data/data.pro new file mode 100644 index 0000000000..1028ea1579 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/data.pro @@ -0,0 +1,11 @@ +TEMPLATE = aux + +include(../../../../../qtcreator.pri) + +STATIC_BASE = $$PWD +STATIC_OUTPUT_BASE = $$IDE_DATA_PATH/generic-highlighter +STATIC_INSTALL_BASE = $$INSTALL_DATA_PATH/generic-highlighter + +STATIC_FILES += $$files($$PWD/syntax/*, true) + +include(../../../../../qtcreatordata.pri) diff --git a/src/libs/3rdparty/syntax-highlighting/data/generators/cmake.xml.tpl b/src/libs/3rdparty/syntax-highlighting/data/generators/cmake.xml.tpl new file mode 100644 index 0000000000..33cc7511aa --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/generators/cmake.xml.tpl @@ -0,0 +1,323 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE language SYSTEM "language.dtd" +[ + <!ENTITY id_re "[_A-Za-z][\-_0-9A-Za-z]*"> +]> +<!-- + This file is part of KDE's kate project. + + Copyright 2004 Alexander Neundorf (neundorf@kde.org) + Copyright 2005 Dominik Haumann (dhdev@gmx.de) + Copyright 2007,2008,2013,2014 Matthew Woehlke (mw_triad@users.sourceforge.net) + Copyright 2013-2015,2017-2018 Alex Turbov (i.zaufi@gmail.com) + + ********************************************************************** + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the * + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301, USA. * + ********************************************************************** + --> + +<language + name="CMake" + version="11" + kateversion="2.4" + section="Other" + extensions="CMakeLists.txt;*.cmake;*.cmake.in" + style="CMake" + mimetype="text/x-cmake" + author="Alex Turbov (i.zaufi@gmail.com)" + license="LGPLv2+" + > + <highlighting> + + <list name="commands"> + {%- for command in commands %} + <item>{{command.name}}</item> + {%- endfor %} + </list> + {% for command in commands -%} + {%- if command.named_args and command.named_args.kw %} + <list name="{{command.name}}_nargs"> + {%- for arg in command.named_args.kw %} + <item>{{arg}}</item> + {%- endfor %} + </list> + {%- endif %} + {%- if command.special_args and command.special_args.kw %} + <list name="{{command.name}}_sargs"> + {%- for arg in command.special_args.kw %} + <item>{{arg}}</item> + {%- endfor %} + </list> + {%- endif %} + {%- endfor %} + + <list name="variables"> + {%- for var in variables.kw %} + <item>{{var}}</item> + {%- endfor %} + </list> + + {%- for kind in properties.kinds %} + <list name="{{ kind|replace('_', '-') }}"> + {%- for prop in properties[kind].kw %} + <item>{{prop}}</item> + {%- endfor %} + </list> + {%- endfor %} + + <list name="generator-expressions"> + {%- for expr in generator_expressions %} + <item>{{ expr }}</item> + {%- endfor %} + </list> + + <contexts> + + <context attribute="Normal Text" lineEndContext="#stay" name="Normal Text"> + <DetectSpaces/> + {% for command in commands -%} + <WordDetect String="{{command.name}}" insensitive="true" attribute="Command" context="{{command.name}}_ctx" /> + {% endfor -%} + <RegExpr attribute="Region Marker" context="RST Documentation" String="^#\[(=*)\[\.rst:" column="0" /> + <RegExpr attribute="Comment" context="Bracketed Comment" String="#\[(=*)\[" /> + <DetectChar attribute="Comment" context="Comment" char="#" /> + <DetectIdentifier attribute="User Function/Macro" context="User Function" /> + <RegExpr attribute="@Variable Substitution" context="@VarSubst" String="@&id_re;@" lookAhead="true" /> + <!-- Include keywords matching for language autocompleter work --> + <keyword attribute="Command" context="#stay" String="commands" /> + </context> + + {% for command in commands -%} + {# + <!-- + {{ command|pprint }} + --> + -#} + <context attribute="Normal Text" lineEndContext="#stay" name="{{command.name}}_ctx"> + <DetectChar attribute="Normal Text" context="{{command.name}}_ctx_op" char="(" /> + </context> + <context attribute="Normal Text" lineEndContext="#stay" name="{{command.name}}_ctx_op"> + {%- if command.nested_parentheses %} + <DetectChar attribute="Normal Text" context="{{command.name}}_ctx_op_nested" char="(" /> + {%- endif %} + <IncludeRules context="EndCmdPop2" /> + {%- if command.named_args and command.named_args.kw %} + <keyword attribute="Named Args" context="#stay" String="{{command.name}}_nargs" /> + {%- endif %} + {%- if command.special_args and command.special_args.kw %} + <keyword attribute="Special Args" context="#stay" String="{{command.name}}_sargs" /> + {%- endif %} + {%- if command.property_args and command.property_args.kw %} + {%- for kind in command.property_args.kw %} + <keyword attribute="Property" context="#stay" String="{{kind}}" /> + {%- if properties[kind|replace('-', '_')].re %} + <IncludeRules context="Detect More {{kind}}" /> + {%- endif %} + {%- endfor %} + {%- endif %} + {%- if command is not nulary %} + <IncludeRules context="User Function Args" /> + {%- if command.name == 'cmake_policy' %} + <!-- NOTE Handle CMP<NNN> as a special arg of `cmake_policy` command --> + <RegExpr attribute="Special Args" context="#stay" String="\bCMP[0-9]+\b" /> + {%- endif %} + {%- endif %} + </context> + {%- if command.nested_parentheses %} + <context attribute="Normal Text" lineEndContext="#stay" name="{{command.name}}_ctx_op_nested"> + <IncludeRules context="EndCmdPop" /> + {%- if command.named_args and command.named_args.kw %} + <keyword attribute="Named Args" context="#stay" String="{{command.name}}_nargs" /> + {%- endif %} + {%- if command.special_args and command.special_args.kw %} + <keyword attribute="Special Args" context="#stay" String="{{command.name}}_sargs" /> + {%- endif %} + {%- if command.property_args and command.property_args.kw %} + {%- for kind in command.property_args.kw %} + <keyword attribute="Property" context="#stay" String="{{kind}}" /> + {%- if properties[kind|replace('-', '_')].re %} + <IncludeRules context="Detect More {{kind}}" /> + {%- endif %} + {%- endfor %} + {%- endif %} + <IncludeRules context="User Function Args" /> + </context> + {%- endif %} + {% endfor -%} + + {% for kind in properties.kinds if properties[kind].re -%} + <context attribute="Normal Text" lineEndContext="#stay" name="Detect More {{ kind|replace('_', '-') }}"> + {%- for prop in properties[kind].re %} + <RegExpr attribute="Property" context="#stay" String="{{prop}}" /> + {%- endfor %} + </context>{{ '\n' }} + {% endfor -%} + + <context attribute="Normal Text" lineEndContext="#stay" name="EndCmdPop"> + <DetectChar attribute="Normal Text" context="#pop" char=")" /> + </context> + + <context attribute="Normal Text" lineEndContext="#stay" name="EndCmdPop2"> + <DetectChar attribute="Normal Text" context="#pop#pop" char=")" /> + </context> + + <context attribute="User Function/Macro" lineEndContext="#stay" name="User Function"> + <DetectChar attribute="Normal Text" context="User Function Opened" char="(" /> + <IncludeRules context="EndCmdPop2" /> + </context> + + <context attribute="Normal Text" lineEndContext="#stay" name="User Function Opened"> + <IncludeRules context="EndCmdPop2" /> + <IncludeRules context="User Function Args" /> + </context> + + <context attribute="Normal Text" lineEndContext="#stay" name="Detect Builtin Variables"> + <keyword attribute="Builtin Variable" context="#stay" String="variables" insensitive="false" /> + <IncludeRules context="Detect More Builtin Variables" /> + <RegExpr attribute="Internal Name" context="#stay" String="\b_&id_re;\b" /> + </context> + + <context attribute="Normal Text" lineEndContext="#stay" name="Detect More Builtin Variables"> + {%- for var in variables.re %} + <RegExpr attribute="Builtin Variable" context="#stay" String="{{var}}" /> + {%- endfor %} + </context> + + <context attribute="Normal Text" lineEndContext="#stay" name="Detect Variable Substitutions"> + <RegExpr attribute="Environment Variable Substitution" context="#stay" String="\$ENV\{\s*[\w-]+\s*\}" /> + <Detect2Chars attribute="Variable Substitution" context="VarSubst" char="$" char1="{" /> + <RegExpr attribute="@Variable Substitution" context="@VarSubst" String="@&id_re;@" lookAhead="true" /> + </context> + + <context attribute="Variable Substitution" lineEndContext="#pop" name="VarSubst"> + <IncludeRules context="Detect Builtin Variables" /> + <DetectIdentifier /> + <DetectChar attribute="Variable Substitution" context="#pop" char="}" /> + <IncludeRules context="Detect Variable Substitutions" /> + </context> + + <context attribute="@Variable Substitution" lineEndContext="#pop" name="@VarSubst"> + <DetectChar attribute="@Variable Substitution" context="VarSubst@" char="@" /> + </context> + + <context attribute="@Variable Substitution" lineEndContext="#pop#pop" name="VarSubst@"> + <IncludeRules context="Detect Builtin Variables" /> + <DetectIdentifier /> + <DetectChar attribute="@Variable Substitution" context="#pop#pop" char="@" /> + </context> + + <context attribute="Normal Text" lineEndContext="#stay" name="User Function Args"> + <Detect2Chars attribute="Normal Text" context="#stay" char="\" char1="(" /> + <Detect2Chars attribute="Normal Text" context="#stay" char="\" char1=")" /> + <RegExpr attribute="Escapes" context="#stay" String="\\["$n\\]" /> + <DetectChar attribute="Strings" context="String" char=""" /> + <RegExpr attribute="Strings" context="Bracketed String" String="\[(=*)\[" /> + <RegExpr attribute="Comment" context="Bracketed Comment" String="#\[(=*)\[" /> + <DetectChar attribute="Comment" context="Comment" char="#" /> + <IncludeRules context="Detect Builtin Variables" /> + <IncludeRules context="Detect Variable Substitutions" /> + <IncludeRules context="Detect Special Values" /> + <IncludeRules context="Detect Aliased Targets" /> + <IncludeRules context="Detect Generator Expressions" /> + </context> + + <context attribute="Normal Text" lineEndContext="#stay" name="Detect Special Values"> + <RegExpr attribute="True Special Arg" context="#stay" String="\b(TRUE|ON)\b" /> + <RegExpr attribute="False Special Arg" context="#stay" String="\b(FALSE|OFF|(&id_re;-)?NOTFOUND)\b" /> + <RegExpr attribute="Special Args" context="#stay" String="\bCMP[0-9][0-9][0-9]\b" /> + </context> + + <context attribute="Normal Text" lineEndContext="#stay" name="Detect Aliased Targets"> + <RegExpr attribute="Aliased Targets" context="#stay" String="\b&id_re;::&id_re;(::&id_re;)*\b" /> + </context> + + <context attribute="Comment" lineEndContext="#pop" name="Comment"> + <LineContinue attribute="Comment" context="#pop" /> + <IncludeRules context="##Alerts" /> + <IncludeRules context="##Modelines" /> + </context> + + <context attribute="Comment" lineEndContext="#stay" name="RST Documentation" dynamic="true"> + <RegExpr attribute="Region Marker" context="#pop" String="^#?\]%1\]" dynamic="true" column="0" /> + <IncludeRules context="##reStructuredText" /> + </context> + + <context attribute="Comment" lineEndContext="#stay" name="Bracketed Comment" dynamic="true"> + <RegExpr attribute="Comment" context="#pop" String=".*\]%1\]" dynamic="true" /> + <IncludeRules context="##Alerts" /> + <IncludeRules context="##Modelines" /> + </context> + + <context attribute="Strings" lineEndContext="#stay" name="String"> + <RegExpr attribute="Strings" context="#pop" String=""(?=[ );]|$)" /> + <RegExpr attribute="Escapes" context="#stay" String="\\["$nrt\\]" /> + <IncludeRules context="Detect Variable Substitutions" /> + <IncludeRules context="Detect Generator Expressions" /> + </context> + + <context attribute="Strings" lineEndContext="#stay" name="Bracketed String" dynamic="true"> + <RegExpr attribute="Strings" context="#pop" String="\]%1\]" dynamic="true" /> + </context> + + <context attribute="Normal Text" lineEndContext="#stay" name="Detect Generator Expressions"> + <Detect2Chars attribute="Generator Expression" context="Generator Expression" char="$" char1="<" /> + </context> + + <context attribute="Generator Expression" lineEndContext="#stay" name="Generator Expression"> + <IncludeRules context="Detect Generator Expressions" /> + <DetectChar attribute="Comment" context="Comment" char="#" /> + <DetectChar attribute="Generator Expression" context="#pop" char=">" /> + <keyword attribute="Generator Expression Keyword" context="#stay" String="generator-expressions" insensitive="false" /> + <IncludeRules context="Detect Aliased Targets" /> + <IncludeRules context="Detect Variable Substitutions" /> + </context> + + </contexts> + + <itemDatas> + <itemData name="Normal Text" defStyleNum="dsNormal" spellChecking="false" /> + <itemData name="Command" defStyleNum="dsKeyword" spellChecking="false" /> + <itemData name="User Function/Macro" defStyleNum="dsFunction" spellChecking="false" /> + <itemData name="Property" defStyleNum="dsOthers" spellChecking="false" /> + <itemData name="Aliased Targets" defStyleNum="dsBaseN" spellChecking="false" /> + <itemData name="Named Args" defStyleNum="dsOthers" spellChecking="false" /> + <itemData name="Special Args" defStyleNum="dsOthers" spellChecking="false" /> + <itemData name="True Special Arg" defStyleNum="dsOthers" color="#30a030" selColor="#30a030" spellChecking="false" /> + <itemData name="False Special Arg" defStyleNum="dsOthers" color="#e05050" selColor="#e05050" spellChecking="false" /> + <itemData name="Strings" defStyleNum="dsString" spellChecking="true" /> + <itemData name="Escapes" defStyleNum="dsChar" spellChecking="false" /> + <itemData name="Builtin Variable" defStyleNum="dsDecVal" color="#c09050" selColor="#c09050" spellChecking="false" /> + <itemData name="Variable Substitution" defStyleNum="dsDecVal" spellChecking="false" /> + <itemData name="@Variable Substitution" defStyleNum="dsBaseN" spellChecking="false" /> + <itemData name="Internal Name" defStyleNum="dsDecVal" color="#303030" selColor="#303030" spellChecking="false" /> + <itemData name="Environment Variable Substitution" defStyleNum="dsFloat" spellChecking="false" /> + <itemData name="Generator Expression Keyword" defStyleNum="dsKeyword" color="#b84040" selColor="#b84040" spellChecking="false" /> + <itemData name="Generator Expression" defStyleNum="dsOthers" color="#b86050" selColor="#b86050" spellChecking="false" /> + <itemData name="Comment" defStyleNum="dsComment" spellChecking="true" /> + <itemData name="Region Marker" defStyleNum="dsRegionMarker" spellChecking="false" /> + </itemDatas> + + </highlighting> + + <general> + <comments> + <comment name="singleLine" start="#" /> + </comments> + <keywords casesensitive="1" /> + </general> +</language> + +<!-- kate: indent-width 2; tab-width 2; --> diff --git a/src/libs/3rdparty/syntax-highlighting/data/generators/cmake.yaml b/src/libs/3rdparty/syntax-highlighting/data/generators/cmake.yaml new file mode 100644 index 0000000000..1174c35215 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/generators/cmake.yaml @@ -0,0 +1,2446 @@ +global-properties: + - ALLOW_DUPLICATE_CUSTOM_TARGETS + - AUTOGEN_SOURCE_GROUP + - AUTOGEN_TARGETS_FOLDER + - AUTOMOC_SOURCE_GROUP + - AUTOMOC_TARGETS_FOLDER + - AUTORCC_SOURCE_GROUP + - CMAKE_C_KNOWN_FEATURES + - CMAKE_CXX_KNOWN_FEATURES + - DEBUG_CONFIGURATIONS + - DISABLED_FEATURES + - ENABLED_FEATURES + - ENABLED_LANGUAGES + - FIND_LIBRARY_USE_LIB32_PATHS + - FIND_LIBRARY_USE_LIB64_PATHS + - FIND_LIBRARY_USE_LIBX32_PATHS + - FIND_LIBRARY_USE_OPENBSD_VERSIONING + - GENERATOR_IS_MULTI_CONFIG + - GLOBAL_DEPENDS_DEBUG_MODE + - GLOBAL_DEPENDS_NO_CYCLES + - IN_TRY_COMPILE + - PACKAGES_FOUND + - PACKAGES_NOT_FOUND + - JOB_POOLS + - PREDEFINED_TARGETS_FOLDER + - ECLIPSE_EXTRA_NATURES + - REPORT_UNDEFINED_PROPERTIES + - RULE_LAUNCH_COMPILE + - RULE_LAUNCH_CUSTOM + - RULE_LAUNCH_LINK + - RULE_MESSAGES + - TARGET_ARCHIVES_MAY_BE_SHARED_LIBS + - TARGET_MESSAGES + - TARGET_SUPPORTS_SHARED_LIBS + - USE_FOLDERS + - XCODE_EMIT_EFFECTIVE_PLATFORM_NAME + # Other well-known global properties + # - FeatureSummary + - FeatureSummary_PKG_TYPES + - FeatureSummary_REQUIRED_PKG_TYPES + - FeatureSummary_DEFAULT_PKG_TYPE + - FeatureSummary_<TYPE>_DESCRIPTION + +directory-properties: + - ADDITIONAL_MAKE_CLEAN_FILES + - BINARY_DIR + - BUILDSYSTEM_TARGETS + - CACHE_VARIABLES + - CLEAN_NO_CUSTOM + - CMAKE_CONFIGURE_DEPENDS + - COMPILE_DEFINITIONS + - COMPILE_OPTIONS + - DEFINITIONS + - EXCLUDE_FROM_ALL + - IMPLICIT_DEPENDS_INCLUDE_TRANSFORM + - INCLUDE_DIRECTORIES + - INCLUDE_REGULAR_EXPRESSION + - INTERPROCEDURAL_OPTIMIZATION_<CONFIG> + - INTERPROCEDURAL_OPTIMIZATION + - LABELS # Since 3.10 + - LINK_DIRECTORIES + - LINK_OPTIONS # Since 3.13 + - LISTFILE_STACK + - MACROS + - PARENT_DIRECTORY + - RULE_LAUNCH_COMPILE + - RULE_LAUNCH_CUSTOM + - RULE_LAUNCH_LINK + - SOURCE_DIR + - SUBDIRECTORIES + - TESTS # Since 3.12 + - TEST_INCLUDE_FILE + - TEST_INCLUDE_FILES # Since 3.10 + - VARIABLES + - VS_GLOBAL_SECTION_POST_<section> + - VS_GLOBAL_SECTION_PRE_<section> + - VS_STARTUP_PROJECT + +# NOTE Copy-n-pasting this list from official docs may contain a redudant item `Example`! Check it! +target-properties: + - ALIASED_TARGET + - ANDROID_ANT_ADDITIONAL_OPTIONS + - ANDROID_API + - ANDROID_API_MIN + - ANDROID_ARCH + - ANDROID_ASSETS_DIRECTORIES + - ANDROID_GUI + - ANDROID_JAR_DEPENDENCIES + - ANDROID_JAR_DIRECTORIES + - ANDROID_JAVA_SOURCE_DIR + - ANDROID_NATIVE_LIB_DEPENDENCIES + - ANDROID_NATIVE_LIB_DIRECTORIES + - ANDROID_PROCESS_MAX + - ANDROID_PROGUARD + - ANDROID_PROGUARD_CONFIG_PATH + - ANDROID_SECURE_PROPS_PATH + - ANDROID_SKIP_ANT_STEP + - ANDROID_STL_TYPE + - ARCHIVE_OUTPUT_DIRECTORY_<CONFIG> + - ARCHIVE_OUTPUT_DIRECTORY + - ARCHIVE_OUTPUT_NAME_<CONFIG> + - ARCHIVE_OUTPUT_NAME + - AUTOGEN_BUILD_DIR + - AUTOGEN_TARGET_DEPENDS + - AUTOMOC_DEPEND_FILTERS + - AUTOMOC_MOC_OPTIONS + - AUTOMOC + - AUTOUIC + - AUTOUIC_OPTIONS + - AUTOUIC_SEARCH_PATHS + - AUTORCC + - AUTORCC_OPTIONS + - BINARY_DIR + - BUILD_RPATH + - BUILD_WITH_INSTALL_NAME_DIR + - BUILD_WITH_INSTALL_RPATH + - BUNDLE_EXTENSION + - BUNDLE + - C_EXTENSIONS + - C_STANDARD + - C_STANDARD_REQUIRED + - COMMON_LANGUAGE_RUNTIME # Sine 3.12 + - COMPATIBLE_INTERFACE_BOOL + - COMPATIBLE_INTERFACE_NUMBER_MAX + - COMPATIBLE_INTERFACE_NUMBER_MIN + - COMPATIBLE_INTERFACE_STRING + - COMPILE_DEFINITIONS + - COMPILE_FEATURES + - COMPILE_FLAGS + - COMPILE_OPTIONS + - COMPILE_PDB_NAME + - COMPILE_PDB_NAME_<CONFIG> + - COMPILE_PDB_OUTPUT_DIRECTORY + - COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG> + - <CONFIG>_OUTPUT_NAME + - <CONFIG>_POSTFIX + - CROSSCOMPILING_EMULATOR + - CUDA_PTX_COMPILATION + - CUDA_SEPARABLE_COMPILATION + - CUDA_RESOLVE_DEVICE_SYMBOLS + - CUDA_EXTENSIONS + - CUDA_STANDARD + - CUDA_STANDARD_REQUIRED + - CXX_EXTENSIONS + - CXX_STANDARD + - CXX_STANDARD_REQUIRED + # - DEBUG_POSTFIX # NOTE: Handled by `<CONFIG>_POSTFIX` + - DEFINE_SYMBOL + - DEPLOYMENT_ADDITIONAL_FILES # Since 3.13 + - DEPLOYMENT_REMOTE_DIRECTORY + - DOTNET_TARGET_FRAMEWORK_VERSION # Since 3.12 + - EchoString + - ENABLE_EXPORTS + - EXCLUDE_FROM_ALL + - EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG> + - EXCLUDE_FROM_DEFAULT_BUILD + - EXPORT_NAME + - EXPORT_PROPERTIES # Since 3.12 + - FOLDER + - Fortran_FORMAT + - Fortran_MODULE_DIRECTORY + - FRAMEWORK + - FRAMEWORK_VERSION + - GENERATOR_FILE_NAME + - GNUtoMS + - HAS_CXX + - IMPLICIT_DEPENDS_INCLUDE_TRANSFORM + - IMPORTED_COMMON_LANGUAGE_RUNTIME # Since 3.12 + - IMPORTED_CONFIGURATIONS + - IMPORTED_GLOBAL # Since 3.11 + - IMPORTED_IMPLIB_<CONFIG> + - IMPORTED_IMPLIB + - IMPORTED_LIBNAME_<CONFIG> + - IMPORTED_LIBNAME + - IMPORTED_LINK_DEPENDENT_LIBRARIES_<CONFIG> + - IMPORTED_LINK_DEPENDENT_LIBRARIES + - IMPORTED_LINK_INTERFACE_LANGUAGES_<CONFIG> + - IMPORTED_LINK_INTERFACE_LANGUAGES + - IMPORTED_LINK_INTERFACE_LIBRARIES_<CONFIG> + - IMPORTED_LINK_INTERFACE_LIBRARIES + - IMPORTED_LINK_INTERFACE_MULTIPLICITY_<CONFIG> + - IMPORTED_LINK_INTERFACE_MULTIPLICITY + - IMPORTED_LOCATION_<CONFIG> + - IMPORTED_LOCATION + - IMPORTED_NO_SONAME_<CONFIG> + - IMPORTED_NO_SONAME + - IMPORTED_OBJECTS_<CONFIG> + - IMPORTED_OBJECTS + - IMPORTED + - IMPORTED_SONAME_<CONFIG> + - IMPORTED_SONAME + - IMPORT_PREFIX + - IMPORT_SUFFIX + - INCLUDE_DIRECTORIES + - INSTALL_NAME_DIR + - INSTALL_RPATH + - INSTALL_RPATH_USE_LINK_PATH + - INTERFACE_AUTOUIC_OPTIONS + - INTERFACE_COMPILE_DEFINITIONS + - INTERFACE_COMPILE_FEATURES + - INTERFACE_COMPILE_OPTIONS + - INTERFACE_INCLUDE_DIRECTORIES + - INTERFACE_LINK_DEPENDS # Since 3.13 + - INTERFACE_LINK_DIRECTORIES # Since 3.13 + - INTERFACE_LINK_LIBRARIES + - INTERFACE_LINK_OPTIONS # Since 3.13 + - INTERFACE_POSITION_INDEPENDENT_CODE + - INTERFACE_SOURCES + - INTERFACE_SYSTEM_INCLUDE_DIRECTORIES + - INTERPROCEDURAL_OPTIMIZATION_<CONFIG> + - INTERPROCEDURAL_OPTIMIZATION + - IOS_INSTALL_COMBINED + - JOB_POOL_COMPILE + - JOB_POOL_LINK + - LABELS + - <LANG>_CLANG_TIDY + - <LANG>_COMPILER_LAUNCHER + - <LANG>_CPPCHECK # Since 3.10 + - <LANG>_CPPLINT + - <LANG>_INCLUDE_WHAT_YOU_USE + - <LANG>_VISIBILITY_PRESET + - LIBRARY_OUTPUT_DIRECTORY_<CONFIG> + - LIBRARY_OUTPUT_DIRECTORY + - LIBRARY_OUTPUT_NAME_<CONFIG> + - LIBRARY_OUTPUT_NAME + - LINK_DEPENDS_NO_SHARED + - LINK_DEPENDS + - LINK_DIRECTORIES # Since 3.13 + - LINKER_LANGUAGE + - LINK_FLAGS_<CONFIG> + - LINK_FLAGS + - LINK_INTERFACE_LIBRARIES_<CONFIG> + - LINK_INTERFACE_LIBRARIES + - LINK_INTERFACE_MULTIPLICITY_<CONFIG> + - LINK_INTERFACE_MULTIPLICITY + - LINK_LIBRARIES + - LINK_OPTIONS # Since 3.13 + - LINK_SEARCH_END_STATIC + - LINK_SEARCH_START_STATIC + - LINK_WHAT_YOU_USE + - LOCATION_<CONFIG> + - LOCATION + - MACOSX_BUNDLE_INFO_PLIST + - MACOSX_BUNDLE + - MACOSX_FRAMEWORK_INFO_PLIST + - MACOSX_RPATH + - MANUALLY_ADDED_DEPENDENCIES + - MAP_IMPORTED_CONFIG_<CONFIG> + - NAME + - NO_SONAME + - NO_SYSTEM_FROM_IMPORTED + - OSX_ARCHITECTURES_<CONFIG> + - OSX_ARCHITECTURES + - OUTPUT_NAME_<CONFIG> + - OUTPUT_NAME + - PDB_NAME_<CONFIG> + - PDB_NAME + - PDB_OUTPUT_DIRECTORY_<CONFIG> + - PDB_OUTPUT_DIRECTORY + - POSITION_INDEPENDENT_CODE + - PREFIX + - PRIVATE_HEADER + - PROJECT_LABEL + - PUBLIC_HEADER + - RESOURCE + - RULE_LAUNCH_COMPILE + - RULE_LAUNCH_CUSTOM + - RULE_LAUNCH_LINK + - RUNTIME_OUTPUT_DIRECTORY_<CONFIG> + - RUNTIME_OUTPUT_DIRECTORY + - RUNTIME_OUTPUT_NAME_<CONFIG> + - RUNTIME_OUTPUT_NAME + - SKIP_BUILD_RPATH + - SOURCE_DIR + - SOURCES + - SOVERSION + - STATIC_LIBRARY_FLAGS_<CONFIG> + - STATIC_LIBRARY_FLAGS + - STATIC_LIBRARY_OPTIONS # Since 3.13 + - SUFFIX + - TYPE + - VERSION + - VISIBILITY_INLINES_HIDDEN + - VS_CONFIGURATION_TYPE + - VS_DEBUGGER_COMMAND # Since 3.12 + - VS_DEBUGGER_COMMAND_ARGUMENTS # Since 3.13 + - VS_DEBUGGER_ENVIRONMENT # Since 3.13 + - VS_DEBUGGER_WORKING_DIRECTORY + - VS_DESKTOP_EXTENSIONS_VERSION + - VS_DOTNET_REFERENCE_<refname> + - VS_DOTNET_REFERENCEPROP_<refname>_TAG_<tagname> # Since 3.10 + - VS_DOTNET_REFERENCES + - VS_DOTNET_REFERENCES_COPY_LOCAL + - VS_DOTNET_TARGET_FRAMEWORK_VERSION + - VS_GLOBAL_KEYWORD + - VS_GLOBAL_PROJECT_TYPES + - VS_GLOBAL_ROOTNAMESPACE + - VS_GLOBAL_<variable> + - VS_IOT_EXTENSIONS_VERSION + - VS_IOT_STARTUP_TASK + - VS_KEYWORD + - VS_MOBILE_EXTENSIONS_VERSION + - VS_SCC_AUXPATH + - VS_SCC_LOCALPATH + - VS_SCC_PROJECTNAME + - VS_SCC_PROVIDER + - VS_SDK_REFERENCES + - VS_USER_PROPS + - VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION + - VS_WINRT_COMPONENT + - VS_WINRT_EXTENSIONS + - VS_WINRT_REFERENCES + - WIN32_EXECUTABLE + - WINDOWS_EXPORT_ALL_SYMBOLS + - XCODE_ATTRIBUTE_<an-attribute> + - XCODE_EXPLICIT_FILE_TYPE + - XCODE_PRODUCT_TYPE + - XCODE_SCHEME_ADDRESS_SANITIZER # Since 3.13 + - XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN # Since 3.13 + - XCODE_SCHEME_THREAD_SANITIZER # Since 3.13 + - XCODE_SCHEME_THREAD_SANITIZER_STOP # Since 3.13 + - XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER # Since 3.13 + - XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP # Since 3.13 + - XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER # Since 3.13 + - XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP # Since 3.13 + - XCODE_SCHEME_MALLOC_SCRIBBLE # Since 3.13 + - XCODE_SCHEME_MALLOC_GUARD_EDGES # Since 3.13 + - XCODE_SCHEME_GUARD_MALLOC # Since 3.13 + - XCODE_SCHEME_ZOMBIE_OBJECTS # Since 3.13 + - XCODE_SCHEME_MALLOC_STACK # Since 3.13 + - XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE # Since 3.13 + - XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS # Since 3.13 + - XCODE_SCHEME_EXECUTABLE # Since 3.13 + - XCODE_SCHEME_ARGUMENTS # Since 3.13 + - XCODE_SCHEME_ENVIRONMENT # Since 3.13 + - XCTEST + +test-properties: + - ATTACHED_FILES_ON_FAIL + - ATTACHED_FILES + - COST + - DEPENDS + - DISABLED + - ENVIRONMENT + - FAIL_REGULAR_EXPRESSION + - FIXTURES_CLEANUP + - FIXTURES_REQUIRED + - FIXTURES_SETUP + - LABELS + - MEASUREMENT + - PASS_REGULAR_EXPRESSION + - PROCESSOR_AFFINITY # Since 3.12 + - PROCESSORS + - REQUIRED_FILES + - RESOURCE_LOCK + - RUN_SERIAL + - SKIP_RETURN_CODE + - TIMEOUT + - TIMEOUT_AFTER_MATCH + - WILL_FAIL + - WORKING_DIRECTORY + +source-properties: + - ABSTRACT + - AUTOUIC_OPTIONS + - AUTORCC_OPTIONS + - COMPILE_DEFINITIONS + - COMPILE_FLAGS + - COMPILE_OPTIONS # Since 3.11 + - EXTERNAL_OBJECT + - Fortran_FORMAT + - GENERATED + - HEADER_FILE_ONLY + - INCLUDE_DIRECTORIES # Since 3.11 + - KEEP_EXTENSION + - LABELS + - LANGUAGE + - LOCATION + - MACOSX_PACKAGE_LOCATION + - OBJECT_DEPENDS + - OBJECT_OUTPUTS + - SKIP_AUTOGEN + - SKIP_AUTOMOC + - SKIP_AUTORCC + - SKIP_AUTOUIC + - SYMBOLIC + - VS_COPY_TO_OUT_DIR + - VS_CSHARP_<tagname> + - VS_DEPLOYMENT_CONTENT + - VS_DEPLOYMENT_LOCATION + - VS_INCLUDE_IN_VSIX + - VS_RESOURCE_GENERATOR + - VS_SHADER_DISABLE_OPTIMIZATIONS # Since 3.11 + - VS_SHADER_ENABLE_DEBUG # Since 3.11 + - VS_SHADER_ENTRYPOINT + - VS_SHADER_FLAGS + - VS_SHADER_MODEL + - VS_SHADER_OBJECT_FILE_NAME # Since 3.12 + - VS_SHADER_OUTPUT_HEADER_FILE # Since 3.10 + - VS_SHADER_TYPE + - VS_SHADER_VARIABLE_NAME # Since 3.10 + - VS_TOOL_OVERRIDE + - VS_XAML_TYPE + - WRAP_EXCLUDE + - XCODE_EXPLICIT_FILE_TYPE + - XCODE_FILE_ATTRIBUTES + - XCODE_LAST_KNOWN_FILE_TYPE + +cache-properties: + - ADVANCED + - HELPSTRING + - MODIFIED + - STRINGS + - TYPE + - VALUE + +install-properties: + - CPACK_DESKTOP_SHORTCUTS + - CPACK_NEVER_OVERWRITE + - CPACK_PERMANENT + - CPACK_START_MENU_SHORTCUTS + - CPACK_STARTUP_SHORTCUTS + - CPACK_WIX_ACL + +generator-expressions: + - 0 + - 1 + - AND + - ANGLE-R + - BOOL + - BUILD_INTERFACE + - COMMA + - COMPILE_FEATURES + - COMPILE_LANGUAGE + - CONFIG + - CXX_COMPILER_ID + - CXX_COMPILER_VERSION + - C_COMPILER_ID + - C_COMPILER_VERSION + - EQUAL + - GENEX_EVAL # Since 3.12 + - IF + - INSTALL_INTERFACE + - INSTALL_PREFIX + - IN_LIST # Since 3.12 + - JOIN + - LINK_ONLY + - LOWER_CASE + - MAKE_C_IDENTIFIER + - NOT + - OR + - PLATFORM_ID + - SEMICOLON + - SHELL_PATH + - STREQUAL + - TARGET_BUNDLE_CONTENT_DIR + - TARGET_BUNDLE_DIR + - TARGET_EXISTS # Since 3.12 + - TARGET_FILE + - TARGET_FILE_DIR + - TARGET_FILE_NAME + - TARGET_GENEX_EVAL # Since 3.12 + - TARGET_LINKER_FILE + - TARGET_LINKER_FILE_DIR + - TARGET_LINKER_FILE_NAME + - TARGET_NAME + - TARGET_NAME_IF_EXISTS # Since 3.12 + - TARGET_OBJECTS + - TARGET_PDB_FILE + - TARGET_PDB_FILE_DIR + - TARGET_PDB_FILE_NAME + - TARGET_POLICY + - TARGET_PROPERTY + - TARGET_SONAME_FILE + - TARGET_SONAME_FILE_DIR + - TARGET_SONAME_FILE_NAME + - UPPER_CASE + - VERSION_EQUAL + - VERSION_GREATER + - VERSION_GREATER_EQUAL + - VERSION_LESS + - VERSION_LESS_EQUAL + +variables: + # Variables that Provide Information + - CMAKE_AR + - CMAKE_ARGC + - CMAKE_ARGV0 + - CMAKE_BINARY_DIR + - CMAKE_BUILD_TOOL + - CMAKE_CACHEFILE_DIR + - CMAKE_CACHE_MAJOR_VERSION + - CMAKE_CACHE_MINOR_VERSION + - CMAKE_CACHE_PATCH_VERSION + - CMAKE_CFG_INTDIR + - CMAKE_COMMAND + - CMAKE_CROSSCOMPILING + - CMAKE_CROSSCOMPILING_EMULATOR + - CMAKE_CTEST_COMMAND + - CMAKE_CURRENT_BINARY_DIR + - CMAKE_CURRENT_LIST_DIR + - CMAKE_CURRENT_LIST_FILE + - CMAKE_CURRENT_LIST_LINE + - CMAKE_CURRENT_SOURCE_DIR + - CMAKE_DIRECTORY_LABELS # Since 3.10 + - CMAKE_DL_LIBS + - CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION # Since 3.12 + - CMAKE_EDIT_COMMAND + - CMAKE_EXECUTABLE_SUFFIX + - CMAKE_EXTRA_GENERATOR + - CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES + - CMAKE_FIND_PACKAGE_NAME + - CMAKE_FIND_PACKAGE_SORT_DIRECTION + - CMAKE_FIND_PACKAGE_SORT_ORDER + - CMAKE_GENERATOR + - CMAKE_GENERATOR_INSTANCE # Since 3.11 + - CMAKE_GENERATOR_PLATFORM + - CMAKE_GENERATOR_TOOLSET + - CMAKE_HOME_DIRECTORY + - CMAKE_IMPORT_LIBRARY_PREFIX + - CMAKE_IMPORT_LIBRARY_SUFFIX + - CMAKE_JOB_POOL_COMPILE + - CMAKE_JOB_POOL_LINK + - CMAKE_JOB_POOLS # Since 3.11 + - CMAKE_<LANG>_COMPILER_AR + - CMAKE_<LANG>_COMPILER_RANLIB + - CMAKE_LINK_LIBRARY_SUFFIX + - CMAKE_LINK_SEARCH_END_STATIC + - CMAKE_LINK_SEARCH_START_STATIC + - CMAKE_MAJOR_VERSION + - CMAKE_MAKE_PROGRAM + - CMAKE_MATCH_COUNT + - CMAKE_MATCH_<n> + - CMAKE_MINIMUM_REQUIRED_VERSION + - CMAKE_MINOR_VERSION + - CMAKE_NETRC # Since 3.11 + - CMAKE_NETRC_FILE # Since 3.11 + - CMAKE_PARENT_LIST_FILE + - CMAKE_PATCH_VERSION + - CMAKE_PROJECT_DESCRIPTION + - CMAKE_PROJECT_HOMEPAGE_URL # Since 3.12 + - CMAKE_PROJECT_NAME + - CMAKE_PROJECT_VERSION # Since 3.12 + - CMAKE_PROJECT_VERSION_MAJOR # Since 3.12 + - CMAKE_PROJECT_VERSION_MINOR # Since 3.12 + - CMAKE_PROJECT_VERSION_PATCH # Since 3.12 + - CMAKE_PROJECT_VERSION_TWEAK # Since 3.12 + - CMAKE_RANLIB + - CMAKE_ROOT + - CMAKE_SCRIPT_MODE_FILE + - CMAKE_SHARED_LIBRARY_PREFIX + - CMAKE_SHARED_LIBRARY_SUFFIX + - CMAKE_SHARED_MODULE_PREFIX + - CMAKE_SHARED_MODULE_SUFFIX + - CMAKE_SIZEOF_VOID_P + - CMAKE_SKIP_INSTALL_RULES + - CMAKE_SKIP_RPATH + - CMAKE_SOURCE_DIR + - CMAKE_STATIC_LIBRARY_PREFIX + - CMAKE_STATIC_LIBRARY_SUFFIX + - CMAKE_TOOLCHAIN_FILE + - CMAKE_TWEAK_VERSION + - CMAKE_VERBOSE_MAKEFILE + - CMAKE_VERSION + - CMAKE_VS_DEVENV_COMMAND + - CMAKE_VS_INTEL_Fortran_PROJECT_VERSION + - CMAKE_VS_MSBUILD_COMMAND + - CMAKE_VS_NsightTegra_VERSION + - CMAKE_VS_PLATFORM_NAME + - CMAKE_VS_PLATFORM_TOOLSET + - CMAKE_VS_PLATFORM_TOOLSET_CUDA + - CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE + - CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION + - CMAKE_XCODE_GENERATE_SCHEME + - CMAKE_XCODE_PLATFORM_TOOLSET + - <PROJECT-NAME>_BINARY_DIR + - <PROJECT-NAME>_SOURCE_DIR + - <PROJECT-NAME>_VERSION + - <PROJECT-NAME>_VERSION_MAJOR + - <PROJECT-NAME>_VERSION_MINOR + - <PROJECT-NAME>_VERSION_PATCH + - <PROJECT-NAME>_VERSION_TWEAK + - PROJECT_BINARY_DIR + - PROJECT_DESCRIPTION + - PROJECT_HOMEPAGE_URL # Since 3.12 + - PROJECT_NAME + - PROJECT_SOURCE_DIR + - PROJECT_VERSION + - PROJECT_VERSION_MAJOR + - PROJECT_VERSION_MINOR + - PROJECT_VERSION_PATCH + - PROJECT_VERSION_TWEAK + # Variables that Change Behavior + - BUILD_SHARED_LIBS + - CMAKE_ABSOLUTE_DESTINATION_FILES + - CMAKE_APPBUNDLE_PATH + - CMAKE_AUTOMOC_RELAXED_MODE + - CMAKE_BACKWARDS_COMPATIBILITY + - CMAKE_BUILD_TYPE + - CMAKE_CODEBLOCKS_COMPILER_ID # Since 3.11 + - CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES # Since 3.10 + - CMAKE_CODELITE_USE_TARGETS + - CMAKE_COLOR_MAKEFILE + - CMAKE_CONFIGURATION_TYPES + - CMAKE_DEBUG_TARGET_PROPERTIES + - CMAKE_DEPENDS_IN_PROJECT_ONLY + - CMAKE_DISABLE_FIND_PACKAGE_<PackageName> + - CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES + - CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT + - CMAKE_ECLIPSE_MAKE_ARGUMENTS + - CMAKE_ECLIPSE_VERSION + - CMAKE_ERROR_DEPRECATED + - CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION + - CMAKE_EXPORT_COMPILE_COMMANDS + - CMAKE_EXPORT_NO_PACKAGE_REGISTRY + - CMAKE_FIND_APPBUNDLE + - CMAKE_FIND_FRAMEWORK + - CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX + - CMAKE_FIND_LIBRARY_PREFIXES + - CMAKE_FIND_LIBRARY_SUFFIXES + - CMAKE_FIND_NO_INSTALL_PREFIX + - CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY + - CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY + - CMAKE_FIND_PACKAGE_WARN_NO_MODULE + - CMAKE_FIND_ROOT_PATH + - CMAKE_FIND_ROOT_PATH_MODE_INCLUDE + - CMAKE_FIND_ROOT_PATH_MODE_LIBRARY + - CMAKE_FIND_ROOT_PATH_MODE_PACKAGE + - CMAKE_FIND_ROOT_PATH_MODE_PROGRAM + - CMAKE_FRAMEWORK_PATH + - CMAKE_IGNORE_PATH + - CMAKE_INCLUDE_DIRECTORIES_BEFORE + - CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE + - CMAKE_INCLUDE_PATH + - CMAKE_INSTALL_DEFAULT_COMPONENT_NAME + - CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS # Since 3.11 + - CMAKE_INSTALL_MESSAGE + - CMAKE_INSTALL_PREFIX + - CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT + - CMAKE_LIBRARY_PATH + - CMAKE_LINK_DIRECTORIES_BEFORE # Since 3.13 + - CMAKE_MFC_FLAG + - CMAKE_MODULE_PATH + - CMAKE_NOT_USING_CONFIG_FLAGS + - CMAKE_POLICY_DEFAULT_CMP<NNNN> + - CMAKE_POLICY_WARNING_CMP<NNNN> + - CMAKE_PREFIX_PATH + - CMAKE_PROGRAM_PATH + - CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE + - CMAKE_SKIP_INSTALL_ALL_DEPENDENCY + - CMAKE_STAGING_PREFIX + - CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS + - CMAKE_SUBLIME_TEXT_2_EXCLUDE_BUILD_TREE + - CMAKE_SUPPRESS_REGENERATION # Since 3.12 + - CMAKE_SYSROOT + - CMAKE_SYSROOT_COMPILE + - CMAKE_SYSROOT_LINK + - CMAKE_SYSTEM_APPBUNDLE_PATH + - CMAKE_SYSTEM_FRAMEWORK_PATH + - CMAKE_SYSTEM_IGNORE_PATH + - CMAKE_SYSTEM_INCLUDE_PATH + - CMAKE_SYSTEM_LIBRARY_PATH + - CMAKE_SYSTEM_PREFIX_PATH + - CMAKE_SYSTEM_PROGRAM_PATH + - CMAKE_USER_MAKE_RULES_OVERRIDE + - CMAKE_WARN_DEPRECATED + - CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION + - CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY # Since 3.13 + - CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER # Since 3.13 + - CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN # Since 3.13 + - CMAKE_XCODE_SCHEME_THREAD_SANITIZER # Since 3.13 + - CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP # Since 3.13 + - CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER # Since 3.13 + - CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP # Since 3.13 + - CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER # Since 3.13 + - CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP # Since 3.13 + - CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE # Since 3.13 + - CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES # Since 3.13 + - CMAKE_XCODE_SCHEME_GUARD_MALLOC # Since 3.13 + - CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS # Since 3.13 + - CMAKE_XCODE_SCHEME_MALLOC_STACK # Since 3.13 + - CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE # Since 3.13 + - CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS # Since 3.13 + - CMAKE_SUPPRESS_DEVELOPER_WARNINGS # Undocumented yet (CMake <= 3.10) + - CMAKE_SUPPRESS_DEVELOPER_ERRORS # Undocumented yet (CMake <= 3.10) + # Variables that Describe the System + - ANDROID + - APPLE + - BORLAND + - CMAKE_CL_64 + - CMAKE_COMPILER_2005 + - CMAKE_HOST_APPLE + - CMAKE_HOST_SOLARIS + - CMAKE_HOST_SYSTEM + - CMAKE_HOST_SYSTEM_NAME + - CMAKE_HOST_SYSTEM_PROCESSOR + - CMAKE_HOST_SYSTEM_VERSION + - CMAKE_HOST_UNIX + - CMAKE_HOST_WIN32 + - CMAKE_LIBRARY_ARCHITECTURE + - CMAKE_LIBRARY_ARCHITECTURE_REGEX + - CMAKE_OBJECT_PATH_MAX + - CMAKE_SYSTEM + - CMAKE_SYSTEM_NAME + - CMAKE_SYSTEM_PROCESSOR + - CMAKE_SYSTEM_VERSION + - CYGWIN + # NOTE `ENV` not a variable in fact! + # - ENV + - GHS-MULTI + - MINGW + - MSVC + - MSVC10 + - MSVC11 + - MSVC12 + - MSVC14 + - MSVC60 + - MSVC70 + - MSVC71 + - MSVC80 + - MSVC90 + - MSVC_IDE + - MSVC_TOOLSET_VERSION # Since 3.12 + - MSVC_VERSION + - UNIX + - WIN32 + - WINCE + - WINDOWS_PHONE + - WINDOWS_STORE + - XCODE + - XCODE_VERSION + # Variables that Control the Build + - CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS + - CMAKE_ANDROID_API + - CMAKE_ANDROID_API_MIN + - CMAKE_ANDROID_ARCH + - CMAKE_ANDROID_ARCH_ABI + - CMAKE_ANDROID_ARM_MODE + - CMAKE_ANDROID_ARM_NEON + - CMAKE_ANDROID_ASSETS_DIRECTORIES + - CMAKE_ANDROID_GUI + - CMAKE_ANDROID_JAR_DEPENDENCIES + - CMAKE_ANDROID_JAR_DIRECTORIES + - CMAKE_ANDROID_JAVA_SOURCE_DIR + - CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES + - CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES + - CMAKE_ANDROID_NDK + - CMAKE_ANDROID_NDK_DEPRECATED_HEADERS + - CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG + - CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION + - CMAKE_ANDROID_PROCESS_MAX + - CMAKE_ANDROID_PROGUARD + - CMAKE_ANDROID_PROGUARD_CONFIG_PATH + - CMAKE_ANDROID_SECURE_PROPS_PATH + - CMAKE_ANDROID_SKIP_ANT_STEP + - CMAKE_ANDROID_STANDALONE_TOOLCHAIN + - CMAKE_ANDROID_STL_TYPE + - CMAKE_ARCHIVE_OUTPUT_DIRECTORY + - CMAKE_ARCHIVE_OUTPUT_DIRECTORY_<CONFIG> + - CMAKE_AUTOGEN_PARALLEL + - CMAKE_AUTOGEN_VERBOSE # Since 3.13 + - CMAKE_AUTOMOC + - CMAKE_AUTOMOC_DEPEND_FILTERS + - CMAKE_AUTOMOC_MOC_OPTIONS + - CMAKE_AUTORCC + - CMAKE_AUTORCC_OPTIONS + - CMAKE_AUTOUIC + - CMAKE_AUTOUIC_OPTIONS + - CMAKE_AUTOUIC_SEARCH_PATHS + - CMAKE_BUILD_RPATH + - CMAKE_BUILD_WITH_INSTALL_NAME_DIR + - CMAKE_BUILD_WITH_INSTALL_RPATH + - CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY + - CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG> + - CMAKE_<CONFIG>_POSTFIX + - CMAKE_CUDA_SEPARABLE_COMPILATION # Since 3.11 + - CMAKE_DEBUG_POSTFIX + - CMAKE_ENABLE_EXPORTS + - CMAKE_EXE_LINKER_FLAGS + - CMAKE_EXE_LINKER_FLAGS_<CONFIG> + - CMAKE_EXE_LINKER_FLAGS_<CONFIG>_INIT + - CMAKE_EXE_LINKER_FLAGS_INIT + - CMAKE_FOLDER # Since 3.12 + - CMAKE_Fortran_FORMAT + - CMAKE_Fortran_MODULE_DIRECTORY + - CMAKE_GNUtoMS + - CMAKE_INCLUDE_CURRENT_DIR + - CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE + - CMAKE_INSTALL_NAME_DIR + - CMAKE_INSTALL_RPATH + - CMAKE_INSTALL_RPATH_USE_LINK_PATH + - CMAKE_INTERPROCEDURAL_OPTIMIZATION + - CMAKE_INTERPROCEDURAL_OPTIMIZATION_<CONFIG> + - CMAKE_IOS_INSTALL_COMBINED + - CMAKE_<LANG>_CLANG_TIDY + - CMAKE_<LANG>_COMPILER_LAUNCHER + - CMAKE_<LANG>_CPPCHECK # Since 3.10 + - CMAKE_<LANG>_CPPLINT + - CMAKE_<LANG>_INCLUDE_WHAT_YOU_USE + - CMAKE_<LANG>_VISIBILITY_PRESET + - CMAKE_LIBRARY_OUTPUT_DIRECTORY + - CMAKE_LIBRARY_OUTPUT_DIRECTORY_<CONFIG> + - CMAKE_LIBRARY_PATH_FLAG + - CMAKE_LINK_DEF_FILE_FLAG + - CMAKE_LINK_DEPENDS_NO_SHARED + - CMAKE_LINK_INTERFACE_LIBRARIES + - CMAKE_LINK_LIBRARY_FILE_FLAG + - CMAKE_LINK_LIBRARY_FLAG + - CMAKE_LINK_WHAT_YOU_USE + - CMAKE_MACOSX_BUNDLE + - CMAKE_MACOSX_RPATH + - CMAKE_MAP_IMPORTED_CONFIG_<CONFIG> + - CMAKE_MODULE_LINKER_FLAGS + - CMAKE_MODULE_LINKER_FLAGS_<CONFIG> + - CMAKE_MODULE_LINKER_FLAGS_<CONFIG>_INIT + - CMAKE_MODULE_LINKER_FLAGS_INIT + - CMAKE_NINJA_OUTPUT_PATH_PREFIX + - CMAKE_NO_BUILTIN_CHRPATH + - CMAKE_NO_SYSTEM_FROM_IMPORTED + - CMAKE_OSX_ARCHITECTURES + - CMAKE_OSX_DEPLOYMENT_TARGET + - CMAKE_OSX_SYSROOT + - CMAKE_PDB_OUTPUT_DIRECTORY + - CMAKE_PDB_OUTPUT_DIRECTORY_<CONFIG> + - CMAKE_POSITION_INDEPENDENT_CODE + - CMAKE_RUNTIME_OUTPUT_DIRECTORY + - CMAKE_RUNTIME_OUTPUT_DIRECTORY_<CONFIG> + - CMAKE_SHARED_LINKER_FLAGS + - CMAKE_SHARED_LINKER_FLAGS_<CONFIG> + - CMAKE_SHARED_LINKER_FLAGS_<CONFIG>_INIT + - CMAKE_SHARED_LINKER_FLAGS_INIT + - CMAKE_SKIP_BUILD_RPATH + - CMAKE_SKIP_INSTALL_RPATH + - CMAKE_STATIC_LINKER_FLAGS + - CMAKE_STATIC_LINKER_FLAGS_<CONFIG> + - CMAKE_STATIC_LINKER_FLAGS_<CONFIG>_INIT + - CMAKE_STATIC_LINKER_FLAGS_INIT + - CMAKE_TRY_COMPILE_CONFIGURATION + - CMAKE_TRY_COMPILE_PLATFORM_VARIABLES + - CMAKE_TRY_COMPILE_TARGET_TYPE + - CMAKE_USE_RELATIVE_PATHS + - CMAKE_VISIBILITY_INLINES_HIDDEN + - CMAKE_VS_GLOBALS # Since 3.13 + - CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD + - CMAKE_VS_INCLUDE_PACKAGE_TO_DEFAULT_BUILD + - CMAKE_VS_SDK_EXCLUDE_DIRECTORIES # Since 3.12 + - CMAKE_VS_SDK_EXECUTABLE_DIRECTORIES # Since 3.12 + - CMAKE_VS_SDK_INCLUDE_DIRECTORIES # Since 3.12 + - CMAKE_VS_SDK_LIBRARY_DIRECTORIES # Since 3.12 + - CMAKE_VS_SDK_LIBRARY_WINRT_DIRECTORIES # Since 3.12 + - CMAKE_VS_SDK_REFERENCE_DIRECTORIES # Since 3.12 + - CMAKE_VS_SDK_SOURCE_DIRECTORIES # Since 3.12 + - CMAKE_WIN32_EXECUTABLE + - CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS + - CMAKE_XCODE_ATTRIBUTE_<an-attribute> + - EXECUTABLE_OUTPUT_PATH + - LIBRARY_OUTPUT_PATH + # Variables for Languages + - CMAKE_COMPILER_IS_GNUCC + - CMAKE_COMPILER_IS_GNUCXX + - CMAKE_COMPILER_IS_GNUG77 + - CMAKE_CUDA_EXTENSIONS + - CMAKE_CUDA_STANDARD + - CMAKE_CUDA_STANDARD_REQUIRED + - CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES + - CMAKE_CXX_COMPILE_FEATURES + - CMAKE_CXX_EXTENSIONS + - CMAKE_CXX_STANDARD + - CMAKE_CXX_STANDARD_REQUIRED + - CMAKE_C_COMPILE_FEATURES + - CMAKE_C_EXTENSIONS + - CMAKE_C_STANDARD + - CMAKE_C_STANDARD_REQUIRED + - CMAKE_Fortran_MODDIR_DEFAULT + - CMAKE_Fortran_MODDIR_FLAG + - CMAKE_Fortran_MODOUT_FLAG + - CMAKE_INTERNAL_PLATFORM_ABI + - CMAKE_<LANG>_ANDROID_TOOLCHAIN_MACHINE + - CMAKE_<LANG>_ANDROID_TOOLCHAIN_PREFIX + - CMAKE_<LANG>_ANDROID_TOOLCHAIN_SUFFIX + - CMAKE_<LANG>_ARCHIVE_APPEND + - CMAKE_<LANG>_ARCHIVE_CREATE + - CMAKE_<LANG>_ARCHIVE_FINISH + - CMAKE_<LANG>_COMPILER + - CMAKE_<LANG>_COMPILER_ABI + - CMAKE_<LANG>_COMPILER_EXTERNAL_TOOLCHAIN + - CMAKE_<LANG>_COMPILER_ID + - CMAKE_<LANG>_COMPILER_LOADED + - CMAKE_<LANG>_COMPILER_TARGET + - CMAKE_<LANG>_COMPILER_VERSION + - CMAKE_<LANG>_COMPILE_OBJECT + - CMAKE_<LANG>_CREATE_SHARED_LIBRARY + - CMAKE_<LANG>_CREATE_SHARED_MODULE + - CMAKE_<LANG>_CREATE_STATIC_LIBRARY + - CMAKE_<LANG>_FLAGS + - CMAKE_<LANG>_FLAGS_DEBUG + - CMAKE_<LANG>_FLAGS_DEBUG_INIT + - CMAKE_<LANG>_FLAGS_INIT + - CMAKE_<LANG>_FLAGS_MINSIZEREL + - CMAKE_<LANG>_FLAGS_MINSIZEREL_INIT + - CMAKE_<LANG>_FLAGS_RELEASE + - CMAKE_<LANG>_FLAGS_RELEASE_INIT + - CMAKE_<LANG>_FLAGS_RELWITHDEBINFO + - CMAKE_<LANG>_FLAGS_RELWITHDEBINFO_INIT + - CMAKE_<LANG>_GHS_KERNEL_FLAGS_DEBUG + - CMAKE_<LANG>_GHS_KERNEL_FLAGS_MINSIZEREL + - CMAKE_<LANG>_GHS_KERNEL_FLAGS_RELEASE + - CMAKE_<LANG>_GHS_KERNEL_FLAGS_RELWITHDEBINFO + - CMAKE_<LANG>_IGNORE_EXTENSIONS + - CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES + - CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES + - CMAKE_<LANG>_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES + - CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES + - CMAKE_<LANG>_LIBRARY_ARCHITECTURE + - CMAKE_<LANG>_LINKER_PREFERENCE + - CMAKE_<LANG>_LINKER_PREFERENCE_PROPAGATES + - CMAKE_<LANG>_LINKER_WRAPPER_FLAG # Since 3.13 + - CMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP # Since 3.13 + - CMAKE_<LANG>_LINK_EXECUTABLE + - CMAKE_<LANG>_OUTPUT_EXTENSION + - CMAKE_<LANG>_PLATFORM_ID + - CMAKE_<LANG>_SIMULATE_ID + - CMAKE_<LANG>_SIMULATE_VERSION + - CMAKE_<LANG>_SIZEOF_DATA_PTR + - CMAKE_<LANG>_SOURCE_FILE_EXTENSIONS + - CMAKE_<LANG>_STANDARD_INCLUDE_DIRECTORIES + - CMAKE_<LANG>_STANDARD_LIBRARIES + - CMAKE_Swift_LANGUAGE_VERSION + - CMAKE_USER_MAKE_RULES_OVERRIDE_<LANG> + # Variables for CTest + - CTEST_BINARY_DIRECTORY + - CTEST_BUILD_COMMAND + - CTEST_BUILD_NAME + - CTEST_BZR_COMMAND + - CTEST_BZR_UPDATE_OPTIONS + - CTEST_CHANGE_ID + - CTEST_CHECKOUT_COMMAND + - CTEST_CONFIGURATION_TYPE + - CTEST_CONFIGURE_COMMAND + - CTEST_COVERAGE_COMMAND + - CTEST_COVERAGE_EXTRA_FLAGS + - CTEST_CURL_OPTIONS + - CTEST_CUSTOM_COVERAGE_EXCLUDE + - CTEST_CUSTOM_ERROR_EXCEPTION + - CTEST_CUSTOM_ERROR_MATCH + - CTEST_CUSTOM_ERROR_POST_CONTEXT + - CTEST_CUSTOM_ERROR_PRE_CONTEXT + - CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE + - CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS + - CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS + - CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE + - CTEST_CUSTOM_MEMCHECK_IGNORE + - CTEST_CUSTOM_POST_MEMCHECK + - CTEST_CUSTOM_POST_TEST + - CTEST_CUSTOM_PRE_MEMCHECK + - CTEST_CUSTOM_PRE_TEST + - CTEST_CUSTOM_TEST_IGNORE + - CTEST_CUSTOM_WARNING_EXCEPTION + - CTEST_CUSTOM_WARNING_MATCH + - CTEST_CVS_CHECKOUT + - CTEST_CVS_COMMAND + - CTEST_CVS_UPDATE_OPTIONS + - CTEST_DROP_LOCATION + - CTEST_DROP_METHOD + - CTEST_DROP_SITE + - CTEST_DROP_SITE_CDASH + - CTEST_DROP_SITE_PASSWORD + - CTEST_DROP_SITE_USER + - CTEST_EXTRA_COVERAGE_GLOB + - CTEST_GIT_COMMAND + - CTEST_GIT_INIT_SUBMODULES + - CTEST_GIT_UPDATE_CUSTOM + - CTEST_GIT_UPDATE_OPTIONS + - CTEST_HG_COMMAND + - CTEST_HG_UPDATE_OPTIONS + - CTEST_LABELS_FOR_SUBPROJECTS # Since 3.10 + - CTEST_MEMORYCHECK_COMMAND + - CTEST_MEMORYCHECK_COMMAND_OPTIONS + - CTEST_MEMORYCHECK_SANITIZER_OPTIONS + - CTEST_MEMORYCHECK_SUPPRESSIONS_FILE + - CTEST_MEMORYCHECK_TYPE + - CTEST_NIGHTLY_START_TIME + - CTEST_P4_CLIENT + - CTEST_P4_COMMAND + - CTEST_P4_OPTIONS + - CTEST_P4_UPDATE_OPTIONS + - CTEST_SCP_COMMAND + - CTEST_SITE + - CTEST_SOURCE_DIRECTORY + - CTEST_SVN_COMMAND + - CTEST_SVN_OPTIONS + - CTEST_SVN_UPDATE_OPTIONS + - CTEST_TEST_LOAD + - CTEST_TEST_TIMEOUT + - CTEST_TRIGGER_SITE + - CTEST_UPDATE_COMMAND + - CTEST_UPDATE_OPTIONS + - CTEST_UPDATE_VERSION_ONLY + - CTEST_USE_LAUNCHERS + # Variables for CPack + - CPACK_ABSOLUTE_DESTINATION_FILES + - CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY + - CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION + - CPACK_INCLUDE_TOPLEVEL_DIRECTORY + - CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS # Since 3.11 + - CPACK_INSTALL_SCRIPT + - CPACK_PACKAGING_INSTALL_PREFIX + - CPACK_SET_DESTDIR + - CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION + # Variables for `find_package()` + - PACKAGE_FIND_NAME + - PACKAGE_FIND_VERSION + - PACKAGE_FIND_VERSION_MAJOR + - PACKAGE_FIND_VERSION_MINOR + - PACKAGE_FIND_VERSION_PATCH + - PACKAGE_FIND_VERSION_TWEAK + - PACKAGE_FIND_VERSION_COUNT + - PACKAGE_VERSION + - PACKAGE_VERSION_EXACT + - PACKAGE_VERSION_COMPATIBLE + - PACKAGE_VERSION_UNSUITABLE + # NOTE <SMTH>_VERSION and components already defined above, so skipped here + - <package>_FOUND + - <package>_VERSION_COUNT + - <package>_FIND_REQUIRED + - <package>_FIND_QUIETLY + - <package>_FIND_VERSION + - <package>_FIND_VERSION_MAJOR + - <package>_FIND_VERSION_MINOR + - <package>_FIND_VERSION_PATCH + - <package>_FIND_VERSION_TWEAK + - <package>_FIND_VERSION_COUNT + - <package>_FIND_VERSION_EXACT + - <package>_FIND_COMPONENTS + - <package>_FIND_REQUIRED_<c> + - <package>_CONSIDERED_CONFIGS + - <package>_CONSIDERED_VERSIONS + - <PackageName>_ROOT # Since 3.12 + # Other standard variables/patterns + # - `try_run` + - <RUN_RESULT_VAR>__TRYRUN_OUTPUT + # Well known CMake's official module's variables + # - CheckCCompilerFlag + # - CheckCSourceCompiles + # - CheckCSourceRuns + # - CheckCxxCompilerFlag + # - CheckCxxSourceCompiles + # - CheckCxxSourceRuns + # - CheckCXXSymbolExists + # - CheckFortranCompilerFlag + # - CheckFortranFunctionExists + # - CheckFortranSourceCompiles + # - CheckFortranSourceCompiles + # - CheckFunctionExists + # - CheckIncludeFileCXX + # - CheckIncludeFile + # - CheckIncludeFiles + # - CheckLibraryExists + # - CheckPrototypeDefinition + # - CheckStructHasMember + # - CheckSymbolExists + # - CheckTypeSize + # - CheckVariableExists + - CMAKE_REQUIRED_DEFINITIONS + - CMAKE_REQUIRED_FLAGS + - CMAKE_REQUIRED_INCLUDES + - CMAKE_REQUIRED_LIBRARIES + - CMAKE_REQUIRED_QUIET + # - CheckTypeSize + # - CMakePushCheckState + - CMAKE_EXTRA_INCLUDE_FILES + # - CMakeBackwardCompatibilityCXX + - CMAKE_ANSI_CXXFLAGS + - CMAKE_HAS_ANSI_STRING_STREAM + # - CMakeFindFrameworks + - CMAKE_FIND_FRAMEWORK_EXTRA_LOCATIONS + # - CMakeGraphVizOptions + - GRAPHVIZ_GRAPH_TYPE + - GRAPHVIZ_GRAPH_NAME + - GRAPHVIZ_GRAPH_HEADER + - GRAPHVIZ_NODE_PREFIX + - GRAPHVIZ_EXECUTABLES + - GRAPHVIZ_STATIC_LIBS + - GRAPHVIZ_SHARED_LIBS + - GRAPHVIZ_MODULE_LIBS + - GRAPHVIZ_EXTERNAL_LIBS + - GRAPHVIZ_IGNORE_TARGETS + - GRAPHVIZ_GENERATE_PER_TARGET + # - CPackArchive + - CPACK_ARCHIVE_FILE_NAME + - CPACK_ARCHIVE_<COMPONENT>_FILE_NAME + - CPACK_ARCHIVE_COMPONENT_INSTALL + # - CPackBundle + - CPACK_BUNDLE_NAME + - CPACK_BUNDLE_PLIST + - CPACK_BUNDLE_ICON + - CPACK_BUNDLE_STARTUP_COMMAND + - CPACK_BUNDLE_APPLE_CERT_APP + - CPACK_BUNDLE_APPLE_ENTITLEMENTS + - CPACK_BUNDLE_APPLE_CODESIGN_FILES + - CPACK_BUNDLE_APPLE_CODESIGN_PARAMETER + - CPACK_COMMAND_CODESIGN + # - CPackComponent + - CPACK_COMPONENTS_ALL + - CPACK_<GENNAME>_COMPONENT_INSTALL + - CPACK_COMPONENTS_GROUPING + - CPACK_COMPONENT_<COMPNAME>_DISPLAY_NAME + - CPACK_COMPONENT_<COMPNAME>_DESCRIPTION + - CPACK_COMPONENT_<COMPNAME>_GROUP + - CPACK_COMPONENT_<COMPNAME>_DEPENDS + - CPACK_COMPONENT_<COMPNAME>_HIDDEN + - CPACK_COMPONENT_<COMPNAME>_REQUIRED + - CPACK_COMPONENT_<COMPNAME>_DISABLED + # - CPackCygwin + - CPACK_CYGWIN_PATCH_NUMBER + - CPACK_CYGWIN_PATCH_FILE + - CPACK_CYGWIN_BUILD_SCRIPT + # - CPackDeb + - CPACK_DEB_COMPONENT_INSTALL + - CPACK_DEBIAN_PACKAGE_NAME + - CPACK_DEBIAN_<COMPONENT>_PACKAGE_NAME + - CPACK_DEBIAN_FILE_NAME + - CPACK_DEBIAN_<COMPONENT>_FILE_NAME + - CPACK_DEBIAN_PACKAGE_EPOCH # Since 3.10 + - CPACK_DEBIAN_PACKAGE_VERSION + - CPACK_DEBIAN_PACKAGE_RELEASE + - CPACK_DEBIAN_PACKAGE_ARCHITECTURE + - CPACK_DEBIAN_<COMPONENT>_PACKAGE_ARCHITECTURE + - CPACK_DEBIAN_PACKAGE_DEPENDS + - CPACK_DEBIAN_<COMPONENT>_PACKAGE_DEPENDS + - CPACK_DEBIAN_ENABLE_COMPONENT_DEPENDS + - CPACK_DEBIAN_PACKAGE_MAINTAINER + - CPACK_DEBIAN_PACKAGE_DESCRIPTION + - CPACK_COMPONENT_<COMPONENT>_DESCRIPTION + - CPACK_DEBIAN_PACKAGE_SECTION + - CPACK_DEBIAN_<COMPONENT>_PACKAGE_SECTION + - CPACK_DEBIAN_ARCHIVE_TYPE + - CPACK_DEBIAN_COMPRESSION_TYPE + - CPACK_DEBIAN_PACKAGE_PRIORITY + - CPACK_DEBIAN_<COMPONENT>_PACKAGE_PRIORITY + - CPACK_DEBIAN_PACKAGE_HOMEPAGE + - CPACK_DEBIAN_PACKAGE_SHLIBDEPS + - CPACK_DEBIAN_<COMPONENT>_PACKAGE_SHLIBDEPS + - CPACK_DEBIAN_PACKAGE_DEBUG + - CPACK_DEBIAN_PACKAGE_PREDEPENDS + - CPACK_DEBIAN_<COMPONENT>_PACKAGE_PREDEPENDS + - CPACK_DEBIAN_PACKAGE_ENHANCES + - CPACK_DEBIAN_<COMPONENT>_PACKAGE_ENHANCES + - CPACK_DEBIAN_PACKAGE_BREAKS + - CPACK_DEBIAN_<COMPONENT>_PACKAGE_BREAKS + - CPACK_DEBIAN_PACKAGE_CONFLICTS + - CPACK_DEBIAN_<COMPONENT>_PACKAGE_CONFLICTS + - CPACK_DEBIAN_PACKAGE_PROVIDES + - CPACK_DEBIAN_<COMPONENT>_PACKAGE_PROVIDES + - CPACK_DEBIAN_PACKAGE_REPLACES + - CPACK_DEBIAN_<COMPONENT>_PACKAGE_REPLACES + - CPACK_DEBIAN_PACKAGE_RECOMMENDS + - CPACK_DEBIAN_<COMPONENT>_PACKAGE_RECOMMENDS + - CPACK_DEBIAN_PACKAGE_SUGGESTS + - CPACK_DEBIAN_<COMPONENT>_PACKAGE_SUGGESTS + - CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS + - CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS_POLICY + - CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA + - CPACK_DEBIAN_<COMPONENT>_PACKAGE_CONTROL_EXTRA + - CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION + - CPACK_DEBIAN_<COMPONENT>_PACKAGE_CONTROL_STRICT_PERMISSION + - CPACK_DEBIAN_PACKAGE_SOURCE + - CPACK_DEBIAN_<COMPONENT>_PACKAGE_SOURCE + - CPACK_DEBIAN_DEBUGINFO_PACKAGE # Since 3.13 + - CPACK_DEBIAN_<component>_DEBUGINFO_PACKAGE # Since 3.13 + # - CPackDMG + - CPACK_DMG_VOLUME_NAME + - CPACK_DMG_FORMAT + - CPACK_DMG_DS_STORE + - CPACK_DMG_DS_STORE_SETUP_SCRIPT + - CPACK_DMG_BACKGROUND_IMAGE + - CPACK_DMG_DISABLE_APPLICATIONS_SYMLINK + - CPACK_DMG_SLA_DIR + - CPACK_DMG_SLA_LANGUAGES + - CPACK_COMMAND_HDIUTIL + - CPACK_COMMAND_SETFILE + - CPACK_COMMAND_REZ + # -CPackExt (Since 3.13) + - CPACK_EXT_REQUESTED_VERSIONS + - CPACK_EXT_ENABLE_STAGING + - CPACK_EXT_PACKAGE_SCRIPT + # - CPackIFW + - CPACK_IFW_ROOT + - QTIFWDIR + - CPACK_IFW_VERBOSE + - CPACK_IFW_PACKAGE_TITLE + - CPACK_IFW_PACKAGE_PUBLISHER + - CPACK_IFW_PRODUCT_URL + - CPACK_IFW_PACKAGE_ICON + - CPACK_IFW_PACKAGE_WINDOW_ICON + - CPACK_IFW_PACKAGE_LOGO + - CPACK_IFW_PACKAGE_WATERMARK + - CPACK_IFW_PACKAGE_BANNER + - CPACK_IFW_PACKAGE_BACKGROUND + - CPACK_IFW_PACKAGE_WIZARD_STYLE + - CPACK_IFW_PACKAGE_WIZARD_DEFAULT_WIDTH + - CPACK_IFW_PACKAGE_WIZARD_DEFAULT_HEIGHT + - CPACK_IFW_PACKAGE_TITLE_COLOR + - CPACK_IFW_PACKAGE_START_MENU_DIRECTORY + - CPACK_IFW_TARGET_DIRECTORY + - CPACK_IFW_ADMIN_TARGET_DIRECTORY + - CPACK_IFW_PACKAGE_GROUP + - CPACK_IFW_PACKAGE_NAME + - CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_NAME + - CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_INI_FILE + - CPACK_IFW_PACKAGE_ALLOW_NON_ASCII_CHARACTERS + - CPACK_IFW_PACKAGE_ALLOW_SPACE_IN_PATH + - CPACK_IFW_PACKAGE_CONTROL_SCRIPT + - CPACK_IFW_PACKAGE_REMOVE_TARGET_DIR # Since 3.11 + - CPACK_IFW_PACKAGE_RESOURCES + - CPACK_IFW_REPOSITORIES_ALL + - CPACK_IFW_DOWNLOAD_ALL + - CPACK_IFW_RESOLVE_DUPLICATE_NAMES + - CPACK_IFW_PACKAGES_DIRECTORIES + - CPACK_IFW_FRAMEWORK_VERSION + - CPACK_IFW_BINARYCREATOR_EXECUTABLE + - CPACK_IFW_REPOGEN_EXECUTABLE + - CPACK_IFW_INSTALLERBASE_EXECUTABLE + - CPACK_IFW_DEVTOOL_EXECUTABLE + # - CPackNSIS + - CPACK_NSIS_INSTALL_ROOT + - CPACK_NSIS_MUI_ICON + - CPACK_NSIS_MUI_UNIICON + - CPACK_NSIS_INSTALLER_MUI_ICON_CODE + - CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP + - CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP + - CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS + - CPACK_NSIS_EXTRA_INSTALL_COMMANDS + - CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS + - CPACK_NSIS_COMPRESSOR + - CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL + - CPACK_NSIS_MODIFY_PATH + - CPACK_NSIS_DISPLAY_NAME + - CPACK_NSIS_PACKAGE_NAME + - CPACK_NSIS_INSTALLED_ICON_NAME + - CPACK_NSIS_HELP_LINK + - CPACK_NSIS_URL_INFO_ABOUT + - CPACK_NSIS_CONTACT + - CPACK_NSIS_<compName>_INSTALL_DIRECTORY + - CPACK_NSIS_CREATE_ICONS_EXTRA + - CPACK_NSIS_DELETE_ICONS_EXTRA + - CPACK_NSIS_EXECUTABLES_DIRECTORY + - CPACK_NSIS_MUI_FINISHPAGE_RUN + - CPACK_NSIS_MENU_LINKS + # - CPackNuGet (since 3.12) + - CPACK_NUGET_COMPONENT_INSTALL + - CPACK_NUGET_PACKAGE_NAME + - CPACK_NUGET_<compName>_PACKAGE_NAME + - CPACK_NUGET_PACKAGE_VERSION + - CPACK_NUGET_<compName>_PACKAGE_VERSION + - CPACK_NUGET_PACKAGE_DESCRIPTION + - CPACK_NUGET_<compName>_PACKAGE_DESCRIPTION + - CPACK_NUGET_PACKAGE_AUTHORS + - CPACK_NUGET_<compName>_PACKAGE_AUTHORS + - CPACK_NUGET_PACKAGE_TITLE + - CPACK_NUGET_<compName>_PACKAGE_TITLE + - CPACK_NUGET_PACKAGE_OWNERS + - CPACK_NUGET_<compName>_PACKAGE_OWNERS + - CPACK_NUGET_PACKAGE_HOMEPAGE_URL + - CPACK_NUGET_<compName>_PACKAGE_HOMEPAGE_URL + - CPACK_NUGET_PACKAGE_LICENSEURL + - CPACK_NUGET_<compName>_PACKAGE_LICENSEURL + - CPACK_NUGET_PACKAGE_ICONURL + - CPACK_NUGET_<compName>_PACKAGE_ICONURL + - CPACK_NUGET_PACKAGE_DESCRIPTION_SUMMARY + - CPACK_NUGET_<compName>_PACKAGE_DESCRIPTION_SUMMARY + - CPACK_NUGET_PACKAGE_RELEASE_NOTES + - CPACK_NUGET_<compName>_PACKAGE_RELEASE_NOTES + - CPACK_NUGET_PACKAGE_COPYRIGHT + - CPACK_NUGET_<compName>_PACKAGE_COPYRIGHT + - CPACK_NUGET_PACKAGE_TAGS + - CPACK_NUGET_<compName>_PACKAGE_TAGS + - CPACK_NUGET_PACKAGE_DEPENDENCIES + - CPACK_NUGET_<compName>_PACKAGE_DEPENDENCIES + - CPACK_NUGET_PACKAGE_DEPENDENCIES_<dependency>_VERSION + - CPACK_NUGET_<compName>_PACKAGE_DEPENDENCIES_<dependency>_VERSION + - CPACK_NUGET_PACKAGE_DEBUG + # - CPackPackageMaker + - CPACK_OSX_PACKAGE_VERSION + # - CPackProductBuild + - CPACK_COMMAND_PRODUCTBUILD + - CPACK_PRODUCTBUILD_IDENTITY_NAME + - CPACK_PRODUCTBUILD_KEYCHAIN_PATH + - CPACK_COMMAND_PKGBUILD + - CPACK_PKGBUILD_IDENTITY_NAME + - CPACK_PKGBUILD_KEYCHAIN_PATH + - CPACK_PRODUCTBUILD_RESOURCES_DIR + # - CPackRPM + - CPACK_RPM_COMPONENT_INSTALL + - CPACK_RPM_PACKAGE_SUMMARY + - CPACK_RPM_<COMPONENT>_PACKAGE_SUMMARY + - CPACK_RPM_PACKAGE_NAME + - CPACK_RPM_<COMPONENT>_PACKAGE_NAME + - CPACK_RPM_FILE_NAME + - CPACK_RPM_<COMPONENT>_FILE_NAME + - CPACK_RPM_MAIN_COMPONENT + - CPACK_RPM_PACKAGE_EPOCH # Since 3.10 + - CPACK_RPM_PACKAGE_VERSION + - CPACK_RPM_PACKAGE_ARCHITECTURE + - CPACK_RPM_<COMPONENT>_PACKAGE_ARCHITECTURE + - CPACK_RPM_PACKAGE_RELEASE + - CPACK_RPM_PACKAGE_RELEASE_DIST + - CPACK_RPM_PACKAGE_LICENSE + - CPACK_RPM_PACKAGE_GROUP + - CPACK_RPM_<COMPONENT>_PACKAGE_GROUP + - CPACK_RPM_PACKAGE_VENDOR + - CPACK_RPM_PACKAGE_URL + - CPACK_RPM_<COMPONENT>_PACKAGE_URL + - CPACK_RPM_PACKAGE_DESCRIPTION + - CPACK_RPM_<COMPONENT>_PACKAGE_DESCRIPTION + - CPACK_RPM_COMPRESSION_TYPE + - CPACK_RPM_PACKAGE_AUTOREQ + - CPACK_RPM_<COMPONENT>_PACKAGE_AUTOREQ + - CPACK_RPM_PACKAGE_AUTOPROV + - CPACK_RPM_<COMPONENT>_PACKAGE_AUTOPROV + - CPACK_RPM_PACKAGE_AUTOREQPROV + - CPACK_RPM_<COMPONENT>_PACKAGE_AUTOREQPROV + - CPACK_RPM_PACKAGE_REQUIRES + - CPACK_RPM_<COMPONENT>_PACKAGE_REQUIRES + - CPACK_RPM_PACKAGE_CONFLICTS + - CPACK_RPM_<COMPONENT>_PACKAGE_CONFLICTS + - CPACK_RPM_PACKAGE_REQUIRES_PRE + - CPACK_RPM_<COMPONENT>_PACKAGE_REQUIRES_PRE + - CPACK_RPM_PACKAGE_REQUIRES_POST + - CPACK_RPM_<COMPONENT>_PACKAGE_REQUIRES_POST + - CPACK_RPM_PACKAGE_REQUIRES_POSTUN + - CPACK_RPM_<COMPONENT>_PACKAGE_REQUIRES_POSTUN + - CPACK_RPM_PACKAGE_REQUIRES_PREUN + - CPACK_RPM_<COMPONENT>_PACKAGE_REQUIRES_PREUN + - CPACK_RPM_PACKAGE_SUGGESTS + - CPACK_RPM_<COMPONENT>_PACKAGE_SUGGESTS + - CPACK_RPM_PACKAGE_PROVIDES + - CPACK_RPM_<COMPONENT>_PACKAGE_PROVIDES + - CPACK_RPM_PACKAGE_OBSOLETES + - CPACK_RPM_<COMPONENT>_PACKAGE_OBSOLETES + - CPACK_RPM_PACKAGE_RELOCATABLE + - CPACK_RPM_SPEC_INSTALL_POST + - CPACK_RPM_SPEC_MORE_DEFINE + - CPACK_RPM_PACKAGE_DEBUG + - CPACK_RPM_USER_BINARY_SPECFILE + - CPACK_RPM_<COMPONENTNAME>_USER_BINARY_SPECFILE + - CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE + - CPACK_RPM_PRE_INSTALL_SCRIPT_FILE + - CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE + - CPACK_RPM_POST_INSTALL_SCRIPT_FILE + - CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE + - CPACK_RPM_USER_FILELIST + - CPACK_RPM_<COMPONENT>_USER_FILELIST + - CPACK_RPM_CHANGELOG_FILE + - CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST + - CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION + - CPACK_RPM_RELOCATION_PATHS + - CPACK_RPM_<COMPONENT>_PACKAGE_PREFIX + - CPACK_RPM_NO_INSTALL_PREFIX_RELOCATION + - CPACK_RPM_NO_<COMPONENT>_INSTALL_PREFIX_RELOCATION + - CPACK_RPM_ADDITIONAL_MAN_DIRS + - CPACK_RPM_DEFAULT_USER + - CPACK_RPM_<COMPNAME>_DEFAULT_USER + - CPACK_RPM_DEFAULT_GROUP + - CPACK_RPM_<COMPNAME>_DEFAULT_GROUP + - CPACK_RPM_DEFAULT_FILE_PERMISSIONS + - CPACK_RPM_<COMPNAME>_DEFAULT_FILE_PERMISSIONS + - CPACK_RPM_DEFAULT_DIR_PERMISSIONS + - CPACK_RPM_<COMPNAME>_DEFAULT_DIR_PERMISSIONS + - CPACK_RPM_INSTALL_WITH_EXEC # Since 3.11 + - CPACK_RPM_DEBUGINFO_PACKAGE + - CPACK_RPM_<COMPONENT>_DEBUGINFO_PACKAGE + - CPACK_BUILD_SOURCE_DIRS + - CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX + - CPACK_RPM_<COMPONENT>_BUILD_SOURCE_DIRS_PREFIX + - CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS + - CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS_ADDITION + - CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE + - CPACK_RPM_DEBUGINFO_FILE_NAME + - CPACK_RPM_<COMPONENT>_DEBUGINFO_FILE_NAME + - CPACK_RPM_FILE_NAME + - CPACK_RPM_PACKAGE_SOURCES + - CPACK_RPM_SOURCE_PKG_BUILD_PARAMS + - CPACK_RPM_SOURCE_PKG_PACKAGING_INSTALL_PREFIX + - CPACK_RPM_BUILDREQUIRES + # - CPack + - CPACK_PACKAGE_NAME + - CPACK_PACKAGE_VENDOR + # `CPACK_PACKAGE_CONTACT` used by some modules (like Deb and NSIS), + # but not documented yet... + - CPACK_PACKAGE_CONTACT + - CPACK_PACKAGE_DIRECTORY + - CPACK_PACKAGE_VERSION_MAJOR + - CPACK_PACKAGE_VERSION_MINOR + - CPACK_PACKAGE_VERSION_PATCH + - CPACK_PACKAGE_DESCRIPTION # Documented since 3.12 + - CPACK_PACKAGE_DESCRIPTION_FILE + - CPACK_PACKAGE_DESCRIPTION_SUMMARY + - CPACK_PACKAGE_HOMEPAGE_URL # Since 3.12 + - CPACK_PACKAGE_FILE_NAME + - CPACK_PACKAGE_INSTALL_DIRECTORY + - CPACK_PACKAGE_ICON + - CPACK_PACKAGE_CHECKSUM + - CPACK_PROJECT_CONFIG_FILE + - CPACK_RESOURCE_FILE_LICENSE + - CPACK_RESOURCE_FILE_README + - CPACK_RESOURCE_FILE_WELCOME + - CPACK_MONOLITHIC_INSTALL + - CPACK_GENERATOR + - CPACK_OUTPUT_CONFIG_FILE + - CPACK_PACKAGE_EXECUTABLES + - CPACK_STRIP_FILES + - CPACK_VERBATIM_VARIABLES + - CPACK_SOURCE_PACKAGE_FILE_NAME + - CPACK_SOURCE_STRIP_FILES + - CPACK_SOURCE_GENERATOR + - CPACK_SOURCE_OUTPUT_CONFIG_FILE + - CPACK_SOURCE_IGNORE_FILES + - CPACK_CMAKE_GENERATOR + - CPACK_INSTALL_CMAKE_PROJECTS + - CPACK_SYSTEM_NAME + - CPACK_PACKAGE_VERSION + - CPACK_TOPLEVEL_TAG + - CPACK_INSTALL_COMMANDS + - CPACK_INSTALLED_DIRECTORIES + - CPACK_PACKAGE_INSTALL_REGISTRY_KEY + - CPACK_CREATE_DESKTOP_LINKS + - CPACK_BINARY_<GENNAME> + # - CPackWIX + - CPACK_WIX_UPGRADE_GUID + - CPACK_WIX_PRODUCT_GUID + - CPACK_WIX_LICENSE_RTF + - CPACK_WIX_PRODUCT_ICON + - CPACK_WIX_UI_REF + - CPACK_WIX_UI_BANNER + - CPACK_WIX_UI_DIALOG + - CPACK_WIX_PROGRAM_MENU_FOLDER + - CPACK_WIX_CULTURES + - CPACK_WIX_TEMPLATE + - CPACK_WIX_PATCH_FILE + - CPACK_WIX_EXTRA_SOURCES + - CPACK_WIX_EXTRA_OBJECTS + - CPACK_WIX_EXTENSIONS + - CPACK_WIX_<TOOL>_EXTENSIONS + - CPACK_WIX_<TOOL>_EXTRA_FLAGS + - CPACK_WIX_CMAKE_PACKAGE_REGISTRY + - CPACK_WIX_PROPERTY_<PROPERTY> + - CPACK_WIX_ROOT_FEATURE_TITLE + - CPACK_WIX_ROOT_FEATURE_DESCRIPTION + - CPACK_WIX_SKIP_PROGRAM_FOLDER + - CPACK_WIX_ROOT_FOLDER_ID + - CPACK_WIX_ROOT + # - CTest + # - Dart + - BUILD_TESTING + # - ExternalData + - ExternalData_BINARY_ROOT + - ExternalData_CUSTOM_SCRIPT_<key> + - ExternalData_LINK_CONTENT + - ExternalData_NO_SYMLINKS + - ExternalData_OBJECT_STORES + - ExternalData_SERIES_PARSE + - ExternalData_SERIES_PARSE_PREFIX + - ExternalData_SERIES_PARSE_NUMBER + - ExternalData_SERIES_PARSE_SUFFIX + - ExternalData_SERIES_MATCH + - ExternalData_SOURCE_ROOT + - ExternalData_TIMEOUT_ABSOLUTE + - ExternalData_TIMEOUT_INACTIVITY + - ExternalData_URL_ALGO_<algo>_<key> + - ExternalData_URL_TEMPLATES + - ExternalData_CUSTOM_LOCATION + - ExternalData_CUSTOM_FILE + - ExternalData_CUSTOM_ERROR + # - FindXXX module "standard" variables + - <package>_INCLUDE_DIRS + - <package>_LIBRARIES + - <package>_LIBRARY_DIRS + - <package>_VERSION_STRING + # - FindDoxygen + - DOXYGEN_<TAG> + # - FindPkgConfig + - PKG_CONFIG_EXECUTABLE + - PKG_CONFIG_VERSION_STRING + - PKG_CONFIG_USE_CMAKE_PREFIX_PATH + # - FindThreads + - CMAKE_THREAD_LIBS_INIT + - CMAKE_USE_SPROC_INIT + - CMAKE_USE_WIN32_THREADS_INIT + - CMAKE_USE_PTHREADS_INIT + - CMAKE_HP_PTHREADS_INIT + - CMAKE_THREAD_PREFER_PTHREAD + - THREADS_PREFER_PTHREAD_FLAG + # - GNUInstallDirs + - CMAKE_INSTALL_BINDIR + - CMAKE_INSTALL_FULL_BINDIR + - CMAKE_INSTALL_SBINDIR + - CMAKE_INSTALL_FULL_SBINDIR + - CMAKE_INSTALL_LIBEXECDIR + - CMAKE_INSTALL_FULL_LIBEXECDIR + - CMAKE_INSTALL_SYSCONFDIR + - CMAKE_INSTALL_FULL_SYSCONFDIR + - CMAKE_INSTALL_SHAREDSTATEDIR + - CMAKE_INSTALL_FULL_SHAREDSTATEDIR + - CMAKE_INSTALL_LOCALSTATEDIR + - CMAKE_INSTALL_FULL_LOCALSTATEDIR + - CMAKE_INSTALL_RUNSTATEDIR + - CMAKE_INSTALL_FULL_RUNSTATEDIR + - CMAKE_INSTALL_LIBDIR + - CMAKE_INSTALL_FULL_LIBDIR + - CMAKE_INSTALL_INCLUDEDIR + - CMAKE_INSTALL_FULL_INCLUDEDIR + - CMAKE_INSTALL_OLDINCLUDEDIR + - CMAKE_INSTALL_FULL_OLDINCLUDEDIR + - CMAKE_INSTALL_DATAROOTDIR + - CMAKE_INSTALL_FULL_DATAROOTDIR + - CMAKE_INSTALL_DATADIR + - CMAKE_INSTALL_FULL_DATADIR + - CMAKE_INSTALL_INFODIR + - CMAKE_INSTALL_FULL_INFODIR + - CMAKE_INSTALL_LOCALEDIR + - CMAKE_INSTALL_FULL_LOCALEDIR + - CMAKE_INSTALL_MANDIR + - CMAKE_INSTALL_FULL_MANDIR + - CMAKE_INSTALL_DOCDIR + - CMAKE_INSTALL_FULL_DOCDIR + # - InstallRequiredSystemLibraries + - CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS + - CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP + - CMAKE_INSTALL_DEBUG_LIBRARIES + - CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY + - CMAKE_INSTALL_UCRT_LIBRARIES + - CMAKE_INSTALL_MFC_LIBRARIES + - CMAKE_INSTALL_OPENMP_LIBRARIES + - CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION + - CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS + - CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT + # - TestForANSIForScope + - CMAKE_NO_ANSI_FOR_SCOPE + # - TestForANSIStreamHeaders + - CMAKE_NO_ANSI_STREAM_HEADERS + # - TestForSSTREAM + - CMAKE_NO_ANSI_STRING_STREAM + # - TestForSTDNamespace + - CMAKE_NO_STD_NAMESPACE + # - UseSWIG + - CMAKE_SWIG_FLAGS + - CMAKE_SWIG_OUTDIR + - SWIG_MODULE_<name>_EXTRA_DEPS + +scripting-commands: + - + name: break + nulary?: true + - + name: cmake_host_system_information + named-args: [RESULT, QUERY] + special-args: [ + NUMBER_OF_LOGICAL_CORES + , NUMBER_OF_PHYSICAL_CORES + , HOSTNAME + , FQDN + , TOTAL_VIRTUAL_MEMORY + , AVAILABLE_VIRTUAL_MEMORY + , TOTAL_PHYSICAL_MEMORY + , AVAILABLE_PHYSICAL_MEMORY + # Since 3.10 + , IS_64BIT + , HAS_FPU + , HAS_MMX + , HAS_MMX_PLUS + , HAS_SSE + , HAS_SSE2 + , HAS_SSE_FP + , HAS_SSE_MMX + , HAS_AMD_3DNOW + , HAS_AMD_3DNOW_PLUS + , HAS_IA64 + , HAS_SERIAL_NUMBER + , PROCESSOR_SERIAL_NUMBER + , PROCESSOR_NAME + , PROCESSOR_DESCRIPTION + , OS_NAME + , OS_RELEASE + , OS_VERSION + , OS_PLATFORM + ] + - + name: cmake_minimum_required + named-args: [VERSION, FATAL_ERROR] + - + name: cmake_parse_arguments + named-args: [PARSE_ARGV] + - + name: cmake_policy + named-args: [GET, SET, PUSH, POP, VERSION] + special-args: [OLD, NEW] + - + name: configure_file + named-args: [COPYONLY, ESCAPE_QUOTES, "@ONLY", NEWLINE_STYLE] + special-args: [UNIX, DOS, WIN32, LF, CRLF] + - + name: continue + nulary?: true + - + name: elseif + named-args: &if [ + NOT + , AND + , OR + , POLICY + , TARGET + , TEST + , EXISTS + , IS_NEWER_THAN + , IS_NEWER_THAN + , IS_DIRECTORY + , IS_SYMLINK + , IS_ABSOLUTE + , MATCHES + , LESS + , GREATER + , EQUAL + , LESS_EQUAL + , GREATER_EQUAL + , STRLESS + , STRGREATER + , STREQUAL + , STRLESS_EQUAL + , STRGREATER_EQUAL + , VERSION_LESS + , VERSION_GREATER + , VERSION_EQUAL + , VERSION_LESS_EQUAL + , VERSION_GREATER_EQUAL + , IN_LIST + , DEFINED + ] + nested-parentheses?: true + - + name: else + nulary?: true + - + name: endforeach + nulary?: true + - + name: endfunction + nulary?: true + - + name: endif + nulary?: true + - + name: endmacro + nulary?: true + - + name: endwhile + nulary?: true + - + name: execute_process + named-args: [ + COMMAND + , WORKING_DIRECTORY + , TIMEOUT + , RESULT_VARIABLE + , RESULTS_VARIABLE # Since 3.10 + , OUTPUT_VARIABLE + , ERROR_VARIABLE + , INPUT_FILE + , OUTPUT_FILE + , ERROR_FILE + , OUTPUT_QUIET + , ERROR_QUIET + , OUTPUT_STRIP_TRAILING_WHITESPACE + , ERROR_STRIP_TRAILING_WHITESPACE + , ENCODING + ] + special-args: [NONE, AUTO, ANSI, OEM, UTF8] + - + name: file + named-args: [ + WRITE + , APPEND + , TOUCH # Since 3.12 + , TOUCH_NOCREATE # Since 3.12 + , READ + , OFFSET + , LIMIT + , HEX + , STRINGS + , LENGTH_MAXIMUM + , LENGTH_MINIMUM + , LIMIT_COUNT + , LIMIT_INPUT + , LIMIT_OUTPUT + , NEWLINE_CONSUME + , NO_HEX_CONVERSION + , REGEX + , ENCODING + , MD5 + , SHA1 + , SHA224 + , SHA256 + , SHA384 + , SHA512 + , SHA3_224 + , SHA3_256 + , SHA3_384 + , SHA3_512 + , GLOB + , GLOB_RECURSE + , LIST_DIRECTORIES + , RELATIVE + , CONFIGURE_DEPENDS # Since 3.12 + , FOLLOW_SYMLINKS + , RENAME + , REMOVE + , REMOVE_RECURSE + , MAKE_DIRECTORY + , RELATIVE_PATH + , TO_CMAKE_PATH + , TO_NATIVE_PATH + , DOWNLOAD + , UPLOAD + , INACTIVITY_TIMEOUT + , LOG + , SHOW_PROGRESS + , STATUS + , TIMEOUT + , USERPWD + , HTTPHEADER + , EXPECTED_HASH + , EXPECTED_MD5 + , TLS_VERIFY + , TLS_CAINFO + , TIMESTAMP + , UTC + , GENERATE + , OUTPUT + , INPUT + , CONTENT + , CONDITION + , COPY + , INSTALL + , DESTINATION + , FILE_PERMISSIONS + , DIRECTORY_PERMISSIONS + , NO_SOURCE_PERMISSIONS + , USE_SOURCE_PERMISSIONS + , FILES_MATCHING + , PATTERN + , REGEX + , EXCLUDE + , PERMISSIONS + , LOCK + , DIRECTORY + , RELEASE + , GUARD + , RESULT_VARIABLE + , TIMEOUT + # Sub-options of UPLOAD/DOWNLOAD since 3.11 + , NETRC + , NETRC_FILE + ] + special-args: [ + UTF-8 + , UTF-16LE + , UTF-16BE + , UTF-32LE + , UTF-32B + , FUNCTION + , FILE + , PROCESS + , OWNER_READ + , OWNER_WRITE + , OWNER_EXECUTE + , GROUP_READ + , GROUP_WRITE + , GROUP_EXECUTE + , WORLD_READ + , WORLD_WRITE + , WORLD_EXECUTE + , SETUID + , SETGID + , IGNORED # NETRC options since 3.11 + , OPTIONAL + , REQUIRED + ] + - + name: find_file + named-args: &find_file [ + NAMES + , HINTS + , PATHS + , PATH_SUFFIXES + , DOC + , NO_DEFAULT_PATH + , NO_PACKAGE_ROOT_PATH + , NO_CMAKE_PATH + , NO_CMAKE_ENVIRONMENT_PATH + , NO_SYSTEM_ENVIRONMENT_PATH + , NO_CMAKE_SYSTEM_PATH + , CMAKE_FIND_ROOT_PATH_BOTH + , ONLY_CMAKE_FIND_ROOT_PATH + , NO_CMAKE_FIND_ROOT_PATH + ] + - + name: find_library + named-args: &find_library [ + NAMES + , NAMES_PER_DIR + , HINTS + , PATHS + , PATH_SUFFIXES + , DOC + , NO_DEFAULT_PATH + , NO_PACKAGE_ROOT_PATH + , NO_CMAKE_PATH + , NO_CMAKE_ENVIRONMENT_PATH + , NO_SYSTEM_ENVIRONMENT_PATH + , NO_CMAKE_SYSTEM_PATH + , CMAKE_FIND_ROOT_PATH_BOTH + , ONLY_CMAKE_FIND_ROOT_PATH + , NO_CMAKE_FIND_ROOT_PATH + ] + - + name: find_package + named-args: [ + EXACT + , QUIET + , MODULE + , REQUIRED + , COMPONENTS + , OPTIONAL_COMPONENTS + , NO_POLICY_SCOPE + , CONFIG + , NO_MODULE + , NAMES + , CONFIGS + , HINTS + , PATHS + , PATH_SUFFIXES + , NO_DEFAULT_PATH + , NO_PACAKGE_ROOT_PATH + , NO_CMAKE_PATH + , NO_CMAKE_ENVIRONMENT_PATH + , NO_SYSTEM_ENVIRONMENT_PATH + , NO_CMAKE_PACKAGE_REGISTRY + , NO_CMAKE_SYSTEM_PATH + , NO_CMAKE_SYSTEM_PACKAGE_REGISTRY + , CMAKE_FIND_ROOT_PATH_BOTH + , ONLY_CMAKE_FIND_ROOT_PATH + , NO_CMAKE_FIND_ROOT_PATH + ] + - + name: find_path + named-args: *find_file + - + name: find_program + named-args: *find_library + - + name: foreach + named-args: [RANGE, IN, LISTS, ITEMS] + - + name: function + - + name: get_cmake_property + property-args: [global-properties] + - + name: get_directory_property + named-args: [DIRECTORY, DEFINITION] + property-args: &get_directory_property [directory-properties] + - + name: get_filename_component + named-args: [DIRECTORY, NAME, EXT, NAME_WE, PATH, CACHE, BASE_DIR, ABSOLUTE, REALPATH, PROGRAM, PROGRAM_ARGS] + - + name: get_property + named-args: [GLOBAL, DIRECTORY, TARGET, SOURCE, INSTALL, TEST, CACHE, VARIABLE, PROPERTY, SET, DEFINED, BRIEF_DOCS, FULL_DOCS] + property-args: &get-property [ + global-properties + , directory-properties + , target-properties + , test-properties + , source-properties + , cache-properties + , install-properties + ] + - + name: if + named-args: *if + nested-parentheses?: true + - + name: include + named-args: [OPTIONAL, RESULT_VARIABLE, NO_POLICY_SCOPE] + - + # Since 3.10 + name: include_guard + named-args: [DIRECTORY, GLOBAL] + - + name: list + named-args: [ + LENGTH + , GET + , APPEND + , FILTER + , INCLUDE + , EXCLUDE + , REGEX + , FIND + , INSERT + , REMOVE_ITEM + , REMOVE_AT + , REMOVE_DUPLICATES + , REVERSE + , SORT + # Since 3.13 + , COMPARE + , CASE + , ORDER + # Since 3.12 + , JOIN + , SUBLIST + , TRANSFORM + # `TRANSFORM`'s actions + # NOTE Another `APPEND` named arg has already added + , PREPEND + , TOLOWER + , TOLOWER + , STRIP + , GENEX_STRIP + , REPLACE + # `TRANSFORM`'s selectors + , AT + , FOR + # NOTE Another `REGEX` named arg has already added + , OUTPUT_VARIABLE + ] + # Since 3.13 + special-args: [STRING, FILE_BASENAME, SENSITIVE, INSENSITIVE, ASCENDING, DESCENDING] + - + name: macro + - + name: mark_as_advanced + named-args: [CLEAR, FORCE] + - + name: math + named-args: [ + EXPR + , OUTPUT_FORMAT # Since 3.13 + ] + # Since 3.13 + special-args: [DECIMAL, HEXADECIMAL] + - + name: message + named-args: [STATUS, WARNING, AUTHOR_WARNING, SEND_ERROR, FATAL_ERROR, DEPRECATION] + - + name: option + - + name: return + nulary?: true + - + name: separate_arguments + named-args: [NATIVE_COMMAND, UNIX_COMMAND, WINDOWS_COMMAND] + - + name: set_directory_properties + named-args: [PROPERTIES] + property-args: *get-property + - + name: set_property + named-args: [GLOBAL, DIRECTORY, TARGET, DIRECTORY, SOURCE, INSTALL, TEST, CACHE, VARIABLE, APPEND, APPEND_STRING, PROPERTY] + property-args: *get-property + - + name: set + named-args: [PARENT_SCOPE, CACHE, FORCE] + special-args: [BOOL, FILEPATH, PATH, STRING, INTERNAL, STATIC] + - + name: site_name + - + name: string + named-args: [ + FIND + , REVERSE + , REPLACE + , REGEX + , MATCH + , MATCHALL + , APPEND + , PREPEND # Since 3.10 + , CONCAT + , JOIN # Since 3.12 + , TOLOWER + , TOUPPER + , LENGTH + , SUBSTRING + , STRIP + , GENEX_STRIP + , COMPARE + , LESS + , GREATER + , EQUAL + , NOTEQUAL + , LESS_EQUAL + , GREATER_EQUAL + , MD5 + , SHA1 + , SHA224 + , SHA256 + , SHA384 + , SHA512 + , SHA3_224 + , SHA3_256 + , SHA3_384 + , SHA3_512 + , ASCII + , CONFIGURE + , "@ONLY" + , ESCAPE_QUOTES + , RANDOM + , LENGTH + , ALPHABET + , RANDOM_SEED + , TIMESTAMP + , UTC + , MAKE_C_IDENTIFIER + , UUID + , NAMESPACE + , NAME + , TYPE + , UPPER + ] + - + name: unset + named-args: [CACHE, PARENT_SCOPE] + - + name: variable_watch + - + name: while + named-args: *if + nested-parentheses?: true + +project-commands: + - + name: add_compile_definitions # Since 3.12 + - + name: add_compile_options + - + name: add_custom_command + named-args: [ + OUTPUT + , COMMAND + , ARGS + , MAIN_DEPENDENCY + , DEPENDS + , BYPRODUCTS + , IMPLICIT_DEPENDS + , WORKING_DIRECTORY + , COMMENT + , DEPFILE + , VERBATIM + , APPEND + , USES_TERMINAL + , COMMAND_EXPAND_LISTS + , TARGET + , PRE_BUILD + , PRE_LINK + , POST_BUILD + ] + - + name: add_custom_target + named-args: [ + ALL + , COMMAND + , DEPENDS + , BYPRODUCTS + , IMPLICIT_DEPENDS + , WORKING_DIRECTORY + , COMMENT + , DEPFILE + , VERBATIM + , APPEND + , USES_TERMINAL + , COMMAND_EXPAND_LISTS + , SOURCES + ] + - + name: add_definitions + - + name: add_dependencies + - + name: add_executable + named-args: [WIN32, MACOSX_BUNDLE, EXCLUDE_FROM_ALL, IMPORTED, GLOBAL, ALIAS] + - + name: add_library + named-args: [STATIC, SHARED, MODULE, OBJECT, EXCLUDE_FROM_ALL, IMPORTED, UNKNOWN, GLOBAL, ALIAS, INTERFACE] + - + name: add_link_options + - + name: add_subdirectory + named-args: [EXCLUDE_FROM_ALL] + - + name: add_test + named-args: [NAME, COMMAND, CONFIGURATIONS, WORKING_DIRECTORY] + - + name: aux_source_directory + - + name: build_command + named-args: [CONFIGURATION, TARGET] + - + name: create_test_sourcelist + named-args: [EXTRA_INCLUDE, FUNCTION] + - + name: define_property + named-args: [GLOBAL, DIRECTORY, DIRECTORY, SOURCE, TEST, VARIABLE, CACHED_VARIABLE, PROPERTY, INHERITED, BRIEF_DOCS, FULL_DOCS] + property-args: *get-property + - + name: enable_language + named-args: [OPTIONAL] + special-args: [C, CXX, RC, Fortran] + - + name: enable_testing + - + name: export + named-args: [EXPORT, NAMESPACE, FILE, TARGETS, APPEND, EXPORT_LINK_INTERFACE_LIBRARIES, ANDROID_MK] + - + name: fltk_wrap_ui + - + name: get_source_file_property + property-args: &get_source_file_property [source-properties] + - + name: get_target_property + property-args: &get_target_property [target-properties] + - + name: get_test_property + property-args: &get_test_property [test-properties] + - + name: include_directories + named-args: [AFTER, BEFORE, SYSTEM] + - + name: include_external_msproject + named-args: [TYPE, GUID, PLATFORM] + - + name: include_regular_expression + - + name: install + named-args: [ + # Common + DESTINATION + , PERMISSIONS + , CONFIGURATIONS + , COMPONENT + , NAMELINK_COMPONENT # Since 3.12 + , EXCLUDE_FROM_ALL + , RENAME + , OPTIONAL + # Installing Targets + , TARGETS + , EXPORT + , ARCHIVE + , LIBRARY + , RUNTIME + , OBJECTS + , FRAMEWORK + , BUNDLE + , PRIVATE_HEADER + , PUBLIC_HEADER + , RESOURCE + , INCLUDES + , NAMELINK_ONLY + , NAMELINK_SKIP + # Installing Files + , FILES + , PROGRAMS + # Installing Directories + , DIRECTORY + , FILE_PERMISSIONS + , DIRECTORY_PERMISSIONS + , USE_SOURCE_PERMISSIONS + , MESSAGE_NEVER + , FILES_MATCHING + , PATTERN + , REGEX + , EXCLUDE + # Custom Installation Logic + , SCRIPT + , CODE + # Installing Exports + , NAMESPACE + , FILE + , EXPORT_ANDROID_MK + , EXPORT_LINK_INTERFACE_LIBRARIES + ] + special-args: &valid_permissions [ + OWNER_READ + , OWNER_WRITE + , OWNER_EXECUTE + , GROUP_READ + , GROUP_WRITE + , GROUP_EXECUTE + , WORLD_READ + , WORLD_WRITE + , WORLD_EXECUTE + , SETUID + , SETGID + ] + - + name: link_directories + named-args: [AFTER, BEFORE] + - + name: link_libraries + named-args: [debug, optimized, general] + - + name: load_cache + named-args: [READ_WITH_PREFIX, EXCLUDE, INCLUDE_INTERNALS] + - + name: project + named-args: [ + VERSION + , DESCRIPTION # Since 3.8 or 3.9 (?) + , HOMEPAGE_URL # Since 3.12 + , LANGUAGES + ] + special-args: [NONE, C, CXX, RC, CUDA, Fortran, ASM] + - + name: qt_wrap_cpp + - + name: qt_wrap_ui + - + name: remove_definitions + - + name: set_source_files_properties + named-args: [PROPERTIES] + property-args: *get_source_file_property + - + name: set_target_properties + named-args: [PROPERTIES] + property-args: *get_target_property + - + name: set_tests_properties + named-args: [PROPERTIES] + property-args: *get_test_property + - + name: source_group + named-args: [FILES, REGULAR_EXPRESSION, TREE, PREFIX] + - + name: target_compile_definitions + named-args: &target_compile_definitions [INTERFACE, PUBLIC, PRIVATE] + - + name: target_compile_features + named-args: *target_compile_definitions + special-args: [ + # CMAKE_CXX_KNOWN_FEATURES + cxx_std_98 + , cxx_std_11 + , cxx_std_14 + , cxx_std_17 + , cxx_std_20 # Since 3.12 + , cxx_aggregate_default_initializers + , cxx_alias_templates + , cxx_alignas + , cxx_alignof + , cxx_attributes + , cxx_attribute_deprecated + , cxx_auto_type + , cxx_binary_literals + , cxx_constexpr + , cxx_contextual_conversions + , cxx_decltype_incomplete_return_types + , cxx_decltype + , cxx_decltype_auto + , cxx_default_function_template_args + , cxx_defaulted_functions + , cxx_defaulted_move_initializers + , cxx_delegating_constructors + , cxx_deleted_functions + , cxx_digit_separators + , cxx_enum_forward_declarations + , cxx_explicit_conversions + , cxx_extended_friend_declarations + , cxx_extern_templates + , cxx_final + , cxx_func_identifier + , cxx_generalized_initializers + , cxx_generic_lambdas + , cxx_inheriting_constructors + , cxx_inline_namespaces + , cxx_lambdas + , cxx_lambda_init_captures + , cxx_local_type_template_args + , cxx_long_long_type + , cxx_noexcept + , cxx_nonstatic_member_init + , cxx_nullptr + , cxx_override + , cxx_range_for + , cxx_raw_string_literals + , cxx_reference_qualified_functions + , cxx_relaxed_constexpr + , cxx_return_type_deduction + , cxx_right_angle_brackets + , cxx_rvalue_references + , cxx_sizeof_member + , cxx_static_assert + , cxx_strong_enums + , cxx_thread_local + , cxx_trailing_return_types + , cxx_unicode_literals + , cxx_uniform_initialization + , cxx_unrestricted_unions + , cxx_user_literals + , cxx_variable_templates + , cxx_variadic_macros + , cxx_variadic_templates + , cxx_template_template_parameters + # CMAKE_C_KNOWN_FEATURES + , c_std_90 + , c_std_99 + , c_std_11 + , c_function_prototypes + , c_restrict + , c_static_assert + , c_variadic_macros + ] + - + name: target_compile_options + named-args: &target_compile_options [BEFORE, INTERFACE, PUBLIC, PRIVATE] + - + name: target_include_directories + named-args: [BEFORE, SYSTEM, INTERFACE, PUBLIC, PRIVATE] + - + # Since 3.13 + name: target_link_directories + named-args: *target_compile_options + - + name: target_link_libraries + named-args: *target_compile_definitions + - + name: target_link_options + named-args: *target_compile_definitions + - + name: target_sources + named-args: *target_compile_definitions + - + name: try_compile + named-args: [ + RESULT_VAR + , CMAKE_FLAGS + , OUTPUT_VARIABLE + , SOURCES + , COMPILE_DEFINITIONS + , LINK_LIBRARIES + , COPY_FILE + , COPY_FILE_ERROR + , <LANG>_STANDARD + , <LANG>_STANDARD_REQUIRED + , <LANG>_EXTENSIONS + ] + - + name: try_run + named-args: [ + RUN_RESULT_VAR + , COMPILE_RESULT_VAR + , CMAKE_FLAGS + , COMPILE_DEFINITIONS + , LINK_LIBRARIES + , COMPILE_OUTPUT_VARIABLE + , RUN_OUTPUT_VARIABLE + , OUTPUT_VARIABLE + , ARGS + ] + +ctest-commands: + - + name: ctest_build + named-args: [BUILD, APPEND, CONFIGURATION, FLAGS, PROJECT_NAME, TARGET, NUMBER_ERRORS, NUMBER_WARNINGS, RETURN_VALUE, CAPTURE_CMAKE_ERROR] + - + name: ctest_configure + named-args: [BUILD, SOURCE, APPEND, OPTIONS, RETURN_VALUE, QUIET, CAPTURE_CMAKE_ERROR] + - + name: ctest_coverage + named-args: [BUILD, LABELS, APPEND, RETURN_VALUE, CAPTURE_CMAKE_ERROR, QUIET] + - + name: ctest_empty_binary_directory + - + name: ctest_memcheck + named-args: [ + BUILD + , APPEND + , START + , END + , STRIDE + , EXCLUDE + , INCLUDE + , EXCLUDE_LABEL + , INCLUDE_LABEL + , EXCLUDE_FIXTURE + , EXCLUDE_FIXTURE_SETUP + , EXCLUDE_FIXTURE_CLEANUP + , PARALLEL_LEVEL + , TEST_LOAD + , SCHEDULE_RANDOM + , STOP_TIME + , RETURN_VALUE + , DEFECT_COUNT + , QUIET + ] + - + name: ctest_read_custom_files + - + name: ctest_run_script + named-args: [NEW_PROCESS, RETURN_VALUE] + - + name: ctest_sleep + - + name: ctest_start + named-args: [TRACK, APPEND, QUIET] + - + name: ctest_submit + named-args: [PARTS, FILES, HTTPHEADER, RETRY_COUNT, RETRY_DELAY, RETURN_VALUE, QUIET, CDASH_UPLOAD, CDASH_UPLOAD_TYPE] + - + name: ctest_test + named-args: [ + BUILD + , APPEND + , START + , END + , STRIDE + , EXCLUDE + , INCLUDE + , EXCLUDE_LABEL + , INCLUDE_LABEL + , EXCLUDE_FIXTURE + , EXCLUDE_FIXTURE_SETUP + , EXCLUDE_FIXTURE_CLEANUP + , PARALLEL_LEVEL + , TEST_LOAD + , SCHEDULE_RANDOM + , STOP_TIME + , RETURN_VALUE + , CAPTURE_CMAKE_ERROR + , QUIET + ] + - + name: ctest_update + named-args: [SOURCE, RETURN_VALUE, QUIET] + - + name: ctest_upload + named-args: [FILES, CAPTURE_CMAKE_ERROR, QUIET] diff --git a/src/libs/3rdparty/syntax-highlighting/data/generators/generate-cmake-syntax.py b/src/libs/3rdparty/syntax-highlighting/data/generators/generate-cmake-syntax.py new file mode 100644 index 0000000000..61f60a682d --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/generators/generate-cmake-syntax.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Generate Kate syntax file for CMake +# +# Copyright (c) 2017, Alex Turbov <i.zaufi@gmail.com> +# +# To install prerequisites: +# +# $ pip install --user click jinja2 yaml +# +# To use: +# +# $ ./generate-cmake-syntax.py cmake.yaml > ../syntax/cmake.xml +# +import click +import jinja2 +import pathlib +import re +import yaml + +import pprint + + +_TEMPLATED_NAME = re.compile('<[^>]+>') +_PROPERTY_KEYS = [ + 'global-properties' + , 'directory-properties' + , 'target-properties' + , 'source-properties' + , 'test-properties' + , 'cache-properties' + , 'install-properties' + ] +_KW_RE_LIST = ['kw', 're'] + + +def try_transform_placeholder_string_to_regex(name): + ''' + NOTE Some placeholders are not IDs, but numbers... + `CMAKE_MATCH_<N>` 4 example + ''' + m = _TEMPLATED_NAME.split(name) + if 'CMAKE_MATCH_' in m: + return '\\bCMAKE_MATCH_[0-9]+\\b' + + return '\\b{}\\b'.format('&id_re;'.join(list(m))) if 1 < len(m) else name + + +def partition_iterable(fn, iterable): + true, false = [], [] + for i in iterable: + (false, true)[int(fn(i))].append(i) + return true, false + + +def _transform_command_set(cmd, list_name): + args, args_re = partition_iterable(lambda x: _TEMPLATED_NAME.search(x) is None, cmd[list_name]) + del cmd[list_name] + list_name = list_name.replace('-', '_') + + cmd[list_name] = {k: sorted(set(v)) for k, v in zip(_KW_RE_LIST, [args, args_re])} + cmd[list_name]['re'] = [*map(lambda x: try_transform_placeholder_string_to_regex(x), args_re)] + + return cmd + + +def transform_command(cmd): + can_be_nulary = True + + if 'name' not in cmd: + raise RuntimeError('Command have no name') + + if 'named-args' in cmd: + new_cmd = _transform_command_set(cmd, 'named-args') + assert new_cmd == cmd + can_be_nulary = False + + if 'special-args' in cmd: + new_cmd = _transform_command_set(cmd, 'special-args') + assert new_cmd == cmd + can_be_nulary = False + + if 'property-args' in cmd: + new_cmd = _transform_command_set(cmd, 'property-args') + assert new_cmd == cmd + can_be_nulary = False + + cmd['nested_parentheses'] = cmd['nested-parentheses?'] if 'nested-parentheses?' in cmd else False + + if 'nulary?' in cmd and cmd['nulary?'] and not can_be_nulary: + raise RuntimeError('Command `{}` w/ args declared nulary!?'.format(cmd['name'])) + + return cmd + + +#BEGIN Jinja filters + +def cmd_is_nulary(cmd): + assert not ('named-args' in cmd or 'special-args' in cmd or 'property-args' in cmd) + return 'nulary?' in cmd and cmd['nulary?'] + +#END Jinja filters + + +@click.command() +@click.argument('input_yaml', type=click.File('r')) +@click.argument('template', type=click.File('r'), default='./cmake.xml.tpl') +def cli(input_yaml, template): + data = yaml.load(input_yaml) + + # Partition `variables` list into "pure" words and regexes to match + data['variables'] = { + k: sorted(set(v)) for k, v in zip(_KW_RE_LIST, [*partition_iterable(lambda x: _TEMPLATED_NAME.search(x) is None, data['variables'])]) + } + data['variables']['re'] = [*map(lambda x: try_transform_placeholder_string_to_regex(x), data['variables']['re'])] + + # Transform properties and make all-properties list + data['properties'] = {} + for prop in _PROPERTY_KEYS: + python_prop_list_name = prop.replace('-', '_') + props, props_re = partition_iterable(lambda x: _TEMPLATED_NAME.search(x) is None, data[prop]) + del data[prop] + + data['properties'][python_prop_list_name] = {k: sorted(set(v)) for k, v in zip(_KW_RE_LIST, [props, props_re])} + data['properties'][python_prop_list_name]['re'] = [*map(lambda x: try_transform_placeholder_string_to_regex(x), props_re)] + + + data['properties']['kinds'] = [*map(lambda name: name.replace('-', '_'), _PROPERTY_KEYS)] + + # Make all commands list + data['commands'] = [*map(lambda cmd: transform_command(cmd), data['scripting-commands'] + data['project-commands'] + data['ctest-commands'])] + + data['generator_expressions'] = data['generator-expressions'] + + + env = jinja2.Environment( + keep_trailing_newline=True + ) + + # Register convenience filters + env.tests['nulary'] = cmd_is_nulary + + tpl = env.from_string(template.read()) + result = tpl.render(data) + print(result) + + +if __name__ == '__main__': + cli() + # TODO Handle execptions and show errors diff --git a/src/libs/3rdparty/syntax-highlighting/data/generators/generate-php.pl b/src/libs/3rdparty/syntax-highlighting/data/generators/generate-php.pl new file mode 100644 index 0000000000..c8274aab58 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/generators/generate-php.pl @@ -0,0 +1,58 @@ +#!/usr/bin/perl + +# This perl script read stdin and write on stdout. It shall be an XML language file. +# +# * If the name of the language is 'HTML', then it creates the language 'PHP (HTML)' +# which shall be used for PHP hl. +# +# * If the name of the language is something else (say '*'), it creates the language '*/PHP'. +# This new language is the same as the old one, but is able to detect PHP everywhere. +# +# This script will correctly set extensions & mimetype, and will replace +# <IncludeRules context="##*"> by <IncludeRules context="##*/PHP"> +# +# Generated languages need a language named 'PHP/PHP', which shall take care of PHP hl itself +# and which will be called every time something like <?php is encountred. +# +# Author: Jan Villat <jan.villat@net2000.ch> +# License: LGPL + +my $file = ""; + +while (<>) +{ + $file .= $_; +} + +$warning = "\n\n<!-- ***** THIS FILE WAS GENERATED BY A SCRIPT - DO NOT EDIT ***** -->\n"; + +$file =~ s/(?=<language)/$warning\n\n\n/; + +if ($file =~ /<language[^>]+name="HTML"/) +{ + $root = 1; +} + +if ($root == 1) +{ + $file =~ s/<language([^>]+)name="[^"]*"/<language$1name="PHP (HTML)"/s; + $file =~ s/<language([^>]+)section="[^"]*"/<language$1section="Scripts"/s; + $file =~ s/<language([^>]+)extensions="[^"]*"/<language$1extensions="*.php;*.php3;*.wml;*.phtml;*.phtm;*.inc;*.ctp"/s; + $file =~ s/<language([^>]+)mimetype="[^"]*"/<language$1mimetype="text\/x-php4-src;text\/x-php3-src;text\/vnd.wap.wml;application\/x-php"/s; +} +else +{ + $file =~ s/<language([^>]+)name="([^"]*)"/<language$1name="$2\/PHP" hidden="true"/s; + $file =~ s/<language([^>]+)section="[^"]*"/<language$1section="Other"/s; + $file =~ s/<language([^>]+)extensions="[^"]*"/<language$1extensions=""/s; + $file =~ s/<language([^>]+)mimetype="[^"]*"/<language$1mimetype=""/s; +} + +$findphp = "<context name=\"FindPHP\" attribute=\"Normal Text\" lineEndContext=\"#stay\">\n<RegExpr context=\"##PHP/PHP\" String=\"<\\?(?:=|php)?\" lookAhead=\"true\" />\n</context>\n"; + +$file =~ s/<IncludeRules\s([^>]*)context="([^"#]*)##(?!Alerts|Doxygen|Modelines)([^"]+)"/<IncludeRules $1context="$2##$3\/PHP"/g; +$file =~ s/(<context\s[^>]*>)/$1\n<IncludeRules context="FindPHP" \/>/g; +$file =~ s/(?=<\/contexts\s*>)/$findphp/; + +print $file; +print $warning; diff --git a/src/libs/3rdparty/syntax-highlighting/data/generators/get-Qt-classes.sh b/src/libs/3rdparty/syntax-highlighting/data/generators/get-Qt-classes.sh new file mode 100644 index 0000000000..f2735c88a5 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/generators/get-Qt-classes.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# +# Copyright (c) 2012-2013 by Alex Turbov +# +# Grab a documented (officially) class list from Qt project web site: +# http://qt-project.org/doc/qt-${version}/classes.html +# + +version=$1 +shift + +case "$version" in +5*) + url="http://qt-project.org/doc/qt-${version}/qtdoc/classes.html" + ;; +4*) + url="http://qt-project.org/doc/qt-${version}/classes.html" + ;; +*) + echo "*** Error: Only Qt4 and Qt5 supported!" +esac + +if [ -n "$version" ]; then + tmp=`mktemp` + wget -O $tmp "$url" + cat $tmp | egrep '^<dd><a href=".*\.html">.*</a></dd>$' \ + | sed -e 's,<dd><a href=".*\.html">\(.*\)</a></dd>,<item> \1 </item>,' \ + | grep -v 'qoutputrange' + rm $tmp +else + cat <<EOF +Usage: + $0 Qt-version + +Note: Only major and minor version required + +Example: + $0 4.8 +EOF +fi diff --git a/src/libs/3rdparty/syntax-highlighting/data/generators/get-Qt-macros.sh b/src/libs/3rdparty/syntax-highlighting/data/generators/get-Qt-macros.sh new file mode 100644 index 0000000000..db2a32d7a3 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/generators/get-Qt-macros.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# +# Copyright (c) 2011-2012 by Alex Turbov +# +# Simplest (and stupid) way to get #defines from a header file(s) +# +# TODO Think about to use clang to get (an actual) list of free functions and/or types, classes, etc +# Using python bindings it seems possible and not so hard to code... +# + +basepath=$1 +shift + +if [ -n "$*" ]; then + for f in $*; do + egrep '^\s*#\s*define\s+(Q|QT|QT3)_' ${basepath}/$f + done \ + | sed 's,^\s*#\s*define\s\+\(Q[A-Z0-9_]\+\).*,<item> \1 </item>,' \ + | sort \ + | uniq \ + | grep -v EXPORT \ + | grep -v QT_BEGIN_ \ + | grep -v QT_END_ \ + | grep -v QT_MANGLE_ +else + cat <<EOF +Usage: + $0 basepath [qt-header-filenames] + +Example: + $0 /usr/include/qt4/Qt qglobal.h qconfig.h qfeatures.h +EOF +fi diff --git a/src/libs/3rdparty/syntax-highlighting/data/generators/nsis-gen.py b/src/libs/3rdparty/syntax-highlighting/data/generators/nsis-gen.py new file mode 100644 index 0000000000..4f03bd44ff --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/generators/nsis-gen.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +from __future__ import print_function + +tokens = [] +with open("makensiscmdhelp.output") as f: # output from `makensis /cmdhelp` + for line in f: + if line.startswith(" "): + continue # line continuation + + tokens.append(line.split()[0]) + +keywords = [x[1:] for x in tokens if x.startswith("!")] +basefuncs = [x for x in tokens if not x.startswith("!")] + +print("KEYWORDS") +for keyword in keywords: + print("<item> %s </item>" % keyword) +print() + +print("BASEFUNCS") +for basefunc in basefuncs: + print("<item> %s </item>" % basefunc) diff --git a/src/libs/3rdparty/syntax-highlighting/data/generators/qmake-gen.py b/src/libs/3rdparty/syntax-highlighting/data/generators/qmake-gen.py new file mode 100644 index 0000000000..3b20361708 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/generators/qmake-gen.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python + +# Copyright (C) 2016 Kevin Funk <kfunk@kde.org> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +# License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# This script will print XML-like code you can put into the qmake.xml +# syntax definition file +# +# Prerequisite: You need to have a qtbase checkout somewhere +# +# Usage: qmake-gen.py /path/to/qtbase/ + +from __future__ import print_function + +import subprocess +import os +import sys + +qt5Source = sys.argv[1] + +qmakeKeywords = subprocess.check_output("ag --nofilename 'QMAKE_[A-Z_0-9]+' {0}/mkspecs -o".format(qt5Source), shell=True).split(os.linesep) +extraKeywords = subprocess.check_output("sed -nr 's/\\\section1 ([A-Z_0-9]{{2,100}}).*/\\1/p' {0}/qmake/doc/src/qmake-manual.qdoc".format(qt5Source), shell=True).split(os.linesep) +keywords = [] +keywords = [x.strip() for x in qmakeKeywords] +keywords += [x.strip() for x in extraKeywords] +keywords = list(set(keywords)) # remove duplicates +keywords.sort() + +functions = subprocess.check_output("sed -nr 's/\{{ \\\"(.+)\\\", T_.+/\\1/p' {0}/qmake/library/qmakebuiltins.cpp".format(qt5Source), shell=True).split(os.linesep) +functions.sort() + +def printItems(container): + for item in container: + trimmedText = item.strip() + if not trimmedText: + continue + + print("<item> %s </item>" % trimmedText) + print() + +print("KEYWORDS") +printItems(keywords) + +print("FUNCTIONS") +printItems(functions) diff --git a/src/libs/3rdparty/syntax-highlighting/data/schema/language.xsd b/src/libs/3rdparty/syntax-highlighting/data/schema/language.xsd new file mode 100644 index 0000000000..6f05aad7b5 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/schema/language.xsd @@ -0,0 +1,668 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (c) 2001 Joseph Wenninger <jowenn@kde.org> + modified (c) 2002 Anders Lund <anders@alweb.dk> + modified (c) 2003 Simon Huerlimann <simon.huerlimann@access.unizh.ch> + modified (c) 2005 Dominik Haumann <dhdev@gmx.de> + modified (c) 2008 Wilbert Berendsen <info@wilbertberendsen.nl> + + This file describes the XML format used for syntax highlight descriptions + for the Kate text editor (http://kate.kde.org), which is part of the KDE + desktop environment (http://www.kde.org). + You'll find the "Writing a Kate Highlighting XML File HOWTO" at + http://kate.kde.org/doc/hlhowto.php + + This format is identified using the SYSTEM identifier + SYSTEM "language.dtd" + + Files using this format should include a DOCTYPE declaration like this: + <!DOCTYPE language SYSTEM "language.dtd"> + + You can validate your syntax files using "validatehl.sh yourSyntax.xml". + This needs xmllint from the libxml2 XML library. + + In any case, the katehighlightingindexer will validate all files bundled + with KTextEditor during compile time and fail on errors. + + To use your syntax file, copy it to ~/.local/share/katepart5/syntax/ in + your home directory. You have to open a new instance of kwrite/kate to use + the new syntax file. + + TODO + - find a more readable way for the - -dtdvalid stuff, it's just annoying + xml comments don't allow it. +--> +<!-- + Entity declarations + You can use '&per;' instead of '.'. This seems to be useful in <item> elements. + + TODO + - Are there any more such pre-defined entities? +--> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> + <!-- + Default Styles + Allowed predefined default styles for itemData, available are: + - dsNormal, used for normal text + - dsKeyword, used for keywords + - dsFunction, used for function calls + - dsVariable, used for variables + - dsControlFlow, used for control flow, e.g. if, then, else, continue, break + - dsOperator, used for operators such as +, -, *, :: + - dsBuiltIn, used for built-in language classes and functions + - dsExtension,used for extensions, such as boost, Qt + - dsPreprocessor, used for preprocessor statements + - dsAttribute,used for attributes, e.g. @override in java + + - dsChar, used for a character + - dsSpecialChar, used for escaped characters + - dsString, used for strings + - dsVerbatimString, used for strings such as HERE docs + - dsSpecialString, used for strings such as regular expressions or LaTeX math mode + - dsImport, used for includes, imports and modules + + - dsDataType, used for data types + - dsDecVal, used for decimal values + - dsBaseN, used for values with a base other than 10 + - dsFloat, used for float values + - dsConstant, used for language constants + + - dsComment, used for comments + - dsDocumentation, used for comments that are API documentation + - dsAnnotation, used for annotation in comments, e.g. @param in doxygen + - dsCommentVar, used for variables in comments, e.g. after @param in doxygen + - dsRegionMarker, used for region markers + - dsInformation, used for information in comments, e.g. @note in doxygen + - dsWarning, used for warnings in comments, e.g. @warning in doxygen + - dsAlert, used for warning messages such as TODO, WARNING in comments + + - dsOthers, used for 'other' things + - dsError, used for error highlighting. + --> + <xs:simpleType name="defStyles"> + <xs:restriction base="xs:token"> + <xs:enumeration value="dsNormal"/> + <xs:enumeration value="dsKeyword"/> + <xs:enumeration value="dsFunction"/> + <xs:enumeration value="dsVariable"/> + <xs:enumeration value="dsControlFlow"/> + <xs:enumeration value="dsOperator"/> + <xs:enumeration value="dsBuiltIn"/> + <xs:enumeration value="dsExtension"/> + <xs:enumeration value="dsPreprocessor"/> + <xs:enumeration value="dsAttribute"/> + <xs:enumeration value="dsChar"/> + <xs:enumeration value="dsSpecialChar"/> + <xs:enumeration value="dsString"/> + <xs:enumeration value="dsVerbatimString"/> + <xs:enumeration value="dsSpecialString"/> + <xs:enumeration value="dsImport"/> + <xs:enumeration value="dsDataType"/> + <xs:enumeration value="dsDecVal"/> + <xs:enumeration value="dsBaseN"/> + <xs:enumeration value="dsFloat"/> + <xs:enumeration value="dsConstant"/> + <xs:enumeration value="dsComment"/> + <xs:enumeration value="dsDocumentation"/> + <xs:enumeration value="dsAnnotation"/> + <xs:enumeration value="dsCommentVar"/> + <xs:enumeration value="dsRegionMarker"/> + <xs:enumeration value="dsInformation"/> + <xs:enumeration value="dsWarning"/> + <xs:enumeration value="dsAlert"/> + <xs:enumeration value="dsOthers"/> + <xs:enumeration value="dsError"/> + </xs:restriction> + </xs:simpleType> + <!-- + Language specification + name: The name of this syntax description. Used in the Highlightning Mode menu + section: The logical group to which this syntax description belongs. Used for sub menus + extensions: A file glob or pattern to decide for which documents to use this syntax description + style: The style that this highlighter provides. It is used through required-syntax-style by the indenters. [optional] + mimetype: A list of mimetypes to decide for which documents to use this syntax description [optional] + version: Version number of this syntax description [optional] + kateversion: Kate version required for using this file [optional] + casesensitive: Whether text is matched case sensitive. [boolean, optional, default=true] FIXME: This is not implemented yet + priority: Priority of this language, if more than one are usable for the file [optional] + author: Name of author of this hl file [optional] + license: License for this hl file [optional] + indenter: Name of the Indenter to use for this highlighting mode per default, like "cstyle" [optional] + hidden: Should it be hidden in menu [boolean, optional, default=false] + + TODO + - Which matches are affected by casesensitive? keyword, RegExpr, StringDetect, WordDetect...? + + WARNING: due to helper scripts, the language opening tag must be on a + *single line* and *cannot* be split in multiple lines. + + --> + <xs:element name="language"> + <xs:complexType> + <xs:sequence> + <xs:element ref="highlighting"/> + <xs:element minOccurs="0" ref="general"/> + <xs:element minOccurs="0" ref="spellchecking"/> + </xs:sequence> + <xs:attribute name="name" use="required"/> + <xs:attribute name="section" use="required" type="xs:NMTOKEN"/> + <xs:attribute name="extensions" use="required"/> + <xs:attribute name="version" use="required" type="xs:integer"/> + <xs:attribute name="kateversion" use="required" type="xs:decimal"/> + <xs:attribute name="style"/> + <xs:attribute name="mimetype"/> + <xs:attribute name="casesensitive" type="xs:boolean"/> + <xs:attribute name="priority" type="xs:integer"/> + <xs:attribute name="author"/> + <xs:attribute name="license"/> + <xs:attribute name="indenter"/> + <xs:attribute name="hidden" type="xs:boolean"/> + </xs:complexType> + </xs:element> + <!-- General options --> + <xs:element name="general"> + <xs:complexType> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="folding"/> + <xs:element ref="comments"/> + <xs:element ref="keywords"/> + <xs:element ref="emptyLines"/> + </xs:choice> + </xs:complexType> + </xs:element> + <!-- + List of folding + indentationsensitive: If true, the code folding is indentation based. + --> + <xs:element name="folding"> + <xs:complexType> + <xs:attribute name="indentationsensitive" type="xs:boolean"/> + </xs:complexType> + </xs:element> + <!-- List of comments --> + <xs:element name="comments"> + <xs:complexType> + <xs:sequence> + <xs:element maxOccurs="unbounded" ref="comment"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <!-- + Comment specification + name: Type of this comment. Allowed are 'singleLine' and 'multiLine' + start: The comment starts with this string + end: The comment ends with this string [optional] + region: The region name of the foldable multiline comment. If you have + beginRegion="Comment" ... endRegion="Comment" you should use + region="Comment". This way uncomment works even if you do not + select all the text of the multiline comment. + position: only availalbe for type singleLine. Default is column0, to insert + the single line comment characters after the whitespaces + (= before the first non space) set position to "afterwhitespace" + --> + <xs:element name="comment"> + <xs:complexType> + <xs:attribute name="name" use="required"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="singleLine"/> + <xs:enumeration value="multiLine"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute name="start" use="required"/> + <xs:attribute name="end"/> + <xs:attribute name="region"/> + <xs:attribute name="position"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="afterwhitespace"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + </xs:complexType> + </xs:element> + <!-- + Keyword options + casesensitive: Whether keywords are matched case sensitive. [boolean, optional, default=true] + weakDeliminator: Add weak deliminators [optional, default: ""] + additionalDeliminator: Add deliminators [optional] + wordWrapDeliminator: characters that are used to wrap long lines [optional] + + --> + <xs:element name="keywords"> + <xs:complexType> + <xs:attribute name="casesensitive" type="xs:boolean"/> + <xs:attribute name="weakDeliminator"/> + <xs:attribute name="additionalDeliminator"/> + <xs:attribute name="wordWrapDeliminator"/> + </xs:complexType> + </xs:element> + <!-- + Treat lines that match a given regular expression as empty line. This is + needed for example in Python for comments (#...), as then the indentation + based folding should ignore the line. + This is only implemented for indentation based folding. If the folding + is not indentation based, the emptyLines are not used. + --> + <xs:element name="emptyLines"> + <xs:complexType> + <xs:sequence> + <xs:element minOccurs="0" maxOccurs="unbounded" ref="emptyLine"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <!-- + One empty line regular expression. + regexpr: The regular expression, example from python: ^\s*#.*$ + casesensitive: Sets, whether the regular expression match is performed case sesitive + --> + <xs:element name="emptyLine"> + <xs:complexType> + <xs:attribute name="regexpr" use="required"/> + <xs:attribute name="casesensitive" type="xs:boolean"/> + </xs:complexType> + </xs:element> + <!-- Highlighting specification --> + <xs:element name="highlighting"> + <xs:complexType> + <xs:sequence> + <xs:element minOccurs="0" maxOccurs="unbounded" ref="list"/> + <xs:element ref="contexts"/> + <xs:element ref="itemDatas"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <!-- + List of items + name: Name of this list + --> + <xs:element name="list"> + <xs:complexType> + <xs:sequence> + <xs:element minOccurs="0" maxOccurs="unbounded" ref="item"/> + </xs:sequence> + <xs:attribute name="name" use="required"/> + </xs:complexType> + </xs:element> + <!-- + List item + contains string used in <keyword> + --> + <xs:element name="item" type="xs:string"/> + <!-- List of contexts --> + <xs:element name="contexts"> + <xs:complexType> + <xs:sequence> + <xs:element maxOccurs="unbounded" ref="context"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <!-- + context specification + name: The name of this context specification. Used in '*Context' attributes [optional] + attribute: The name of the ItemData to be used for matching text + lineEndContext: Next context if end of line is encountered + lineEmptyContext: Next context if an empty line is encountered [optional] + fallthrough: Use a fallthrough context [optional] + fallthroughContext: Fall through to this context [optional] + dynamic: Dynamic context [boolean, optional] + noIndentationBasedFolding: Python uses indentation based folding. However, Python has parts where + it does not use indentation based folding (e.g. for """ strings). In this case + switch to an own context and set this attribute to true. Then the indentation + based folding will ignore this parts and not change folding markers. [optional] + + TODO: + - Explain fallthrough. + - Do we need fallthrough at all? It could be true, if fallthroughContext is set, false otherwise. + - Make lineEndContext optional, defaults to '#stay'. Reasonable? + --> + <xs:element name="context"> + <xs:complexType> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="keyword"/> + <xs:element ref="Float"/> + <xs:element ref="HlCOct"/> + <xs:element ref="HlCHex"/> + <xs:element ref="HlCFloat"/> + <xs:element ref="Int"/> + <xs:element ref="DetectChar"/> + <xs:element ref="Detect2Chars"/> + <xs:element ref="AnyChar"/> + <xs:element ref="StringDetect"/> + <xs:element ref="WordDetect"/> + <xs:element ref="RegExpr"/> + <xs:element ref="LineContinue"/> + <xs:element ref="HlCStringChar"/> + <xs:element ref="RangeDetect"/> + <xs:element ref="HlCChar"/> + <xs:element ref="IncludeRules"/> + <xs:element ref="DetectSpaces"/> + <xs:element ref="DetectIdentifier"/> + </xs:choice> + <xs:attribute name="name"/> + <xs:attribute name="attribute" use="required"/> + <xs:attribute name="lineEndContext" use="required"/> + <xs:attribute name="lineEmptyContext"/> + <xs:attribute name="fallthrough" type="xs:boolean"/> + <xs:attribute name="fallthroughContext"/> + <xs:attribute name="dynamic" type="xs:boolean"/> + <xs:attribute name="noIndentationBasedFolding" type="xs:boolean"/> + </xs:complexType> + </xs:element> + <!-- + Common attributes + attribute: The name of the ItemData to be used for matching text + context: The name of the context to go to when this rule matches + beginRegion: Begin a region of type beginRegion [optional] + endRegion: End a region of type endRegion [optional] + firstNonSpace: should this rule only match at first non-space char in line? + column: should this rule only match at given column in line (column == count of chars in front) + --> + <xs:attributeGroup name="commonAttributes"> + <xs:attribute name="attribute"/> + <xs:attribute name="context"/> + <xs:attribute name="beginRegion"/> + <xs:attribute name="endRegion"/> + <xs:attribute name="lookAhead" type="xs:boolean"/> + <xs:attribute name="firstNonSpace" type="xs:boolean"/> + <xs:attribute name="column" type="xs:integer"/> + </xs:attributeGroup> + <!-- + Detect members of a keyword list + commonAttributes: Common attributes + insensitive: Is this list case-insensitive? [boolean, optional, see note] + String: Name of the list + weakDelimiter: Use weak deliminator + + By default, case sensitivity is determined from <keywords casesensitive> in + <general> (default=true), but can be overridden per-list with 'insensitive'. + + TODO: + - Should be weakDeliminator + - Explain deliminator + - Doesn't seem to be supported in highligh.cpp + --> + <xs:element name="keyword"> + <xs:complexType> + <xs:attributeGroup ref="commonAttributes"/> + <xs:attribute name="insensitive" type="xs:boolean"/> + <xs:attribute name="String" use="required"/> + <xs:attribute name="weakDelimiter"/> + </xs:complexType> + </xs:element> + <!-- + Detect a floating point number + commonAttributes: Common attributes + --> + <xs:element name="Float"> + <xs:complexType> + <xs:attributeGroup ref="commonAttributes"/> + </xs:complexType> + </xs:element> + <!-- + Detect an octal number + commonAttributes: Common attributes + --> + <xs:element name="HlCOct"> + <xs:complexType> + <xs:attributeGroup ref="commonAttributes"/> + </xs:complexType> + </xs:element> + <!-- + Detect a hexadecimal number + commonAttributes: Common attributes + --> + <xs:element name="HlCHex"> + <xs:complexType> + <xs:attributeGroup ref="commonAttributes"/> + </xs:complexType> + </xs:element> + <!-- + Detect a C-style floating point number + commonAttributes: Common attributes + --> + <xs:element name="HlCFloat"> + <xs:complexType> + <xs:attributeGroup ref="commonAttributes"/> + </xs:complexType> + </xs:element> + <!-- + Detect C-style character + commonAttributes: Common attributes + + TODO + - Did I get this right? + --> + <xs:element name="HlCChar"> + <xs:complexType> + <xs:attributeGroup ref="commonAttributes"/> + </xs:complexType> + </xs:element> + <!-- + Detect an integer number + commonAttributes: Common attributes + --> + <xs:element name="Int"> + <xs:complexType> + <xs:attributeGroup ref="commonAttributes"/> + </xs:complexType> + </xs:element> + <!-- + Detect a single character + commonAttributes: Common attributes + char: The character to look for + dynamic: Uses 1 .. 9 as placeholders for dynamic arguments (in fact, first char of arg...) [boolean, optional, default=false] + --> + <xs:element name="DetectChar"> + <xs:complexType> + <xs:attributeGroup ref="commonAttributes"/> + <xs:attribute name="char" use="required"/> + <xs:attribute name="dynamic" type="xs:boolean"/> + </xs:complexType> + </xs:element> + <!-- + Detect two characters + commonAttributes: Common attributes + char: The first character + char1: The second character + --> + <xs:element name="Detect2Chars"> + <xs:complexType> + <xs:attributeGroup ref="commonAttributes"/> + <xs:attribute name="char" use="required"/> + <xs:attribute name="char1" use="required"/> + </xs:complexType> + </xs:element> + <!-- + Detect any group of characters + commonAttributes: Common attributes + String: A string representing the characters to look for + + TODO + - Description is not descriptive enough, I'm not sure what it exactly does:-( + --> + <xs:element name="AnyChar"> + <xs:complexType> + <xs:attributeGroup ref="commonAttributes"/> + <xs:attribute name="String" use="required"/> + </xs:complexType> + </xs:element> + <!-- + Detect a string + commonAttributes: Common attributes + String: The string to look for + insensitive: Whether the string is matched case INsensitive. [boolean, optional, default=false] + dynamic: Uses %1 .. %9 as placeholders for dynamic arguments [boolean, optional, default=false] + + TODO + - What's default of insensitive? I'm not sure... + --> + <xs:element name="StringDetect"> + <xs:complexType> + <xs:attributeGroup ref="commonAttributes"/> + <xs:attribute name="String" use="required"/> + <xs:attribute name="insensitive" type="xs:boolean"/> + <xs:attribute name="dynamic" type="xs:boolean"/> + </xs:complexType> + </xs:element> + <!-- + Detect a word, i.e. a string at word boundaries + commonAttributes: Common attributes + String: The string to look for + insensitive: Whether the string is matched case INsensitive. [boolean, optional, default=false] + + TODO + - What's default of insensitive? I'm not sure... + --> + <xs:element name="WordDetect"> + <xs:complexType> + <xs:attributeGroup ref="commonAttributes"/> + <xs:attribute name="String" use="required"/> + <xs:attribute name="insensitive" type="xs:boolean"/> + </xs:complexType> + </xs:element> + <!-- + Detect a match of a regular expression + commonAttributes: Common attributes + String: The regular expression pattern + insensitive: Whether the text is matched case INsensitive. [boolean, optional, default=false] + minimal: Wheather to use minimal matching for wild cards in the pattern [boolean, optional, default='false'] + dynamic: Uses %1 .. %9 as placeholders for dynamic arguments [boolean, optional, default=false] + --> + <xs:element name="RegExpr"> + <xs:complexType> + <xs:attributeGroup ref="commonAttributes"/> + <xs:attribute name="String" use="required"/> + <xs:attribute name="insensitive" type="xs:boolean"/> + <xs:attribute name="minimal" type="xs:boolean"/> + <xs:attribute name="dynamic" type="xs:boolean"/> + </xs:complexType> + </xs:element> + <!-- + Detect a line continuation + commonAttributes: Common attributes + char: The char marking the end of line [char, optional, default='\\'] + --> + <xs:element name="LineContinue"> + <xs:complexType> + <xs:attributeGroup ref="commonAttributes"/> + <xs:attribute name="char"/> + </xs:complexType> + </xs:element> + <!-- + Detect a C-style escaped character + commonAttributes: Common attributes + + TODO: + - Did I get this right? Only one character, or a string? + --> + <xs:element name="HlCStringChar"> + <xs:complexType> + <xs:attributeGroup ref="commonAttributes"/> + </xs:complexType> + </xs:element> + <!-- + Detect a range of characters + commonAttributes: Common attributes + char: The character starting the range + char1: The character terminating the range + --> + <xs:element name="RangeDetect"> + <xs:complexType> + <xs:attributeGroup ref="commonAttributes"/> + <xs:attribute name="char" use="required"/> + <xs:attribute name="char1" use="required"/> + </xs:complexType> + </xs:element> + <!-- + Include Rules of another context + context: The name of the context to include + includeAttrib: If this is true, the host context of the IncludeRules + will be given the attribute of the source context + --> + <xs:element name="IncludeRules"> + <xs:complexType> + <xs:attribute name="context" use="required"/> + <xs:attribute name="includeAttrib" type="xs:boolean"/> + </xs:complexType> + </xs:element> + <!-- Detect all following Spaces --> + <xs:element name="DetectSpaces"> + <xs:complexType> + <xs:attributeGroup ref="commonAttributes"/> + </xs:complexType> + </xs:element> + <!-- Detect an Identifier ( == LETTER(LETTER|NUMBER|_)*) --> + <xs:element name="DetectIdentifier"> + <xs:complexType> + <xs:attributeGroup ref="commonAttributes"/> + </xs:complexType> + </xs:element> + <!-- List of attributes --> + <xs:element name="itemDatas"> + <xs:complexType> + <xs:sequence> + <xs:element maxOccurs="unbounded" ref="itemData"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <!-- + Attribute specification + name CDATA #REQUIRED The name of this attribute + defStyleNum CDATA #REQUIRED The index of the default style to use + color CDATA #IMPLIED Color for this style, either a hex triplet, a name or some other format recognized by Qt [optional] + selColor CDATA #IMPLIED The color for this style when text is selected [optional] + italic CDATA #IMPLIED Whether this attribute should be rendered using an italic typeface [optional, boolean, default=false] + bold CDATA #IMPLIED Whether this attribute should be renederd using a bold typeface [optional, boolean, default=false] + underline CDATA #IMPLIED Whether this attribute should be underlined [optional, boolean, default=false] + strikeOut CDATA #IMPLIED Whether this attribute should be striked out [optional, boolean, default=false] + backgroundColor CDATA #IMPLIED The background color for this style [optional] + selBackgroundColor CDATA #IMPLIED The background color for this style when text is selected [optional] + spellChecking CDATA #IMPLIED Whether this attribute should be spell checked [optional, boolean, default=true] + --> + <xs:element name="itemData"> + <xs:complexType> + <xs:attribute name="name" use="required"/> + <xs:attribute name="defStyleNum" use="required" type="defStyles"/> + <xs:attribute name="color"/> + <xs:attribute name="selColor"/> + <xs:attribute name="italic" type="xs:boolean"/> + <xs:attribute name="bold" type="xs:boolean"/> + <xs:attribute name="underline" type="xs:boolean"/> + <xs:attribute name="strikeOut" type="xs:boolean"/> + <xs:attribute name="backgroundColor"/> + <xs:attribute name="selBackgroundColor"/> + <xs:attribute name="spellChecking" type="xs:boolean"/> + </xs:complexType> + </xs:element> + <!-- Spellchecking specification --> + <xs:element name="spellchecking"> + <xs:complexType> + <xs:sequence> + <xs:element minOccurs="0" ref="encodings"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <!-- List of character encodings --> + <xs:element name="encodings"> + <xs:complexType> + <xs:sequence> + <xs:element maxOccurs="unbounded" ref="encoding"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <!-- + Encoding specification + sequence CDATA #REQUIRED Character sequence of the encoding; must not contain new-line characters, i.e. \n or \r + character CDATA #IMPLIED Encoded character; must be of length 1 + ignored (%boolean;) #IMPLIED If true, then the encoding sequence is ignored for spellchecking + --> + <xs:element name="encoding"> + <xs:complexType> + <xs:attribute name="string" use="required"/> + <xs:attribute name="char"/> + <xs:attribute name="ignored" type="xs:boolean"/> + </xs:complexType> + </xs:element> +</xs:schema> diff --git a/src/libs/3rdparty/syntax-highlighting/data/schema/validatehl.sh b/src/libs/3rdparty/syntax-highlighting/data/schema/validatehl.sh new file mode 100644 index 0000000000..06bf60ce35 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/schema/validatehl.sh @@ -0,0 +1,2 @@ +#!/bin/sh +xmllint --noout --schema language.xsd $@ diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax-data.qrc.in b/src/libs/3rdparty/syntax-highlighting/data/syntax-data.qrc.in new file mode 100644 index 0000000000..352d3f035b --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax-data.qrc.in @@ -0,0 +1,7 @@ +<!DOCTYPE RCC> +<RCC version="1.0"> +<qresource prefix="/org.kde.syntax-highlighting/syntax"> +<file alias="index.katesyntax">@CMAKE_CURRENT_BINARY_DIR@/index.katesyntax</file> +@SYNTAX_DATA_QRC_FILES_STRING@ +</qresource> +</RCC> diff --git a/src/share/3rdparty/generic-highlighter/alert.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/alert.xml index ec881f1503..ec881f1503 100644 --- a/src/share/3rdparty/generic-highlighter/alert.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/alert.xml diff --git a/src/share/3rdparty/generic-highlighter/bash.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/bash.xml index cdfdf95844..cdfdf95844 100644 --- a/src/share/3rdparty/generic-highlighter/bash.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/bash.xml diff --git a/src/share/3rdparty/generic-highlighter/cmake.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/cmake.xml index 2a9088b46c..2a9088b46c 100644 --- a/src/share/3rdparty/generic-highlighter/cmake.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/cmake.xml diff --git a/src/share/3rdparty/generic-highlighter/css.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/css.xml index 25a614e826..25a614e826 100644 --- a/src/share/3rdparty/generic-highlighter/css.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/css.xml diff --git a/src/share/3rdparty/generic-highlighter/doxygen.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/doxygen.xml index 99b1d79c02..99b1d79c02 100644 --- a/src/share/3rdparty/generic-highlighter/doxygen.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/doxygen.xml diff --git a/src/share/3rdparty/generic-highlighter/dtd.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/dtd.xml index 5c39c1b597..5c39c1b597 100644 --- a/src/share/3rdparty/generic-highlighter/dtd.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/dtd.xml diff --git a/src/share/3rdparty/generic-highlighter/html.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/html.xml index 4f9eb962d7..4f9eb962d7 100644 --- a/src/share/3rdparty/generic-highlighter/html.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/html.xml diff --git a/src/share/3rdparty/generic-highlighter/ini.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/ini.xml index 465422f0b0..465422f0b0 100644 --- a/src/share/3rdparty/generic-highlighter/ini.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/ini.xml diff --git a/src/share/3rdparty/generic-highlighter/java.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/java.xml index f59415048e..f59415048e 100644 --- a/src/share/3rdparty/generic-highlighter/java.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/java.xml diff --git a/src/share/3rdparty/generic-highlighter/javadoc.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/javadoc.xml index e72488b221..e72488b221 100644 --- a/src/share/3rdparty/generic-highlighter/javadoc.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/javadoc.xml diff --git a/src/share/3rdparty/generic-highlighter/json.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/json.xml index 28ad8e8a33..28ad8e8a33 100644 --- a/src/share/3rdparty/generic-highlighter/json.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/json.xml diff --git a/src/share/3rdparty/generic-highlighter/makefile.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/makefile.xml index 6067a2470f..6067a2470f 100644 --- a/src/share/3rdparty/generic-highlighter/makefile.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/makefile.xml diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/markdown.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/markdown.xml new file mode 100644 index 0000000000..39ffaf77af --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/markdown.xml @@ -0,0 +1,148 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Kate syntax highlight filter for Markdown/MultiMarkdown documents. + + Copyright 2008 Darrin Yeager. http://www.dyeager.org/ + Dual-Licensed under both GPL and BSD licenses. + + Extended 2009 Claes Holmerson. http://github.com/claes/kate-markdown/ +--> +<!-- + The [^\s]{1} is in the regex to avoid interfering with bullet list which + starts "* item". Thus emphasis/strong MUST be formed like *words here* + with the asterisks next to the beginning of the first word. + + Match space or newline, followed by "*", followed by one non-space, + followed by anything non-asterisk, followed by "*", followed by + space, end-of-sentence punctuation, or the end of the line. +--> +<!DOCTYPE language SYSTEM "language.dtd" +[ +<!ENTITY strongemphasisregex "(\s|^)[\*_]{3}[^\*_]+[\*_]{3}(\s|\.|,|;|:|\-|\?|$)"> +<!ENTITY strongregex "(\s|^)[\*_]{2}[^\s]{1}[^\*_]+[\*_]{2}(\s|\.|,|;|:|\-|\?|$)"> +<!ENTITY emphasisregex "(\s|^)[\*_]{1}[^\s]{1}[^\*_]+[\*_]{1}(\s|\.|,|;|:|\-|\?|$)"> +<!ENTITY reflinkregex '\[[^\]\^]+\]\s*\[[^\]]*\]\s*(\s+\"[^\"]*\"){0,1}'> +<!ENTITY reflinktargetregex '\[[^\]\^]+\]\:\s+[^\s]+(\s+\"[^\"]*\"){0,1}'> +<!ENTITY footnoteregex "\[\^[^\]]+\]"> +<!ENTITY inlinelinkregex "\[[^\]\^]+\]\s*\([^\(]*\)"> +<!ENTITY inlineimageregex "\!\[[^\]\^]+\]\([^\(]*\)"> +<!ENTITY refimageregex "\!\[[^\]\^]+\]\[[^\[]*\]"> +<!ENTITY autolinkregex '<(https?|ftp):[^\">\s]+>'> +<!ENTITY mailtolinkregex "<(?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>"> +<!ENTITY rulerregex "\s*([\*\-_]\s?){3,}\s*"> +<!-- two spaces at end of line generates linebreak --> +<!ENTITY linebreakregex " $"> +<!ENTITY strikeoutregex "[~]{2}[^~].*[^~][~]{2}"> +<!-- pandoc style --> +]> +<language name="Markdown" version="3" kateversion="3.8" section="Markup" extensions="*.md;*.mmd;*.markdown" priority="15" author="Darrin Yeager, Claes Holmerson" license="GPL,BSD"> + <highlighting> + <contexts> + <context attribute="Normal Text" lineEndContext="#stay" name="Normal Text"> + <DetectChar context="blockquote" char=">" column="0"/> + <RegExpr attribute="h1" String="^#\s.*[#]?$"/> + <RegExpr attribute="h2" String="^##\s.*[#]?$"/> + <RegExpr attribute="h3" String="^###\s.*[#]?$"/> + <RegExpr attribute="h4" String="^####\s.*[#]?$"/> + <RegExpr attribute="h5" String="^#####\s.*[#]?$"/> + <RegExpr attribute="h6" String="^######\s.*[#]?$"/> + <RegExpr attribute="ruler" String="&rulerregex;"/> + <RegExpr attribute="strong" String="&strongregex;"/> + <RegExpr attribute="emphasis" String="&emphasisregex;"/> + <RegExpr attribute="strongemphasis" String="&strongemphasisregex;"/> + <RegExpr attribute="code" String="^([\s]{4,}|\t+).*$"/> + <RegExpr context="bullet" String="^[\*\+\-]\s"/> + <RegExpr context="numlist" String="^[\d]+\.\s"/> + <RegExpr attribute="meta" String="^(Title|Author|Date|Copyright|Revision|CSS|LaTeX\ XSLT|Categories|Tags|BaseName|Excerpt):(.*)+$"/> + <IncludeRules context="inc"/> + </context> + <context attribute="blockquote" lineEndContext="#stay" lineEmptyContext="#pop" name="blockquote"> + <RegExpr attribute="bq-strong" String="&strongregex;"/> + <RegExpr attribute="bq-emphasis" String="&emphasisregex;"/> + <IncludeRules context="inc"/> + </context> + <context attribute="bullet" lineEndContext="#stay" lineEmptyContext="#pop" name="bullet"> + <RegExpr attribute="bl-strong" String="&strongregex;"/> + <RegExpr attribute="bl-emphasis" String="&emphasisregex;"/> + <IncludeRules context="inc"/> + </context> + <context attribute="numlist" lineEndContext="#stay" lineEmptyContext="#pop" name="numlist"> + <RegExpr attribute="nl-strong" String="&strongregex;"/> + <RegExpr attribute="nl-emphasis" String="&emphasisregex;"/> + <IncludeRules context="inc"/> + </context> + <context attribute="comment" lineEndContext="#stay" name="comment"> + <RegExpr String="-->" attribute="comment" context="#pop" endRegion="comment"/> + </context> + <context attribute="code" lineEndContext="#stay" name="php-code"> + <WordDetect attribute="code" context="#pop" String="```"/> + <IncludeRules context="phpsource##PHP/PHP"/> + </context> + <context attribute="code" lineEndContext="#stay" name="python-code"> + <WordDetect attribute="code" context="#pop" String="```"/> + <IncludeRules context="##Python"/> + </context> + <context attribute="code" lineEndContext="#stay" name="code"> + <WordDetect attribute="code" context="#pop" String="```"/> + </context> + <context attribute="common" name="inc" lineEndContext="#stay"> + <RegExpr attribute="code" String="`[^`]+`"/> + <RegExpr context="comment" String="<!--" beginRegion="comment"/> + <RegExpr attribute="reflink" String="&reflinkregex;"/> + <RegExpr attribute="footnote" String="&footnoteregex;"/> + <RegExpr attribute="inlinelink" String="&inlinelinkregex;"/> + <RegExpr attribute="reflinktarget" String="&reflinktargetregex;"/> + <RegExpr attribute="inlineimage" String="&inlineimageregex;"/> + <RegExpr attribute="refimage" String="&refimageregex;"/> + <RegExpr attribute="autolink" String="&autolinkregex;"/> + <RegExpr attribute="mailtolink" String="&mailtolinkregex;"/> + <RegExpr attribute="strikeout" minimal="true" String="&strikeoutregex;"/> + <RegExpr attribute="linebreak" minimal="true" String="&linebreakregex;"/> + <WordDetect attribute="code" context="php-code" String="```php"/> + <WordDetect attribute="code" context="python-code" String="```python"/> + <StringDetect attribute="code" context="code" String="```"/> + </context> + </contexts> + <itemDatas> + <itemData name="Normal Text" defStyleNum="dsNormal"/> + <itemData name="common" defStyleNum="dsNormal"/> + <itemData name="strongemphasis" defStyleNum="dsNormal" italic="true" bold="true"/> + <itemData name="emphasis" defStyleNum="dsNormal" italic="true"/> + <itemData name="strong" defStyleNum="dsNormal" bold="true"/> + <itemData name="ruler" defStyleNum="dsNormal" bold="true"/> + <itemData name="strikeout" defStyleNum="dsNormal" strikeOut="true"/> + <itemData name="linebreak" defStyleNum="dsNormal" underline="true" color="#999999"/> + <itemData name="h1" defStyleNum="dsFunction" bold="true"/> + <itemData name="h2" defStyleNum="dsFunction" bold="true"/> + <itemData name="h3" defStyleNum="dsFunction" bold="true"/> + <itemData name="h4" defStyleNum="dsFunction" bold="true"/> + <itemData name="h5" defStyleNum="dsFunction" bold="true"/> + <itemData name="h6" defStyleNum="dsFunction" bold="true"/> + <itemData name="blockquote" defStyleNum="dsDataType"/> + <itemData name="bq-emphasis" defStyleNum="dsDataType" italic="true"/> + <itemData name="bq-strong" defStyleNum="dsDataType" bold="true"/> + <itemData name="bullet" defStyleNum="dsFloat"/> + <itemData name="bl-emphasis" defStyleNum="dsFloat" italic="true"/> + <itemData name="bl-strong" defStyleNum="dsFloat" bold="true"/> + <itemData name="numlist" defStyleNum="dsFloat"/> + <itemData name="nl-emphasis" defStyleNum="dsFloat" italic="true"/> + <itemData name="nl-strong" defStyleNum="dsFloat" bold="true"/> + <itemData name="comment" defStyleNum="dsComment"/> + <itemData name="code" defStyleNum="dsBaseN"/> + <itemData name="reflink" defStyleNum="dsOthers" underline="true"/> + <itemData name="inlinelink" defStyleNum="dsOthers" underline="true"/> + <itemData name="autolink" defStyleNum="dsOthers" underline="true"/> + <itemData name="mailtolink" defStyleNum="dsOthers" underline="true"/> + <itemData name="footnote" defStyleNum="dsOthers" italic="true"/> + <itemData name="meta" defStyleNum="dsComment"/> + <itemData name="reflinktarget" defStyleNum="dsOthers" italic="false" bold="false"/> + <itemData name="inlineimage" defStyleNum="dsAlert" italic="false" bold="false"/> + <itemData name="refimage" defStyleNum="dsAlert" italic="false" bold="false"/> + </itemDatas> + </highlighting> + <general> + <comments> + <comment name="multiLine" start="<!--" end="-->" region="comment"/> + </comments> + </general> +</language> diff --git a/src/share/3rdparty/generic-highlighter/perl.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/perl.xml index cd3d3ce65c..cd3d3ce65c 100644 --- a/src/share/3rdparty/generic-highlighter/perl.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/perl.xml diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/powershell.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/powershell.xml new file mode 100644 index 0000000000..8208fd7aae --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/powershell.xml @@ -0,0 +1,934 @@ +<!DOCTYPE language SYSTEM "language.dtd"> +<language + name="PowerShell" + version="4" + kateversion="5.0" + extensions="*.ps1;*.ps1m;*.ps1d" + section="Scripts" + author="Motoki Kashihara (motoki8791@gmail.com); Michael Lombardi (Michael.T.Lombardi@outlook.com)" + casesensitive="0" + license="MIT"> + <highlighting> + <list name="keywords"> + <item>Begin</item> + <item>Exit</item> + <item>Process</item> + <item>Break</item> + <item>Filter</item> + <item>Return</item> + <item>Catch</item> + <item>Finally</item> + <item>Sequence</item> + <item>Class</item> + <item>For</item> + <item>Switch</item> + <item>Continue</item> + <item>ForEach</item> + <item>Throw</item> + <item>Data</item> + <item>From</item> + <item>Trap</item> + <item>Define</item> + <item>Function</item> + <item>Try</item> + <item>Do</item> + <item>If</item> + <item>Until</item> + <item>DynamicParam</item> + <item>In</item> + <item>Using</item> + <item>Else</item> + <item>InlineScript</item> + <item>Var</item> + <item>ElseIf</item> + <item>Parallel</item> + <item>While</item> + <item>End</item> + <item>Param</item> + <item>Workflow</item> + </list> +<!-- TODO: Seems unused?! + <list name="attributes"> + <item>CmdletBinding</item> + <item>ConfirmImpact</item> + <item>DefaultParameterSetName</item> + <item>HelpURI</item> + <item>SupportsPaging</item> + <item>SupportsShouldProcess</item> + <item>PositionalBinding</item> + </list>--> + <list name="types"> + <item>bool</item> + <item>byte</item> + <item>char</item> + <item>decimal</item> + <item>double</item> + <item>float</item> + <item>int</item> + <item>long</item> + <item>object</item> + <item>sbyte</item> + <item>short</item> + <item>string</item> + <item>switch</item> + <item>uint</item> + <item>ulong</item> + <item>ushort</item> + </list> +<!-- TODO: Seems unused?! + <list name="operators"> + <item>-split</item> + <item>-isplit</item> + <item>-csplit</item> + <item>-join</item> + <item>-is</item> + <item>-isnot</item> + <item>-as</item> + <item>-eq</item> + <item>-ieq</item> + <item>-ceq</item> + <item>-ne</item> + <item>-ine</item> + <item>-cne</item> + <item>-gt</item> + <item>-igt</item> + <item>-cgt</item> + <item>-ge</item> + <item>-ige</item> + <item>-cge</item> + <item>-lt</item> + <item>-ilt</item> + <item>-clt</item> + <item>-le</item> + <item>-ile</item> + <item>-cle</item> + <item>-like</item> + <item>-ilike</item> + <item>-clike</item> + <item>-notlike</item> + <item>-inotlike</item> + <item>-cnotlike</item> + <item>-match</item> + <item>-imatch</item> + <item>-cmatch</item> + <item>-notmatch</item> + <item>-inotmatch</item> + <item>-cnotmatch</item> + <item>-contains</item> + <item>-icontains</item> + <item>-ccontains</item> + <item>-notcontains</item> + <item>-inotcontains</item> + <item>-cnotcontains</item> + <item>-replace</item> + <item>-ireplace</item> + <item>-creplace</item> + <item>-band</item> + <item>-bor</item> + <item>-bxor</item> + <item>-and</item> + <item>-or</item> + <item>-xor</item> + <item>.</item> + <item>&</item> + <item>=</item> + <item>+=</item> + <item>-=</item> + <item>*=</item> + <item>/=</item> + <item>%=</item> + </list>--> + <list name="cmdlets"> + <item>Add-Content</item> + <item>Add-ADComputerServiceAccount</item> + <item>Add-ADDomainControllerPasswordReplicationPolicy</item> + <item>Add-ADFineGrainedPasswordPolicySubject</item> + <item>Add-ADGroupMember</item> + <item>Add-ADPrincipalGroupMembership</item> + <item>Add-BitsFile</item> + <item>Add-ClusterDisk</item> + <item>Add-ClusterFileServerRole</item> + <item>Add-ClusterGenericApplicationRole</item> + <item>Add-ClusterGenericScriptRole</item> + <item>Add-ClusterGenericServiceRole</item> + <item>Add-ClusterGroup</item> + <item>Add-ClusterNode</item> + <item>Add-ClusterPrintServerRole</item> + <item>Add-ClusterResource</item> + <item>Add-ClusterResourceDependency</item> + <item>Add-ClusterResourceType</item> + <item>Add-ClusterServerRole</item> + <item>Add-ClusterSharedVolume</item> + <item>Add-ClusterVirtualMachineRole</item> + <item>Add-Computer</item> + <item>Add-Content</item> + <item>Add-History</item> + <item>Add-JobTrigger</item> + <item>Add-Member</item> + <item>Add-NlbClusterNode</item> + <item>Add-NlbClusterNodeDip</item> + <item>Add-NlbClusterPortRule</item> + <item>Add-NlbClusterVip</item> + <item>Add-PSSnapin</item> + <item>Add-Type</item> + <item>Backup-GPO</item> + <item>Block-ClusterAccess</item> + <item>Checkpoint-Computer</item> + <item>Clear-ADAccountExpiration</item> + <item>Clear-ClusterDiskReservation</item> + <item>Clear-ClusterNode</item> + <item>Clear-Content</item> + <item>Clear-EventLog</item> + <item>Clear-History</item> + <item>Clear-Item</item> + <item>Clear-ItemProperty</item> + <item>Clear-RecycleBin</item> + <item>Clear-Variable</item> + <item>Compare-Object</item> + <item>Complete-BitsTransfer</item> + <item>Complete-Transaction</item> + <item>Connect-PSSession</item> + <item>Connect-WSMan</item> + <item>ConvertFrom-Csv</item> + <item>ConvertFrom-Json</item> + <item>ConvertFrom-SecureString</item> + <item>ConvertFrom-String</item> + <item>ConvertFrom-StringData</item> + <item>Convert-Path</item> + <item>Convert-String</item> + <item>ConvertTo-Csv</item> + <item>ConvertTo-Html</item> + <item>ConvertTo-Json</item> + <item>ConvertTo-SecureString</item> + <item>ConvertTo-Xml</item> + <item>Copy-GPO</item> + <item>Copy-Item</item> + <item>Copy-ItemProperty</item> + <item>Debug-Job</item> + <item>Debug-Process</item> + <item>Debug-Runspace</item> + <item>Disable-ADAccount</item> + <item>Disable-ADOptionalFeature</item> + <item>Disable-ComputerRestore</item> + <item>Disable-JobTrigger</item> + <item>Disable-NlbClusterPortRule</item> + <item>Disable-PSBreakpoint</item> + <item>Disable-PSRemoting</item> + <item>Disable-PSSessionConfiguration</item> + <item>Disable-RunspaceDebug</item> + <item>Disable-ScheduledJob</item> + <item>Disable-WSManCredSSP</item> + <item>Disconnect-PSSession</item> + <item>Disconnect-WSMan</item> + <item>Enable-ADAccount</item> + <item>Enable-ADOptionalFeature</item> + <item>Enable-ComputerRestore</item> + <item>Enable-JobTrigger</item> + <item>Enable-NlbClusterPortRule</item> + <item>Enable-PSBreakpoint</item> + <item>Enable-PSRemoting</item> + <item>Enable-PSSessionConfiguration</item> + <item>Enable-RunspaceDebug</item> + <item>Enable-ScheduledJob</item> + <item>Enable-WSManCredSSP</item> + <item>Enter-PSHostProcess</item> + <item>Enter-PSSession</item> + <item>Exit-PSHostProcess</item> + <item>Exit-PSSession</item> + <item>Export-Alias</item> + <item>Export-BinaryMiLog</item> + <item>Export-Clixml</item> + <item>Export-Console</item> + <item>Export-Counter</item> + <item>Export-Csv</item> + <item>Export-FormatData</item> + <item>Export-ModuleMember</item> + <item>Export-PSSession</item> + <item>Find-Package</item> + <item>Find-PackageProvider</item> + <item>ForEach-Object</item> + <item>Format-Custom</item> + <item>Format-List</item> + <item>Format-Table</item> + <item>Format-Wide</item> + <item>Get-Acl</item> + <item>Get-ADAccountAuthorizationGroup</item> + <item>Get-ADAccountResultantPasswordReplicationPolicy</item> + <item>Get-ADComputer</item> + <item>Get-ADComputerServiceAccount</item> + <item>Get-ADDefaultDomainPasswordPolicy</item> + <item>Get-ADDomain</item> + <item>Get-ADDomainController</item> + <item>Get-ADDomainControllerPasswordReplicationPolicy</item> + <item>Get-ADDomainControllerPasswordReplicationPolicyUsage</item> + <item>Get-ADFineGrainedPasswordPolicy</item> + <item>Get-ADFineGrainedPasswordPolicySubject</item> + <item>Get-ADForest</item> + <item>Get-ADGroup</item> + <item>Get-ADGroupMember</item> + <item>Get-ADObject</item> + <item>Get-ADOptionalFeature</item> + <item>Get-ADOrganizationalUnit</item> + <item>Get-ADPrincipalGroupMembership</item> + <item>Get-ADRootDSE</item> + <item>Get-ADServiceAccount</item> + <item>Get-ADUser</item> + <item>Get-ADUserResultantPasswordPolicy</item> + <item>Get-Alias</item> + <item>Get-AppLockerFileInformation</item> + <item>Get-AppLockerPolicy</item> + <item>Get-AuthenticodeSignature</item> + <item>Get-BitsTransfer</item> + <item>Get-ChildItem</item> + <item>Get-CimAssociatedInstance</item> + <item>Get-CimClass</item> + <item>Get-CimInstance</item> + <item>Get-CimSession</item> + <item>Get-Clipboard</item> + <item>Get-Cluster</item> + <item>Get-ClusterAccess</item> + <item>Get-ClusterAvailableDisk</item> + <item>Get-ClusterGroup</item> + <item>Get-ClusterLog</item> + <item>Get-ClusterNetwork</item> + <item>Get-ClusterNetworkInterfac</item> + <item>Get-ClusterNode</item> + <item>Get-ClusterOwnerNode</item> + <item>Get-ClusterParameter</item> + <item>Get-ClusterQuorum</item> + <item>Get-ClusterResource</item> + <item>Get-ClusterResourceDependency</item> + <item>Get-ClusterResourceDependencyReport</item> + <item>Get-ClusterResourceType</item> + <item>Get-ClusterSharedVolume</item> + <item>Get-CmsMessage</item> + <item>Get-Command</item> + <item>Get-ComputerRestorePoint</item> + <item>Get-Content</item> + <item>Get-ControlPanelItem</item> + <item>Get-Counter</item> + <item>Get-Credential</item> + <item>Get-Culture</item> + <item>Get-Date</item> + <item>Get-Event</item> + <item>Get-EventLog</item> + <item>Get-EventSubscriber</item> + <item>Get-ExecutionPolicy</item> + <item>Get-FormatData</item> + <item>Get-GPInheritance</item> + <item>Get-GPO</item> + <item>Get-GPOReport</item> + <item>Get-GPPermissions</item> + <item>Get-GPPrefRegistryValue</item> + <item>Get-GPRegistryValue</item> + <item>Get-GPResultantSetOfPolicy</item> + <item>Get-GPStarterGPO</item> + <item>Get-Help</item> + <item>Get-History</item> + <item>Get-Host</item> + <item>Get-HotFix</item> + <item>Get-Item</item> + <item>Get-ItemProperty</item> + <item>Get-ItemPropertyValue</item> + <item>Get-Job</item> + <item>Get-JobTrigger</item> + <item>Get-Location</item> + <item>Get-Member</item> + <item>Get-Module</item> + <item>Get-NlbCluster</item> + <item>Get-NlbClusterDriverInfo</item> + <item>Get-NlbClusterNode</item> + <item>Get-NlbClusterNodeDip</item> + <item>Get-NlbClusterNodeNetworkInterface</item> + <item>Get-NlbClusterPortRule</item> + <item>Get-NlbClusterVip</item> + <item>Get-Package</item> + <item>Get-PackageProvider</item> + <item>Get-PackageSource</item> + <item>Get-PfxCertificate</item> + <item>Get-Process</item> + <item>Get-PSBreakpoint</item> + <item>Get-PSCallStack</item> + <item>Get-PSDrive</item> + <item>Get-PSHostProcessInfo</item> + <item>Get-PSProvider</item> + <item>Get-PSReadlineKeyHandler</item> + <item>Get-PSReadlineOption</item> + <item>Get-PSSession</item> + <item>Get-PSSessionCapability</item> + <item>Get-PSSessionConfiguration</item> + <item>Get-PSSnapin</item> + <item>Get-Random</item> + <item>Get-Runspace</item> + <item>Get-RunspaceDebug</item> + <item>Get-ScheduledJob</item> + <item>Get-ScheduledJobOption</item> + <item>Get-Service</item> + <item>Get-TraceSource</item> + <item>Get-Transaction</item> + <item>Get-TroubleshootingPack</item> + <item>Get-TypeData</item> + <item>Get-UICulture</item> + <item>Get-Unique</item> + <item>Get-Variable</item> + <item>Get-WinEvent</item> + <item>Get-WmiObject</item> + <item>Get-WSManCredSSP</item> + <item>Get-WSManInstance</item> + <item>Grant-ClusterAccess</item> + <item>Group-Object</item> + <item>Import-Alias</item> + <item>Import-BinaryMiLog</item> + <item>Import-Clixml</item> + <item>Import-Counter</item> + <item>Import-Csv</item> + <item>Import-GPO</item> + <item>Import-LocalizedData</item> + <item>Import-Module</item> + <item>Import-PackageProvider</item> + <item>Import-PSSession</item> + <item>Install-ADServiceAccount</item> + <item>Install-Package</item> + <item>Install-PackageProvider</item> + <item>Invoke-CimMethod</item> + <item>Invoke-Command</item> + <item>Invoke-DscResource</item> + <item>Invoke-Expression</item> + <item>Invoke-History</item> + <item>Invoke-Item</item> + <item>Invoke-RestMethod</item> + <item>Invoke-TroubleshootingPack</item> + <item>Invoke-WebRequest</item> + <item>Invoke-WmiMethod</item> + <item>Invoke-WSManAction</item> + <item>Join-Path</item> + <item>Limit-EventLog</item> + <item>Measure-Command</item> + <item>Measure-Object</item> + <item>Move-ADDirectoryServer</item> + <item>Move-ADDirectoryServerOperationMasterRole</item> + <item>Move-ADObject</item> + <item>Move-ClusterGroup</item> + <item>Move-ClusterResource</item> + <item>Move-ClusterSharedVolume</item> + <item>Move-ClusterVirtualMachineRole</item> + <item>Move-Item</item> + <item>Move-ItemProperty</item> + <item>New-ADComputer</item> + <item>New-ADFineGrainedPasswordPolicy</item> + <item>New-ADGroup</item> + <item>New-ADObject</item> + <item>New-ADOrganizationalUnit</item> + <item>New-ADServiceAccount</item> + <item>New-ADUser</item> + <item>New-Alias</item> + <item>New-AppLockerPolicy</item> + <item>New-CimInstance</item> + <item>New-CimSession</item> + <item>New-CimSessionOption</item> + <item>New-Cluster</item> + <item>New-Event</item> + <item>New-EventLog</item> + <item>New-GPLink</item> + <item>New-GPO</item> + <item>New-GPStarterGPO</item> + <item>New-Item</item> + <item>New-ItemProperty</item> + <item>New-JobTrigger</item> + <item>New-Module</item> + <item>New-ModuleManifest</item> + <item>New-NlbCluster</item> + <item>New-NlbClusterIpv6Address</item> + <item>New-Object</item> + <item>New-PSDrive</item> + <item>New-PSRoleCapabilityFile</item> + <item>New-PSSession</item> + <item>New-PSSessionConfigurationFile</item> + <item>New-PSSessionOption</item> + <item>New-PSTransportOption</item> + <item>New-PSWorkflowExecutionOption</item> + <item>New-ScheduledJobOption</item> + <item>New-Service</item> + <item>New-TimeSpan</item> + <item>New-Variable</item> + <item>New-WebServiceProxy</item> + <item>New-WinEvent</item> + <item>New-WSManInstance</item> + <item>New-WSManSessionOption</item> + <item>Out-Default</item> + <item>Out-File</item> + <item>Out-GridView</item> + <item>Out-Host</item> + <item>Out-Null</item> + <item>Out-Printer</item> + <item>Out-String</item> + <item>Pop-Location</item> + <item>Protect-CmsMessage</item> + <item>Publish-DscConfiguration</item> + <item>Push-Location</item> + <item>Read-Host</item> + <item>Receive-Job</item> + <item>Receive-PSSession</item> + <item>Register-ArgumentCompleter</item> + <item>Register-CimIndicationEvent</item> + <item>Register-EngineEvent</item> + <item>Register-ObjectEvent</item> + <item>Register-PackageSource</item> + <item>Register-PSSessionConfiguration</item> + <item>Register-ScheduledJob</item> + <item>Register-WmiEvent</item> + <item>Remove-ADComputer</item> + <item>Remove-ADComputerServiceAccount</item> + <item>Remove-ADDomainControllerPasswordReplicationPolicy</item> + <item>Remove-ADFineGrainedPasswordPolicy</item> + <item>Remove-ADFineGrainedPasswordPolicySubject</item> + <item>Remove-ADGroup</item> + <item>Remove-ADGroupMember</item> + <item>Remove-ADObject</item> + <item>Remove-ADOrganizationalUnit</item> + <item>Remove-ADPrincipalGroupMembership</item> + <item>Remove-ADServiceAccount</item> + <item>Remove-ADUser</item> + <item>Remove-BitsTransfer</item> + <item>Remove-CimInstance</item> + <item>Remove-CimSession</item> + <item>Remove-Cluster</item> + <item>Remove-ClusterAccess</item> + <item>Remove-ClusterGroup</item> + <item>Remove-ClusterNode</item> + <item>Remove-ClusterResource</item> + <item>Remove-ClusterResourceDependency</item> + <item>Remove-ClusterResourceType</item> + <item>Remove-ClusterSharedVolume</item> + <item>Remove-Computer</item> + <item>Remove-Event</item> + <item>Remove-EventLog</item> + <item>Remove-GPLink</item> + <item>Remove-GPO</item> + <item>Remove-GPPrefRegistryValue</item> + <item>Remove-GPRegistryValue</item> + <item>Remove-Item</item> + <item>Remove-ItemProperty</item> + <item>Remove-Job</item> + <item>Remove-JobTrigger</item> + <item>Remove-Module</item> + <item>Remove-NlbCluster</item> + <item>Remove-NlbClusterNode</item> + <item>Remove-NlbClusterNodeDip</item> + <item>Remove-NlbClusterPortRule</item> + <item>Remove-NlbClusterVip</item> + <item>Remove-PSBreakpoint</item> + <item>Remove-PSDrive</item> + <item>Remove-PSReadlineKeyHandler</item> + <item>Remove-PSSession</item> + <item>Remove-PSSnapin</item> + <item>Remove-TypeData</item> + <item>Remove-Variable</item> + <item>Remove-WmiObject</item> + <item>Remove-WSManInstance</item> + <item>Rename-ADObject</item> + <item>Rename-Computer</item> + <item>Rename-GPO</item> + <item>Rename-Item</item> + <item>Rename-ItemProperty</item> + <item>Repair-ClusterSharedVolume</item> + <item>Reset-ADServiceAccountPassword</item> + <item>Reset-ComputerMachinePassword</item> + <item>Resolve-Path</item> + <item>Restart-Computer</item> + <item>Restart-Service</item> + <item>Restore-ADObject</item> + <item>Restore-Computer</item> + <item>Restore-GPO</item> + <item>Resume-BitsTransfer</item> + <item>Resume-ClusterNode</item> + <item>Resume-ClusterResource</item> + <item>Resume-Job</item> + <item>Resume-NlbCluster</item> + <item>Resume-NlbClusterNode</item> + <item>Resume-Service</item> + <item>Save-Help</item> + <item>Save-Package</item> + <item>Search-ADAccount</item> + <item>Select-Object</item> + <item>Select-String</item> + <item>Select-Xml</item> + <item>Send-MailMessage</item> + <item>Set-Acl</item> + <item>Set-ADAccountControl</item> + <item>Set-ADAccountExpiration</item> + <item>Set-ADAccountPassword</item> + <item>Set-ADComputer</item> + <item>Set-ADDefaultDomainPasswordPolicy</item> + <item>Set-ADDomain</item> + <item>Set-ADDomainMode</item> + <item>Set-ADFineGrainedPasswordPolicy</item> + <item>Set-ADForest</item> + <item>Set-ADForestMode</item> + <item>Set-ADGroup</item> + <item>Set-ADObject</item> + <item>Set-ADOrganizationalUnit</item> + <item>Set-ADServiceAccount</item> + <item>Set-ADUser</item> + <item>Set-Alias</item> + <item>Set-AppLockerPolicy</item> + <item>Set-AuthenticodeSignature</item> + <item>Set-BitsTransfer</item> + <item>Set-CimInstance</item> + <item>Set-Clipboard</item> + <item>Set-ClusterLog</item> + <item>Set-ClusterOwnerNode</item> + <item>Set-ClusterParameter</item> + <item>Set-ClusterQuorum</item> + <item>Set-ClusterResourceDependency</item> + <item>Set-Content</item> + <item>Set-Date</item> + <item>Set-DscLocalConfigurationManager</item> + <item>Set-ExecutionPolicy</item> + <item>Set-GPInheritance</item> + <item>Set-GPLink</item> + <item>Set-GPPermissions</item> + <item>Set-GPPrefRegistryValue</item> + <item>Set-GPRegistryValue</item> + <item>Set-Item</item> + <item>Set-ItemProperty</item> + <item>Set-JobTrigger</item> + <item>Set-Location</item> + <item>Set-NlbCluster</item> + <item>Set-NlbClusterNode</item> + <item>Set-NlbClusterNodeDip</item> + <item>Set-NlbClusterPortRule</item> + <item>Set-NlbClusterPortRuleNodeHandlingPriority</item> + <item>Set-NlbClusterPortRuleNodeWeight</item> + <item>Set-NlbClusterVip</item> + <item>Set-PackageSource</item> + <item>Set-PSBreakpoint</item> + <item>Set-PSDebug</item> + <item>Set-PSReadlineKeyHandler</item> + <item>Set-PSReadlineOption</item> + <item>Set-PSSessionConfiguration</item> + <item>Set-ScheduledJob</item> + <item>Set-ScheduledJobOption</item> + <item>Set-Service</item> + <item>Set-StrictMode</item> + <item>Set-TraceSource</item> + <item>Set-Variable</item> + <item>Set-WmiInstance</item> + <item>Set-WSManInstance</item> + <item>Set-WSManQuickConfig</item> + <item>Show-Command</item> + <item>Show-ControlPanelItem</item> + <item>Show-EventLog</item> + <item>Sort-Object</item> + <item>Split-Path</item> + <item>Start-BitsTransfer</item> + <item>Start-Cluster</item> + <item>Start-ClusterGroup</item> + <item>Start-ClusterNode</item> + <item>Start-ClusterResource</item> + <item>Start-DscConfiguration</item> + <item>Start-Job</item> + <item>Start-NlbCluster</item> + <item>Start-NlbClusterNode</item> + <item>Start-Process</item> + <item>Start-Service</item> + <item>Start-Sleep</item> + <item>Start-Transaction</item> + <item>Start-Transcript</item> + <item>Stop-Cluster</item> + <item>Stop-ClusterGroup</item> + <item>Stop-ClusterNode</item> + <item>Stop-ClusterResource</item> + <item>Stop-Computer</item> + <item>Stop-Job</item> + <item>Stop-NlbCluster</item> + <item>Stop-NlbClusterNode</item> + <item>Stop-Process</item> + <item>Stop-Service</item> + <item>Stop-Transcript</item> + <item>Suspend-BitsTransfer</item> + <item>Suspend-ClusterNode</item> + <item>Suspend-ClusterResource</item> + <item>Suspend-Job</item> + <item>Suspend-NlbCluster</item> + <item>Suspend-NlbClusterNode</item> + <item>Suspend-Service</item> + <item>Tee-Object</item> + <item>Test-AppLockerPolicy</item> + <item>Test-Cluster</item> + <item>Test-ClusterResourceFailure</item> + <item>Test-ComputerSecureChannel</item> + <item>Test-Connection</item> + <item>Test-DscConfiguration</item> + <item>Test-ModuleManifest</item> + <item>Test-Path</item> + <item>Test-PSSessionConfigurationFile</item> + <item>Test-WSMan</item> + <item>Trace-Command</item> + <item>Unblock-File</item> + <item>Undo-Transaction</item> + <item>Uninstall-ADServiceAccount</item> + <item>Uninstall-Package</item> + <item>Unlock-ADAccount</item> + <item>Unprotect-CmsMessage</item> + <item>Unregister-Event</item> + <item>Unregister-PackageSource</item> + <item>Unregister-PSSessionConfiguration</item> + <item>Unregister-ScheduledJob</item> + <item>Update-ClusterIPResource</item> + <item>Update-ClusterVirtualMachineConfiguration</item> + <item>Update-FormatData</item> + <item>Update-Help</item> + <item>Update-List</item> + <item>Update-TypeData</item> + <item>Use-Transaction</item> + <item>Wait-Debugger</item> + <item>Wait-Event</item> + <item>Wait-Job</item> + <item>Wait-Process</item> + <item>Where-Object</item> + <item>Write-Debug</item> + <item>Write-Error</item> + <item>Write-EventLog</item> + <item>Write-Host</item> + <item>Write-Information</item> + <item>Write-Output</item> + <item>Write-Progress</item> + <item>Write-Verbose</item> + <item>Write-Warning</item> + <item>ac</item> + <item>asnp</item> + <item>cat</item> + <item>cd</item> + <item>chdir</item> + <item>clc</item> + <item>clear</item> + <item>clhy</item> + <item>cli</item> + <item>clp</item> + <item>cls</item> + <item>clv</item> + <item>cnsn</item> + <item>compare</item> + <item>copy</item> + <item>cp</item> + <item>cpi</item> + <item>cpp</item> + <item>curl</item> + <item>cvpa</item> + <item>dbp</item> + <item>del</item> + <item>diff</item> + <item>dir</item> + <item>dnsn</item> + <item>ebp</item> + <item>echo</item> + <item>epal</item> + <item>epcsv</item> + <item>epsn</item> + <item>erase</item> + <item>etsn</item> + <item>exsn</item> + <item>fc</item> + <item>fl</item> + <item>foreach</item> + <item>ft</item> + <item>fw</item> + <item>gal</item> + <item>gbp</item> + <item>gc</item> + <item>gci</item> + <item>gcm</item> + <item>gcs</item> + <item>gdr</item> + <item>ghy</item> + <item>gi</item> + <item>gjb</item> + <item>gl</item> + <item>gm</item> + <item>gmo</item> + <item>gp</item> + <item>gps</item> + <item>group</item> + <item>gsn</item> + <item>gsnp</item> + <item>gsv</item> + <item>gu</item> + <item>gv</item> + <item>gwmi</item> + <item>h</item> + <item>history</item> + <item>icm</item> + <item>iex</item> + <item>ihy</item> + <item>ii</item> + <item>ipal</item> + <item>ipcsv</item> + <item>ipmo</item> + <item>ipsn</item> + <item>irm</item> + <item>ise</item> + <item>iwmi</item> + <item>iwr</item> + <item>kill</item> + <item>lp</item> + <item>ls</item> + <item>man</item> + <item>md</item> + <item>measure</item> + <item>mi</item> + <item>mount</item> + <item>move</item> + <item>mp</item> + <item>mv</item> + <item>nal</item> + <item>ndr</item> + <item>ni</item> + <item>nmo</item> + <item>npssc</item> + <item>nsn</item> + <item>nv</item> + <item>ogv</item> + <item>oh</item> + <item>popd</item> + <item>ps</item> + <item>pushd</item> + <item>pwd</item> + <item>r</item> + <item>rbp</item> + <item>rcjb</item> + <item>rcsn</item> + <item>rd</item> + <item>rdr</item> + <item>ren</item> + <item>ri</item> + <item>rjb</item> + <item>rm</item> + <item>rmdir</item> + <item>rmo</item> + <item>rni</item> + <item>rnp</item> + <item>rp</item> + <item>rsn</item> + <item>rsnp</item> + <item>rujb</item> + <item>rv</item> + <item>rvpa</item> + <item>rwmi</item> + <item>sajb</item> + <item>sal</item> + <item>saps</item> + <item>sasv</item> + <item>sbp</item> + <item>sc</item> + <item>select</item> + <item>set</item> + <item>shcm</item> + <item>si</item> + <item>sl</item> + <item>sleep</item> + <item>sls</item> + <item>sort</item> + <item>sp</item> + <item>spjb</item> + <item>spps</item> + <item>spsv</item> + <item>start</item> + <item>sujb</item> + <item>sv</item> + <item>swmi</item> + <item>tee</item> + <item>trcm</item> + <item>type</item> + <item>wget</item> + <item>where</item> + <item>wjb</item> + <item>write</item> + <item>\%</item> + <item>\?</item> + </list> + <list name="special-variables"> + <item>$_</item> + <item>$True</item> + <item>$False</item> + <item>$Env</item> + <item>$Null</item> + <item>$^</item> + <item>$$</item> + <item>$?</item> + <item>$input</item> + <item>$foreach</item> + <item>$args</item> + <item>$switch</item> + <item>$matches</item> + <item>$LastExitCode</item> + <item>$Error</item> + <item>$StackTrace</item> + <item>$HOME</item> + <item>$PsHome</item> + <item>$ConsoleFileName</item> + <item>$PWD</item> + <item>$ShellId</item> + <item>$Profile</item> + <item>$Host</item> + <item>$OFS</item> + </list> + <contexts> + <context attribute="Normal Text" lineEndContext="#stay" name="Normal"> + <keyword attribute="Keyword" context="#stay" String="keywords"/> + <keyword attribute="Data Type" context="#stay" String="types" /> + <IncludeRules context="Cmdlet" /> + <DetectChar attribute="String" context="String" char="""/> + <Detect2Chars attribute="HereString" context="HereStringer" char="@" char1=""" beginRegion="StringRegion"/> + <IncludeRules context="##Doxygen" /> + <DetectChar attribute="Comment" context="Commentar 1" char="#"/> + <Detect2Chars attribute="Comment" context="Commentar 2" char="<" char1="#" beginRegion="CommentRegion"/> + <DetectChar attribute="Symbol" context="#stay" char="{" beginRegion="block1"/> + <DetectChar attribute="Symbol" context="#stay" char="}" endRegion="block1"/> + <RegExpr attribute="Keyword" context="#stay" String="\b\$global(?=\s+(:))"/> + <RegExpr attribute="Keyword" context="#stay" String="\b\$script(?=\s+(:))"/> + <RegExpr attribute="Variable" context="#stay" String="\$+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*" /> + <keyword attribute="Special Variable" context="#stay" String="special-variables"/> + <RegExpr attribute="Symbol" context="Member" String="[.]{1,1}" /> + <AnyChar attribute="Symbol" context="#stay" String=":!%&()+,-/.*<=>?[]|~^;"/> + </context> + <context attribute="String" lineEndContext="#pop" name="String"> + <LineContinue attribute="String" context="#pop"/> + <DetectChar attribute="String" context="#pop" char="""/> + </context> + <context attribute="HereString" lineEndContext="#stay" name="HereStringer"> + <Detect2Chars attribute="HereString" context="#pop" char=""" char1="@" endRegion="StringRegion"/> + </context> + <context attribute="Normal Text" lineEndContext="#pop" name="Member" fallthrough="true" fallthroughContext="#pop"> + <RegExpr attribute="Function" context="#pop" String="\b[_\w][_\w\d]*(?=[\s]*)" /> + </context> + <context attribute="Comment" lineEndContext="#pop" name="Commentar 1"/> + <context attribute="Comment" lineEndContext="#stay" name="Commentar 2"> + <Detect2Chars attribute="Comment" context="#pop" char="#" char1=">" endRegion="CommentRegion"/> + </context> + <context attribute="Cmdlets" lineEndContext="#stay" name="Cmdlet"> + <keyword attribute="Function" context="#stay" String="cmdlets"/> + </context> + </contexts> + <itemDatas> + <itemData name="Normal Text" defStyleNum="dsNormal" spellChecking="false"/> + <itemData name="Keyword" defStyleNum="dsKeyword" spellChecking="false"/> + <itemData name="Function" defStyleNum="dsFunction" spellChecking="false"/> + <itemData name="Data Type" defStyleNum="dsDataType" spellChecking="false"/> + <itemData name="String" defStyleNum="dsString"/> + <itemData name="HereString" defStyleNum="dsVerbatimString"/> + <itemData name="Comment" defStyleNum="dsComment"/> + <itemData name="Cmdlets" defStyleNum="dsBuiltIn" spellChecking="false"/> + <itemData name="Symbol" defStyleNum="dsNormal" spellChecking="false"/> + <itemData name="Variable" defStyleNum="dsVariable" spellChecking="false"/> + <itemData name="Special Variable" defStyleNum="dsVariable" bold="1" spellChecking="false"/> + </itemDatas> + </highlighting> + <general> + <comments> + <comment name="singleLine" start="#" /> + <comment name="multiLine" start="<#" end="#>" region="CommentRegion"/> + </comments> + <keywords casesensitive="0" weakDeliminator=":-"/> + </general> +</language> diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/python.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/python.xml new file mode 100644 index 0000000000..33a313a694 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/python.xml @@ -0,0 +1,688 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE language> +<!-- Python syntax highlightning v0.9 by Per Wigren --> +<!-- Python syntax highlighting v1.9 by Michael Bueker (improved keyword differentiation) --> +<!-- Python syntax highlighting v1.97 by Paul Giannaros --> +<!-- Python syntax highlighting v1.99 by Primoz Anzur --> +<!-- Python syntax highlighting v2.01 by Paul Giannaros: + * full format character support + * unicode string modifier supported --> +<!-- v2.02 remove RegExpr for nums and make indent consistent --> +<!-- v2.03 highlight decorators, remove operator regex, don't highlight parens as operators --> +<!-- v2.04 make alerts visible even if they are directly after ''' or # without a space --> +<!-- v2.06 decorator names can (and often do) contain periods --> +<!-- v2.07 add support for %prog and co, see bug 142832 --> +<!-- v2.08 add missing overloaders, new Python 3 statements, builtins, and keywords --> +<!-- v2.29 recognize escape sequenzes correctly --> +<language name="Python" version="9" style="python" indenter="python" kateversion="5.0" section="Scripts" extensions="*.py;*.pyw;SConstruct;SConscript" mimetype="application/x-python;text/x-python;text/x-python3" casesensitive="1" author="Michael Bueker" license=""> + <highlighting> + <list name="import"> + <item>import</item> + <item>from</item> + <item>as</item> + </list> + <list name="defs"> + <item>class</item> + <item>def</item> + <item>del</item> + <item>global</item> + <item>lambda</item> + <item>nonlocal</item> + </list> + <list name="operators"> + <item>and</item> + <item>in</item> + <item>is</item> + <item>not</item> + <item>or</item> + </list> + <list name="flow"> + <item>assert</item> + <item>break</item> + <item>continue</item> + <item>elif</item> + <item>else</item> + <item>except</item> + <item>finally</item> + <item>for</item> + <item>if</item> + <item>pass</item> + <item>raise</item> + <item>return</item> + <item>try</item> + <item>while</item> + <item>with</item> + <item>yield</item> + <item>async</item> + <item>await</item> + </list> + <list name="builtinfuncs"> + <item>__import__</item> + <item>abs</item> + <item>all</item> + <item>any</item> + <item>apply</item> + <item>ascii</item> + <item>basestring</item> + <item>bin</item> + <item>bool</item> + <item>buffer</item> + <item>bytearray</item> + <item>bytes</item> + <item>callable</item> + <item>chr</item> + <item>classmethod</item> + <item>cmp</item> + <item>coerce</item> + <item>compile</item> + <item>complex</item> + <item>delattr</item> + <item>dict</item> + <item>dir</item> + <item>divmod</item> + <item>enumerate</item> + <item>eval</item> + <item>exec</item> + <item>execfile</item> + <item>file</item> + <item>filter</item> + <item>float</item> + <item>format</item> + <item>frozenset</item> + <item>getattr</item> + <item>globals</item> + <item>hasattr</item> + <item>hash</item> + <item>help</item> + <item>hex</item> + <item>id</item> + <item>input</item> + <item>int</item> + <item>intern</item> + <item>isinstance</item> + <item>issubclass</item> + <item>iter</item> + <item>len</item> + <item>list</item> + <item>locals</item> + <item>long</item> + <item>map</item> + <item>max</item> + <item>memoryview</item> + <item>min</item> + <item>next</item> + <item>object</item> + <item>oct</item> + <item>open</item> + <item>ord</item> + <item>pow</item> + <item>print</item> + <item>property</item> + <item>range</item> + <item>raw_input</item> + <item>reduce</item> + <item>reload</item> + <item>repr</item> + <item>reversed</item> + <item>round</item> + <item>set</item> + <item>setattr</item> + <item>slice</item> + <item>sorted</item> + <item>staticmethod</item> + <item>str</item> + <item>sum</item> + <item>super</item> + <item>tuple</item> + <item>type</item> + <item>unichr</item> + <item>unicode</item> + <item>vars</item> + <item>xrange</item> + <item>zip</item> + </list> + <list name="specialvars"> + <item>None</item> + <item>self</item> + <item>True</item> + <item>False</item> + <item>NotImplemented</item> + <item>Ellipsis</item> + <item>__debug__</item> + <item>__file__</item> + <item>__name__</item> + </list> + <list name="bindings"> + <item>SIGNAL</item> + <item>SLOT</item> + <item>connect</item> + </list> + <list name="overloaders"> + <item>__new__</item> + <item>__init__</item> + <item>__del__</item> + <item>__repr__</item> + <item>__str__</item> + <item>__lt__</item> + <item>__le__</item> + <item>__eq__</item> + <item>__ne__</item> + <item>__gt__</item> + <item>__ge__</item> + <item>__cmp__</item> + <item>__rcmp__</item> + <item>__hash__</item> + <item>__nonzero__</item> + <item>__unicode__</item> + <item>__getattr__</item> + <item>__setattr__</item> + <item>__delattr__</item> + <item>__getattribute__</item> + <item>__get__</item> + <item>__set__</item> + <item>__delete__</item> + <item>__call__</item> + <item>__len__</item> + <item>__getitem__</item> + <item>__setitem__</item> + <item>__delitem__</item> + <item>__iter__</item> + <item>__reversed__</item> + <item>__contains__</item> + <item>__getslice__</item> + <item>__setslice__</item> + <item>__delslice__</item> + <item>__add__</item> + <item>__sub__</item> + <item>__mul__</item> + <item>__floordiv__</item> + <item>__mod__</item> + <item>__divmod__</item> + <item>__pow__</item> + <item>__lshift__</item> + <item>__rshift__</item> + <item>__and__</item> + <item>__xor__</item> + <item>__or__</item> + <item>__div__</item> + <item>__truediv__</item> + <item>__radd__</item> + <item>__rsub__</item> + <item>__rmul__</item> + <item>__rdiv__</item> + <item>__rtruediv__</item> + <item>__rfloordiv__</item> + <item>__rmod__</item> + <item>__rdivmod__</item> + <item>__rpow__</item> + <item>__rlshift__</item> + <item>__rrshift__</item> + <item>__rand__</item> + <item>__rxor__</item> + <item>__ror__</item> + <item>__iadd__</item> + <item>__isub__</item> + <item>__imul__</item> + <item>__idiv__</item> + <item>__itruediv__</item> + <item>__ifloordiv__</item> + <item>__imod__</item> + <item>__ipow__</item> + <item>__ilshift__</item> + <item>__irshift__</item> + <item>__iand__</item> + <item>__ixor__</item> + <item>__ior__</item> + <item>__neg__</item> + <item>__pos__</item> + <item>__abs__</item> + <item>__invert__</item> + <item>__complex__</item> + <item>__int__</item> + <item>__long__</item> + <item>__float__</item> + <item>__oct__</item> + <item>__hex__</item> + <item>__index__</item> + <item>__coerce__</item> + <item>__enter__</item> + <item>__exit__</item> + <item>__bytes__</item> + <item>__format__</item> + <item>__next__</item> + <item>__dir__</item> + <item>__await__</item> + <item>__aiter__</item> + <item>__anext__</item> + <item>__aenter__</item> + <item>__aexit__</item> + </list> + <list name="exceptions"> + <!-- + Exceptions list resources used: + - http://docs.python.org/2.7/library/exceptions.html#exception-hierarchy + - http://docs.python.org/3.4/library/exceptions.html#exception-hierarchy + --> + <item>ArithmeticError</item> + <item>AssertionError</item> + <item>AttributeError</item> + <item>BaseException</item> + <item>BlockingIOError</item> + <item>BrokenPipeError</item> + <item>BufferError</item> + <item>BytesWarning</item> + <item>ChildProcessError</item> + <item>ConnectionAbortedError</item> + <item>ConnectionError</item> + <item>ConnectionRefusedError</item> + <item>ConnectionResetError</item> + <item>DeprecationWarning</item> + <item>EnvironmentError</item> + <item>EOFError</item> + <item>Exception</item> + <item>FileExistsError</item> + <item>FileNotFoundError</item> + <item>FloatingPointError</item> + <item>FutureWarning</item> + <item>GeneratorExit</item> + <item>ImportError</item> + <item>ImportWarning</item> + <item>IndentationError</item> + <item>IndexError</item> + <item>InterruptedError</item> + <item>IOError</item> + <item>IsADirectoryError</item> + <item>KeyboardInterrupt</item> + <item>KeyError</item> + <item>LookupError</item> + <item>MemoryError</item> + <item>NameError</item> + <item>NotADirectoryError</item> + <item>NotImplementedError</item> + <item>OSError</item> + <item>OverflowError</item> + <item>PendingDeprecationWarning</item> + <item>PermissionError</item> + <item>ProcessLookupError</item> + <item>ReferenceError</item> + <item>ResourceWarning</item> + <item>RuntimeError</item> + <item>RuntimeWarning</item> + <item>StandardError</item> + <item>StopIteration</item> + <item>SyntaxError</item> + <item>SyntaxWarning</item> + <item>SystemError</item> + <item>SystemExit</item> + <item>TabError</item> + <item>TimeoutError</item> + <item>TypeError</item> + <item>UnboundLocalError</item> + <item>UnicodeDecodeError</item> + <item>UnicodeEncodeError</item> + <item>UnicodeError</item> + <item>UnicodeTranslateError</item> + <item>UnicodeWarning</item> + <item>UserWarning</item> + <item>ValueError</item> + <item>Warning</item> + <item>WindowsError</item> + <item>ZeroDivisionError</item> + </list> + <contexts> + <context name="Normal" attribute="Normal Text" lineEndContext="#stay"> + <keyword attribute="Import" String="import" context="#stay"/> + <keyword attribute="Definition Keyword" String="defs" context="#stay"/> + <keyword attribute="Operator Keyword" String="operators" context="#stay"/> + <keyword attribute="Flow Control Keyword" String="flow" context="#stay"/> + <keyword attribute="Builtin Function" String="builtinfuncs" context="#stay"/> + <keyword attribute="Special Variable" String="specialvars" context="#stay"/> + <keyword attribute="Extensions" String="bindings" context="#stay"/> + <keyword attribute="Exceptions" String="exceptions" context="#stay"/> + <keyword attribute="Overloaders" String="overloaders" context="#stay"/> + <RegExpr attribute="Normal Text" String="[a-zA-Z_][a-zA-Z_0-9]{2,}" context="#stay"/> + + <RegExpr attribute="Complex" String=" ((([0-9]*\.[0-9]+|[0-9]+\.)|([0-9]+|([0-9]*\.[0-9]+|[0-9]+\.))[eE](\+|-)?[0-9]+)|[0-9]+)[jJ]" context="#stay"/> + <Float attribute="Float" context="#stay" /> + <HlCHex attribute="Hex" context="#stay"/> + <HlCOct attribute="Octal" context="#stay"/> + <Int attribute="Int" context="Int Suffixes"/> + + <RegExpr attribute="Int" String=" ([0-9]+_)+[0-9]+" context="#stay"/> + <RegExpr attribute="Float" String=" ([0-9]+_)+[0-9]+\.[0-9]+" context="#stay"/> + <RegExpr attribute="Hex" String=" [0-9]x([A-F0-9]+_)+[A-F0-9]+" context="#stay"/> + + <DetectChar attribute="Normal Text" char="{" context="Dictionary" beginRegion="Dictionary"/> + <DetectChar attribute="Normal Text" char="[" context="List" beginRegion="List"/> + <DetectChar attribute="Normal Text" char="(" context="Tuple" beginRegion="Tuple"/> + + <IncludeRules context="CommentVariants" /> + + <DetectChar attribute="Comment" char="#" context="Hash comment"/> + + <IncludeRules context="StringVariants" /> + + <RegExpr attribute="Decorator" String="@[_a-zA-Z][\._a-zA-Z0-9]*" firstNonSpace="true"/> + <AnyChar attribute="Operator" String="+*/%\|=;\!<>!^&~-@" context="#stay"/> + </context> + + <context name="Int Suffixes" attribute="Int" lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop"> + <StringDetect attribute="Int" context="#pop" String="L" insensitive="true"/> + </context> + + <context name="#CheckForString" attribute="Normal Text" lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop"> + <DetectSpaces/> + <LineContinue attribute="Normal Text" context="CheckForStringNext"/> + </context> + + <context name="CheckForStringNext" attribute="Normal Text" lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop"> + <DetectSpaces/> + <LineContinue attribute="Normal Text" context="CheckForStringNext"/> + <IncludeRules context="StringVariants"/> + </context> + + <context name="StringVariants" attribute="Normal Text" lineEndContext="#stay"> + <DetectSpaces/> + + <RegExpr attribute="String" String="u?'''" insensitive="true" context="Triple A-string" beginRegion="Triple A-region"/> + <RegExpr attribute="String" String="u?"""" insensitive="true" context="Triple Q-string" beginRegion="Triple Q-region"/> + <RegExpr attribute="String" String="u?'" insensitive="true" context="Single A-string"/> + <RegExpr attribute="String" String="u?"" insensitive="true" context="Single Q-string"/> + + <RegExpr attribute="Raw String" String="(u?r|ru)'''" insensitive="true" context="Raw Triple A-string" beginRegion="Triple A-region"/> + <RegExpr attribute="Raw String" String="(u?r|ru)"""" insensitive="true" context="Raw Triple Q-string" beginRegion="Triple Q-region"/> + <RegExpr attribute="Raw String" String="(u?r|ru)'" insensitive="true" context="Raw A-string"/> + <RegExpr attribute="Raw String" String="(u?r|ru)"" insensitive="true" context="Raw Q-string"/> + + <StringDetect attribute="F-String" String="f'''" insensitive="true" context="Triple A-F-String" beginRegion="Triple A-region"/> + <StringDetect attribute="F-String" String="f"""" insensitive="true" context="Triple Q-F-String" beginRegion="Triple Q-region"/> + <StringDetect attribute="F-String" String="f'" insensitive="true" context="Single A-F-String"/> + <StringDetect attribute="F-String" String="f"" insensitive="true" context="Single Q-F-String"/> + + <RegExpr attribute="Raw F-String" String="(fr|rf)'''" insensitive="true" context="Raw Triple A-F-String" beginRegion="Triple A-region"/> + <RegExpr attribute="Raw F-String" String="(fr|rf)"""" insensitive="true" context="Raw Triple Q-F-String" beginRegion="Triple Q-region"/> + <RegExpr attribute="Raw F-String" String="(fr|rf)'" insensitive="true" context="Raw A-F-String"/> + <RegExpr attribute="Raw F-String" String="(fr|rf)"" insensitive="true" context="Raw Q-F-String"/> + </context> + + <context name="CommentVariants" attribute="Normal Text" lineEndContext="#stay"> + <DetectSpaces/> + + <RegExpr attribute="Comment" String="u?'''" insensitive="true" firstNonSpace="true" context="Triple A-comment" beginRegion="Triple A-region"/> + <RegExpr attribute="Comment" String="u?"""" insensitive="true" firstNonSpace="true" context="Triple Q-comment" beginRegion="Triple Q-region"/> + <RegExpr attribute="Comment" String="u?'" insensitive="true" firstNonSpace="true" context="Single A-comment"/> + <RegExpr attribute="Comment" String="u?"" insensitive="true" firstNonSpace="true" context="Single Q-comment"/> + + <RegExpr attribute="Comment" String="(u?r|ru)'''" insensitive="true" firstNonSpace="true" context="Triple A-comment" beginRegion="Triple A-region"/> + <RegExpr attribute="Comment" String="(u?r|ru)"""" insensitive="true" firstNonSpace="true" context="Triple Q-comment" beginRegion="Triple Q-region"/> + <RegExpr attribute="Comment" String="(u?r|ru)'" insensitive="true" firstNonSpace="true" context="Single A-comment"/> + <RegExpr attribute="Comment" String="(u?r|ru)"" insensitive="true" firstNonSpace="true" context="Single Q-comment"/> + </context> + + <context name="Dictionary" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="true"> + <DetectSpaces/> + <DetectChar attribute="Normal Text" char="}" context="#pop" endRegion="Dictionary"/> + <IncludeRules context="StringVariants" /> + <IncludeRules context="Normal" /> + </context> + + <context name="List" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="true"> + <DetectSpaces/> + <DetectChar attribute="Normal Text" char="]" context="#pop" endRegion="List"/> + <IncludeRules context="StringVariants" /> + <IncludeRules context="Normal" /> + </context> + + <context name="Tuple" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="true"> + <DetectSpaces/> + <DetectChar attribute="Normal Text" char=")" context="#pop" endRegion="Tuple"/> + <IncludeRules context="StringVariants" /> + <IncludeRules context="Normal" /> + </context> + + <!-- Comments --> + + <context name="Hash comment" attribute="Comment" lineEndContext="#pop"> + <IncludeRules context="##Alerts" /> + <IncludeRules context="##Modelines" /> + </context> + + <context name="Triple A-comment" attribute="Comment" lineEndContext="#stay" noIndentationBasedFolding="true"> + <IncludeRules context="stringescape"/> + <StringDetect attribute="Comment" String="'''" context="#pop" endRegion="Triple A-region"/> + <IncludeRules context="##Alerts" /> + </context> + + <context name="Triple Q-comment" attribute="Comment" lineEndContext="#stay" noIndentationBasedFolding="true"> + <IncludeRules context="stringescape"/> + <StringDetect attribute="Comment" String=""""" context="#pop" endRegion="Triple Q-region"/> + <IncludeRules context="##Alerts" /> + </context> + + <context name="Single A-comment" attribute="Comment" lineEndContext="#stay"> + <IncludeRules context="stringescape"/> + <DetectChar attribute="Comment" char="'" context="#pop"/> + <IncludeRules context="##Alerts" /> + </context> + + <context name="Single Q-comment" attribute="Comment" lineEndContext="#stay"> + <IncludeRules context="stringescape"/> + <DetectChar attribute="Comment" char=""" context="#pop"/> + <IncludeRules context="##Alerts" /> + </context> + + <!-- Strings --> + + <!-- format characters --> + <context name="stringformat" attribute="String Substitution" lineEndContext="#stay"> + <!-- Python 2 style. Syntax: + 1. start character '%' + 2. [optional] Mapping key, e.g. '(foo)' + 3. [optional] Conversion flags, one of '#0- +' + 4. [optional] Minimum width, integer or '*' + 5. [optional] Precision, '.' followed by integer or '*' + 6. [optional] Length modifier, one of 'hlL' + 7. conversion type, one of 'crsdiouxXeEfFgG%' + [Special cases: %prog and %default - see http://docs.python.org/library/optparse.html] + --> + <RegExpr attribute="String Substitution" String="%((\([a-zA-Z0-9_]+\))?[#0\- +]?([1-9][0-9]*|\*)?(\.([1-9][0-9]*|\*))?[hlL]?[crsdiouxXeEfFgG%]|prog|default)" context="#stay"/> + <!-- http://docs.python.org/2/library/string.html#format-string-syntax: + replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}" + field_name ::= arg_name ("." attribute_name | "[" element_index "]")* + arg_name ::= [identifier | integer] + attribute_name ::= identifier + element_index ::= integer | index_string + index_string ::= <any source character except "]"> + + conversion ::= "r" | "s" + format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type] + fill ::= <any character> + align ::= "<" | ">" | "=" | "^" + sign ::= "+" | "-" | " " + width ::= integer + precision ::= integer + type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%" + --> + <RegExpr attribute="String Substitution" String="\{(([a-zA-Z0-9_]+|[0-9]+)(\.[a-zA-Z0-9_]+|\[[^ \]]+\])*)?(![rs])?(:([^}]?[<>=^])?[ +-]?#?0?[0-9]*(\.[0-9]+)?[bcdeEfFgGnosxX%]?)?\}" context="#stay"/> + <Detect2Chars attribute="String Substitution" char="{" char1="{" context="#stay" /> + <Detect2Chars attribute="String Substitution" char="}" char1="}" context="#stay" /> + </context> + + <!-- escape characters --> + <context name="stringescape" attribute="String Char" lineEndContext="#stay"> + <!-- As this highlighting style is for both, Python 2 and 3, + we do not know if a normal string is “unicode” or not. So we + --> + <RegExpr attribute="String Char" String="\\[\\'"abfnrtv]" context="#stay"/> + <RegExpr attribute="String Char" String="\\[0-7]{1,3}" context="#stay"/> + <RegExpr attribute="String Char" String="\\x[0-9A-Fa-f]{2}" context="#stay"/> + <RegExpr attribute="String Char" String="\\u[0-9A-Fa-f]{4}" context="#stay"/> + <RegExpr attribute="String Char" String="\\U[0-9A-Fa-f]{8}" context="#stay"/> + <RegExpr attribute="String Char" String="\\N\{[a-zA-Z0-9\- ]+\}" context="#stay"/> + </context> + + <!-- f-literals --> + <context name="stringinterpolation" attribute="F-String" lineEndContext="#stay"> + <Detect2Chars attribute="String Char" char="{" char1="{" context="#stay"/> + <DetectChar attribute="String Substitution" char="{" context="String Interpolation"/> + </context> + <context name="String Interpolation" attribute="String Substitution" lineEndContext="#stay"> + <DetectChar attribute="Error" char="\" context="#pop"/> + <RegExpr attribute="String Substitution" String="(![rs])?(:([^}]?[<>=^])?[ +-]?#?0?[0-9]*(\.[0-9]+)?[bcdeEfFgGnosxX%]?)?\}" context="#pop"/> + <IncludeRules context="Normal"/> <!-- TODO: create expression context instead --> + </context> + + + <!-- + It follows a Binary tree of string kinds (not even touching byte literals). + The levels are: + 1. triple- vs. single-quoted + 2. apostrophe vs. quotation mark + 3. static vs. interpolated (f-literal) + 4. escaped vs. raw + Adding byte literals wouldn’t make the current 2⁴ into 2⁵ contexts, as there are no byte f-literals + --> + + + <!-- Triple-quoted A-strings --> + <context name="Triple A-string" attribute="String" lineEndContext="#stay" noIndentationBasedFolding="true"> + <IncludeRules context="stringescape"/> + <IncludeRules context="stringformat"/> + <StringDetect attribute="String" String="'''" context="#pop#CheckForString" endRegion="Triple A-region"/> + </context> + + <context name="Raw Triple A-string" attribute="Raw String" lineEndContext="#stay" noIndentationBasedFolding="true"> + <HlCStringChar attribute="Raw String" context="#stay"/> + <IncludeRules context="stringformat"/> + <StringDetect attribute="Raw String" String="'''" context="#pop#CheckForString" endRegion="Triple A-region"/> + </context> + + <context name="Triple A-F-String" attribute="F-String" lineEndContext="#stay" noIndentationBasedFolding="true"> + <IncludeRules context="stringescape"/> + <IncludeRules context="stringinterpolation"/> + <StringDetect attribute="F-String" String="'''" context="#pop#CheckForString" endRegion="Triple A-region"/> + </context> + + <context name="Raw Triple A-F-String" attribute="Raw F-String" lineEndContext="#stay" noIndentationBasedFolding="true"> + <HlCStringChar attribute="Raw F-String" context="#stay"/> + <IncludeRules context="stringinterpolation"/> + <StringDetect attribute="Raw F-String" String="'''" context="#pop#CheckForString" endRegion="Triple A-region"/> + </context> + + <!-- Triple-quoted Q-strings --> + <context name="Triple Q-string" attribute="String" lineEndContext="#stay" noIndentationBasedFolding="true"> + <IncludeRules context="stringescape"/> + <IncludeRules context="stringformat"/> + <StringDetect attribute="String" String=""""" context="#pop#CheckForString" endRegion="Triple Q-region"/> + </context> + + <context name="Raw Triple Q-string" attribute="Raw String" lineEndContext="#stay" noIndentationBasedFolding="true"> + <HlCStringChar attribute="Raw String" context="#stay"/> + <IncludeRules context="stringformat"/> + <StringDetect attribute="Raw String" String=""""" context="#pop#CheckForString" endRegion="Triple Q-region"/> + </context> + + <context name="Triple Q-F-String" attribute="F-String" lineEndContext="#stay" noIndentationBasedFolding="true"> + <IncludeRules context="stringescape"/> + <IncludeRules context="stringinterpolation"/> + <StringDetect attribute="F-String" String=""""" context="#pop#CheckForString" endRegion="Triple Q-region"/> + </context> + + <context name="Raw Triple Q-F-String" attribute="Raw F-String" lineEndContext="#stay" noIndentationBasedFolding="true"> + <HlCStringChar attribute="Raw F-String" context="#stay"/> + <IncludeRules context="stringinterpolation"/> + <StringDetect attribute="Raw F-String" String=""""" context="#pop#CheckForString" endRegion="Triple Q-region"/> + </context> + + + <!-- Single-quoted A-strings --> + <context name="Single A-string" attribute="String" lineEndContext="#stay"> + <IncludeRules context="stringescape"/> + <IncludeRules context="stringformat"/> + <DetectChar attribute="String" char="'" context="#pop#CheckForString"/> + </context> + + <context name="Raw A-string" attribute="Raw String" lineEndContext="#stay"> + <HlCStringChar attribute="Raw String" context="#stay"/> + <IncludeRules context="stringformat"/> + <DetectChar attribute="Raw String" char="'" context="#pop#CheckForString"/> + </context> + + <context name="Single A-F-String" attribute="F-String" lineEndContext="#stay"> + <IncludeRules context="stringescape"/> + <IncludeRules context="stringinterpolation"/> + <DetectChar attribute="F-String" char="'" context="#pop#CheckForString"/> + </context> + + <context name="Raw A-F-String" attribute="Raw F-String" lineEndContext="#stay"> + <HlCStringChar attribute="Raw F-String" context="#stay"/> + <IncludeRules context="stringinterpolation"/> + <DetectChar attribute="Raw F-String" char="'" context="#pop#CheckForString"/> + </context> + + <!-- Single-quoted Q-strings --> + <context name="Single Q-string" attribute="String" lineEndContext="#stay"> + <IncludeRules context="stringescape"/> + <IncludeRules context="stringformat"/> + <DetectChar attribute="String" char=""" context="#pop#CheckForString"/> + </context> + + <context name="Raw Q-string" attribute="Raw String" lineEndContext="#stay"> + <HlCStringChar attribute="Raw String" context="#stay"/> + <IncludeRules context="stringformat"/> + <DetectChar attribute="Raw String" char=""" context="#pop#CheckForString"/> + </context> + + <context name="Single Q-F-String" attribute="F-String" lineEndContext="#stay"> + <IncludeRules context="stringescape"/> + <IncludeRules context="stringinterpolation"/> + <DetectChar attribute="F-String" char=""" context="#pop#CheckForString"/> + </context> + + <context name="Raw Q-F-String" attribute="Raw F-String" lineEndContext="#stay"> + <HlCStringChar attribute="Raw F-String" context="#stay"/> + <IncludeRules context="stringinterpolation"/> + <DetectChar attribute="Raw F-String" char=""" context="#pop#CheckForString"/> + </context> + </contexts> + + <itemDatas> + <itemData name="Normal Text" defStyleNum="dsNormal" spellChecking="false"/> + <itemData name="Definition Keyword" defStyleNum="dsKeyword" spellChecking="false"/> + <itemData name="Operator" defStyleNum="dsOperator" spellChecking="false"/> + <itemData name="Operator Keyword" defStyleNum="dsKeyword" spellChecking="false"/> + <itemData name="Flow Control Keyword" defStyleNum="dsControlFlow" spellChecking="false"/> + <itemData name="Builtin Function" defStyleNum="dsBuiltIn" spellChecking="false"/> + <itemData name="Special Variable" defStyleNum="dsVariable" spellChecking="false"/> + <itemData name="Extensions" defStyleNum="dsExtension" spellChecking="false"/> + <itemData name="Exceptions" defStyleNum="dsPreprocessor" spellChecking="false"/> + <itemData name="Overloaders" defStyleNum="dsFunction" spellChecking="false"/> + <itemData name="Import" defStyleNum="dsImport" spellChecking="false"/> + <itemData name="Float" defStyleNum="dsFloat" spellChecking="false"/> + <itemData name="Int" defStyleNum="dsDecVal" spellChecking="false"/> + <itemData name="Hex" defStyleNum="dsBaseN" spellChecking="false"/> + <itemData name="Octal" defStyleNum="dsBaseN" spellChecking="false"/> + <itemData name="Complex" defStyleNum="dsOthers" spellChecking="false"/> + <itemData name="Comment" defStyleNum="dsComment"/> + <itemData name="String" defStyleNum="dsString"/> + <itemData name="Raw String" defStyleNum="dsVerbatimString"/> + <itemData name="F-String" defStyleNum="dsSpecialString"/> + <itemData name="Raw F-String" defStyleNum="dsVerbatimString"/> + <itemData name="String Char" defStyleNum="dsChar" spellChecking="false"/> + <itemData name="String Substitution" defStyleNum="dsSpecialChar" spellChecking="false"/> + <itemData name="Decorator" defStyleNum="dsAttribute" spellChecking="false"/> + <itemData name="Error" defStyleNum="dsError"/> + </itemDatas> + </highlighting> + <general> + <folding indentationsensitive="1" /> + <emptyLines> + <emptyLine regexpr="(?:\s+|\s*#.*)"/> + </emptyLines> + <comments> + <comment name="singleLine" start="#" position="afterwhitespace"/> + </comments> + <keywords casesensitive="1" additionalDeliminator="#'"/> + </general> +</language> + +<!-- kate: space-indent off; indent-width 4; --> diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/qdocconf.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/qdocconf.xml new file mode 100644 index 0000000000..0efd6edc3f --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/qdocconf.xml @@ -0,0 +1,136 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE language SYSTEM "language.dtd"> +<language name="QDoc Configuration" + version="1" + kateversion="5.0" + section="Configuration" + extensions="*.qdocconf" + author="Volker Krause (vkrause@kde.org)" + license="MIT"> + <highlighting> + <list name="key-names"> + <item>alias</item> + <item>buildversion</item> + <item>Cpp</item> + <item>customFilters</item> + <item>defines</item> + <item>depends</item> + <item>description</item> + <item>dita</item> + <item>edition</item> + <item>endheader</item> + <item>exampledirs</item> + <item>examples</item> + <item>excludedirs</item> + <item>excludefiles</item> + <item>falsehoods</item> + <item>file</item> + <item>filterAttributes</item> + <item>headerdirs</item> + <item>headers</item> + <item>HTML</item> + <item>imagedirs</item> + <item>images</item> + <item>indexes</item> + <item>indexRoot</item> + <item>indexTitle</item> + <item>language</item> + <item>macro</item> + <item>manifestmeta</item> + <item>name</item> + <item>namespace</item> + <item>navigation</item> + <item>outputdir</item> + <item>outputformats</item> + <item>outputprefixes</item> + <item>outputsuffixes</item> + <item>project</item> + <item>projects</item> + <item>qhp</item> + <item>selectors</item> + <item>sortPages</item> + <item>sourcedirs</item> + <item>sources</item> + <item>sources.fileextensions</item> + <item>spurious</item> + <item>subprojects</item> + <item>tabsize</item> + <item>tagfile</item> + <item>title</item> + <item>type</item> + <item>url</item> + <item>version</item> + <item>versionsym</item> + <item>virtualFolder</item> + </list> + <list name="function-names"> + <item>include</item> + </list> + <list name="selector-names"> + <item>namespace</item> + <item>class</item> + <item>qmltype</item> + <item>qmlclass</item> + <item>module</item> + <item>qmlmodule</item> + <item>doc</item> + <item>fake</item> + <item>group</item> + <item>example</item> + <item>headerfile</item> + <item>page</item> + <item>manual</item> + </list> + + <contexts> + <context name="key-context" attribute="Normal Text" lineEndContext="#stay"> + <DetectChar char="#" context="comment-context" column="0"/> + <keyword attribute="Keyword" String="key-names"/> + <keyword attribute="Function" String="function-names"/> + <DetectChar char="=" context="value-context"/> + <DetectChar char="(" context="argument-context"/> + </context> + + <context name="value-context" attribute="Normal Text" lineEndContext="#pop" lineEmptyContext="#pop"> + <DetectChar attribute="String" context="string-context" char="""/> + <keyword attribute="Selector" String="selector-names"/> + <RegExpr attribute="Variable" String="\$\w+"/> + <LineContinue char="\" context="#stay"/> + </context> + + <context name="argument-context" attribute="Normal Text" lineEndContext="#stay"> + <DetectChar attribute="String" context="string-context" char="""/> + <RegExpr attribute="Variable" String="\$\w+"/> + <DetectChar char=")" context="#pop"/> + <LineContinue char="\" context="#stay"/> + </context> + + <context name="string-context" attribute="String" lineEndContext="#stay"> + <HlCStringChar attribute="Special Character"/> + <RegExpr attribute="Variable" String="\$\w+"/> + <DetectChar attribute="String" context="#pop" char="""/> + </context> + + <context name="comment-context" attribute="Comment" lineEndContext="#pop"> + <IncludeRules context="##Alerts"/> + </context> + </contexts> + + <itemDatas> + <itemData name="Normal Text" defStyleNum="dsNormal" spellChecking="false"/> + <itemData name="Keyword" defStyleNum="dsBuiltIn" spellChecking="false"/> + <itemData name="String" defStyleNum="dsString" spellChecking="false"/> + <itemData name="Special Character" defStyleNum="dsSpecialChar" spellChecking="false"/> + <itemData name="Variable" defStyleNum="dsVariable" spellChecking="false"/> + <itemData name="Comment" defStyleNum="dsComment"/> + <itemData name="Function" defStyleNum="dsFunction" spellChecking="false"/> + <itemData name="Selector" defStyleNum="dsExtension" spellChecking="false"/> + </itemDatas> + </highlighting> + <general> + <comments> + <comment name="singleLine" start="#"/> + </comments> + <keywords casesensitive="1" weakDeliminator="-/"/> + </general> +</language> diff --git a/src/share/3rdparty/generic-highlighter/ruby.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/ruby.xml index 754dfdc5fe..754dfdc5fe 100644 --- a/src/share/3rdparty/generic-highlighter/ruby.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/ruby.xml diff --git a/src/share/3rdparty/generic-highlighter/valgrind-suppression.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/valgrind-suppression.xml index 7fe3dd474e..7fe3dd474e 100644 --- a/src/share/3rdparty/generic-highlighter/valgrind-suppression.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/valgrind-suppression.xml diff --git a/src/share/3rdparty/generic-highlighter/xml.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/xml.xml index ad34a450b6..ad34a450b6 100644 --- a/src/share/3rdparty/generic-highlighter/xml.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/xml.xml diff --git a/src/share/3rdparty/generic-highlighter/yacc.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/yacc.xml index 6936c7a2de..6936c7a2de 100644 --- a/src/share/3rdparty/generic-highlighter/yacc.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/yacc.xml diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/breeze-dark.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/breeze-dark.theme new file mode 100644 index 0000000000..8147948eeb --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/themes/breeze-dark.theme @@ -0,0 +1,174 @@ +{ + "metadata" : { + "revision" : 2, + "name" : "Breeze Dark" + }, + "text-styles": { + "Normal" : { + "text-color" : "#cfcfc2", + "selected-text-color" : "#cfcfc2", + "bold" : false, + "italic" : false, + "underline" : false, + "strike-through" : false + }, + "Keyword" : { + "text-color" : "#cfcfc2", + "selected-text-color" : "#cfcfc2", + "bold" : true + }, + "Function" : { + "text-color" : "#8e44ad", + "selected-text-color" : "#af81ff" + }, + "Variable" : { + "text-color" : "#27aeae", + "selected-text-color" : "#27aeae" + }, + "ControlFlow" : { + "text-color" : "#fdbc4b", + "selected-text-color" : "#fdbc4b", + "bold" : true + }, + "Operator" : { + "text-color" : "#cfcfc2", + "selected-text-color" : "#cfcfc2" + }, + "BuiltIn" : { + "text-color" : "#7f8c8d", + "selected-text-color" : "#bdc3c7" + }, + "Extension" : { + "text-color" : "#0099ff", + "selected-text-color" : "#bdc3c7", + "bold" : true + }, + "Preprocessor" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + }, + "Attribute" : { + "text-color" : "#2980b9", + "selected-text-color" : "#fdbc4b" + }, + "Char" : { + "text-color" : "#3daee9", + "selected-text-color" : "#3daee9" + }, + "SpecialChar" : { + "text-color" : "#3daee9", + "selected-text-color" : "#3daee9" + }, + "String" : { + "text-color" : "#f44f4f", + "selected-text-color" : "#f44f4f" + }, + "VerbatimString" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "SpecialString" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "Import" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + }, + "DataType" : { + "text-color" : "#2980b9", + "selected-text-color" : "#fdbc4b" + }, + "DecVal" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "BaseN" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "Float" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "Constant" : { + "text-color" : "#27aeae", + "selected-text-color" : "#27aeae", + "bold" : true + }, + "Comment" : { + "text-color" : "#7a7c7d", + "selected-text-color" : "#808080" + }, + "Documentation" : { + "text-color" : "#a43340", + "selected-text-color" : "#da4453" + }, + "Annotation" : { + "text-color" : "#3f8058", + "selected-text-color" : "#54aa75" + }, + "CommentVar" : { + "text-color" : "#7f8c8d", + "selected-text-color" : "#94a3a4" + }, + "RegionMarker" : { + "text-color" : "#2980b9", + "selected-text-color" : "#3daee9", + "background-color" : "#153042" + }, + "Information" : { + "text-color" : "#c45b00", + "selected-text-color" : "#e46700" + }, + "Warning" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "Alert" : { + "text-color" : "#95da4c", + "selected-text-color" : "#95da4c", + "background-color" : "#4d1f24", + "bold" : true + }, + "Error" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453", + "underline" : true + }, + "Others" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + } + }, + "editor-colors": { + "background-color" : "#232629", + "code-folding" : "#224e65", + "bracket-matching" : "#8e44ad", + "current-line" : "#2A2E32", + "icon-border" : "#31363b", + "indentation-line" : "#3a3f44", + "line-numbers" : "#7a7c7d", + "current-line-number" : "#a5a6a8", + "mark-bookmark" : "#0404bf", + "mark-breakpoint-active" : "#8b0607", + "mark-breakpoint-reached" : "#6d6e07", + "mark-breakpoint-disabled" : "#820683", + "mark-execution" : "#4d4e50", + "mark-warning" : "#f67400", + "mark-error" : "#da4453", + "modified-lines" : "#c04900", + "replace-highlight" : "#808021", + "saved-lines" : "#1c8042", + "search-highlight" : "#218058", + "selection" : "#2d5c76", + "separator" : "#7a7c7d", + "spell-checking" : "#c0392b", + "tab-marker" : "#4d4d4d", + "template-background" : "#31363b", + "template-placeholder" : "#123723", + "template-focused-placeholder" : "#123723", + "template-read-only-placeholder" : "#4d1f24", + "word-wrap-marker" : "#3a3f44" + } +} diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/default.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/default.theme new file mode 100644 index 0000000000..e9c5c838d3 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/themes/default.theme @@ -0,0 +1,174 @@ +{ + "metadata" : { + "revision" : 3, + "name" : "Default" + }, + "text-styles": { + "Normal" : { + "text-color" : "#1f1c1b", + "selected-text-color" : "#ffffff", + "bold" : false, + "italic" : false, + "underline" : false, + "strike-through" : false + }, + "Keyword" : { + "text-color" : "#1f1c1b", + "selected-text-color" : "#ffffff", + "bold" : true + }, + "Function" : { + "text-color" : "#644a9b", + "selected-text-color" : "#452886" + }, + "Variable" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e" + }, + "ControlFlow" : { + "text-color" : "#1f1c1b", + "selected-text-color" : "#ffffff", + "bold" : true + }, + "Operator" : { + "text-color" : "#1f1c1b", + "selected-text-color" : "#ffffff" + }, + "BuiltIn" : { + "text-color" : "#644a9b", + "selected-text-color" : "#452886", + "bold" : true + }, + "Extension" : { + "text-color" : "#0095ff", + "selected-text-color" : "#ffffff", + "bold" : true + }, + "Preprocessor" : { + "text-color" : "#006e28", + "selected-text-color" : "#006e28" + }, + "Attribute" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e" + }, + "Char" : { + "text-color" : "#924c9d", + "selected-text-color" : "#6c2477" + }, + "SpecialChar" : { + "text-color" : "#3daee9", + "selected-text-color" : "#fcfcfc" + }, + "String" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e" + }, + "VerbatimString" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e" + }, + "SpecialString" : { + "text-color" : "#ff5500", + "selected-text-color" : "#ff5500" + }, + "Import" : { + "text-color" : "#ff5500", + "selected-text-color" : "#ff5500" + }, + "DataType" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e" + }, + "DecVal" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "BaseN" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "Float" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "Constant" : { + "text-color" : "#aa5500", + "selected-text-color" : "#5e2f00" + }, + "Comment" : { + "text-color" : "#898887", + "selected-text-color" : "#5e5d5d" + }, + "Documentation" : { + "text-color" : "#607880", + "selected-text-color" : "#46585e" + }, + "Annotation" : { + "text-color" : "#ca60ca", + "selected-text-color" : "#a44ea4" + }, + "CommentVar" : { + "text-color" : "#0095ff", + "selected-text-color" : "#ffffff" + }, + "RegionMarker" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e", + "background-color" : "#e0e9f8" + }, + "Information" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "Warning" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e" + }, + "Alert" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e", + "background-color" : "#f7e6e6", + "bold" : true + }, + "Error" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e", + "underline" : true + }, + "Others" : { + "text-color" : "#006e28", + "selected-text-color" : "#006e28" + } + }, + "editor-colors": { + "background-color" : "#ffffff", + "code-folding" : "#94caef", + "bracket-matching" : "#ffff00", + "current-line" : "#f8f7f6", + "icon-border" : "#f0f0f0", + "indentation-line" : "#d2d2d2", + "line-numbers" : "#a0a0a0", + "current-line-number" : "#1e1e1e", + "mark-bookmark" : "#0000ff", + "mark-breakpoint-active" : "#ff0000", + "mark-breakpoint-reached" : "#ffff00", + "mark-breakpoint-disabled" : "#ff00ff", + "mark-execution" : "#a0a0a4", + "mark-warning" : "#00ff00", + "mark-error" : "#ff0000", + "modified-lines" : "#fdbc4b", + "replace-highlight" : "#00ff00", + "saved-lines" : "#2ecc71", + "search-highlight" : "#ffff00", + "selection" : "#94caef", + "separator" : "#898887", + "spell-checking" : "#bf0303", + "tab-marker" : "#d2d2d2", + "template-background" : "#d6d2d0", + "template-placeholder" : "#baf8ce", + "template-focused-placeholder" : "#76da98", + "template-read-only-placeholder" : "#f6e6e6", + "word-wrap-marker" : "#ededed" + } +} diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/printing.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/printing.theme new file mode 100644 index 0000000000..a6048ed01a --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/themes/printing.theme @@ -0,0 +1,173 @@ +{ + "metadata" : { + "revision" : 3, + "name" : "Printing" + }, + "text-styles": { + "Normal" : { + "text-color" : "#000000", + "selected-text-color" : "#ffffff", + "bold" : false, + "italic" : false, + "underline" : false, + "strike-through" : false + }, + "Keyword" : { + "text-color" : "#000000", + "selected-text-color" : "#ffffff", + "bold" : true + }, + "Function" : { + "text-color" : "#644a9b", + "selected-text-color" : "#452886" + }, + "Variable" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e" + }, + "ControlFlow" : { + "text-color" : "#000000", + "selected-text-color" : "#ffffff", + "bold" : true + }, + "Operator" : { + "text-color" : "#000000", + "selected-text-color" : "#ffffff" + }, + "BuiltIn" : { + "text-color" : "#644a9b", + "selected-text-color" : "#452886" + }, + "Extension" : { + "text-color" : "#0095ff", + "selected-text-color" : "#ffffff", + "bold" : true + }, + "Preprocessor" : { + "text-color" : "#006e28", + "selected-text-color" : "#006e28" + }, + "Attribute" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e" + }, + "Char" : { + "text-color" : "#924c9d", + "selected-text-color" : "#6c2477" + }, + "SpecialChar" : { + "text-color" : "#ff5500", + "selected-text-color" : "#ff5500" + }, + "String" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e" + }, + "VerbatimString" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e" + }, + "SpecialString" : { + "text-color" : "#ff5500", + "selected-text-color" : "#ff5500" + }, + "Import" : { + "text-color" : "#644a9b", + "selected-text-color" : "#452886" + }, + "DataType" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e" + }, + "DecVal" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "BaseN" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "Float" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "Constant" : { + "text-color" : "#aa5500", + "selected-text-color" : "#5e2f00" + }, + "Comment" : { + "text-color" : "#898887", + "selected-text-color" : "#5e5d5d" + }, + "Documentation" : { + "text-color" : "#607880", + "selected-text-color" : "#46585e" + }, + "Annotation" : { + "text-color" : "#ca60ca", + "selected-text-color" : "#a44ea4" + }, + "CommentVar" : { + "text-color" : "#0095ff", + "selected-text-color" : "#ffffff" + }, + "RegionMarker" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e", + "background-color" : "#e0e9f8" + }, + "Information" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "Warning" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e" + }, + "Alert" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e", + "background-color" : "#f7e6e6", + "bold" : true + }, + "Error" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e", + "underline" : true + }, + "Others" : { + "text-color" : "#006e28", + "selected-text-color" : "#006e28" + } + }, + "editor-colors": { + "background-color" : "#ffffff", + "code-folding" : "#94caef", + "bracket-matching" : "#edf9ff", + "current-line" : "#f8f7f6", + "icon-border" : "#d6d2d0", + "indentation-line" : "#d2d2d2", + "line-numbers" : "#221f1e", + "current-line-number" : "#221f1e", + "mark-bookmark" : "#0000ff", + "mark-breakpoint-active" : "#ff0000", + "mark-breakpoint-reached" : "#ffff00", + "mark-breakpoint-disabled" : "#ff00ff", + "mark-execution" : "#a0a0a4", + "mark-warning" : "#00ff00", + "mark-error" : "#ff0000", + "modified-lines" : "#f6e6e6", + "replace-highlight" : "#00ff00", + "saved-lines" : "#baf8ce", + "search-highlight" : "#ffff00", + "selection" : "#94caef", + "separator" : "#898887", + "spell-checking" : "#bf0303", + "tab-marker" : "#d2d2d2", + "template-background" : "#d6d2d0", + "template-placeholder" : "#baf8ce", + "template-focused-placeholder" : "#76da98", + "template-read-only-placeholder" : "#f6e6e6", + "word-wrap-marker" : "#ededed" + } +} diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/solarized-dark.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/solarized-dark.theme new file mode 100644 index 0000000000..42a6eacbe8 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/themes/solarized-dark.theme @@ -0,0 +1,175 @@ +{ + "metadata" : { + "revision" : 1, + "name" : "Solarized Dark" + }, + "text-styles": { + "Normal" : { + "text-color" : "#839496", + "selected-text-color" : "#586e75", + "bold" : false, + "italic" : false, + "underline" : false, + "strike-through" : false + }, + "Keyword" : { + "text-color" : "#859900", + "selected-text-color" : "#859900", + "bold" : true + }, + "Function" : { + "text-color" : "#268bd2", + "selected-text-color" : "#268bd2" + }, + "Variable" : { + "text-color" : "#268bd2", + "selected-text-color" : "#268bd2" + }, + "ControlFlow" : { + "text-color" : "#859900", + "selected-text-color" : "#859900", + "bold" : true + }, + "Operator" : { + "text-color" : "#859900", + "selected-text-color" : "#859900" + }, + "BuiltIn" : { + "text-color" : "#cb4b16", + "selected-text-color" : "#cb4b16" + }, + "Extension" : { + "text-color" : "#268bd2", + "selected-text-color" : "#268bd2", + "bold" : true + }, + "Preprocessor" : { + "text-color" : "#cb4b16", + "selected-text-color" : "#cb4b16" + }, + "Attribute" : { + "text-color" : "#268bd2", + "selected-text-color" : "#268bd2" + }, + "Char" : { + "text-color" : "#2aa198", + "selected-text-color" : "#2aa198" + }, + "SpecialChar" : { + "text-color" : "#dc322f", + "selected-text-color" : "#dc322f" + }, + "String" : { + "text-color" : "#2aa198", + "selected-text-color" : "#2aa198" + }, + "VerbatimString" : { + "text-color" : "#2aa198", + "selected-text-color" : "#2aa198" + }, + "SpecialString" : { + "text-color" : "#dc322f", + "selected-text-color" : "#dc322f" + }, + "Import" : { + "text-color" : "#2aa198", + "selected-text-color" : "#2aa198" + }, + "DataType" : { + "text-color" : "#b58900", + "selected-text-color" : "#b58900", + "bold" : true + }, + "DecVal" : { + "text-color" : "#2aa198", + "selected-text-color" : "#2aa198" + }, + "BaseN" : { + "text-color" : "#2aa198", + "selected-text-color" : "#2aa198" + }, + "Float" : { + "text-color" : "#2aa198", + "selected-text-color" : "#2aa198" + }, + "Constant" : { + "text-color" : "#2aa198", + "selected-text-color" : "#2aa198", + "bold" : true + }, + "Comment" : { + "text-color" : "#586e75", + "selected-text-color" : "#93a1a1", + "italic" : true + }, + "Documentation" : { + "text-color" : "#dc322f", + "selected-text-color" : "#dc322f" + }, + "Annotation" : { + "text-color" : "#268bd2", + "selected-text-color" : "#268bd2" + }, + "CommentVar" : { + "text-color" : "#2aa198", + "selected-text-color" : "#2aa198" + }, + "RegionMarker" : { + "text-color" : "#268bd2", + "selected-text-color" : "#268bd2", + "background-color" : "#073642" + }, + "Information" : { + "text-color" : "#b58900", + "selected-text-color" : "#b58900" + }, + "Warning" : { + "text-color" : "#cb4b16", + "selected-text-color" : "#cb4b16" + }, + "Alert" : { + "text-color" : "#d33682", + "selected-text-color" : "#d33682", + "bold" : true + }, + "Error" : { + "text-color" : "#dc322f", + "selected-text-color" : "#dc322f", + "underline" : true + }, + "Others" : { + "text-color" : "#859900", + "selected-text-color" : "#859900" + } + }, + "editor-colors": { + "background-color" : "#002b36", + "code-folding" : "#6c71c4", + "bracket-matching" : "#073642", + "current-line" : "#073642", + "icon-border" : "#073642", + "indentation-line" : "#073642", + "line-numbers" : "#586e75", + "current-line-number" : "#586e75", + "mark-bookmark" : "#268bd2", + "mark-breakpoint-active" : "#dc322f", + "mark-breakpoint-reached" : "#b58900", + "mark-breakpoint-disabled" : "#d33682", + "mark-execution" : "#586e75", + "mark-warning" : "#cb4b16", + "mark-error" : "#dc322f", + "modified-lines" : "#cb4b16", + "replace-highlight" : "#859900", + "saved-lines" : "#2aa198", + "search-highlight" : "#b58900", + "selection" : "#eee8d5", + "separator" : "#586e75", + "spell-checking" : "#dc322f", + "tab-marker" : "#586e75", + "template-background" : "#073642", + "template-placeholder" : "#073642", + "template-focused-placeholder" : "#073642", + "template-read-only-placeholder" : "#073642", + "word-wrap-marker" : "#586e75" + } +} diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/solarized-light.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/solarized-light.theme new file mode 100644 index 0000000000..473f98add3 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/themes/solarized-light.theme @@ -0,0 +1,175 @@ +{ + "metadata" : { + "revision" : 1, + "name" : "Solarized Light" + }, + "text-styles": { + "Normal" : { + "text-color" : "#657b83", + "selected-text-color" : "#839496", + "bold" : false, + "italic" : false, + "underline" : false, + "strike-through" : false + }, + "Keyword" : { + "text-color" : "#859900", + "selected-text-color" : "#859900", + "bold" : true + }, + "Function" : { + "text-color" : "#268bd2", + "selected-text-color" : "#268bd2" + }, + "Variable" : { + "text-color" : "#268bd2", + "selected-text-color" : "#268bd2" + }, + "ControlFlow" : { + "text-color" : "#859900", + "selected-text-color" : "#859900", + "bold" : true + }, + "Operator" : { + "text-color" : "#859900", + "selected-text-color" : "#859900" + }, + "BuiltIn" : { + "text-color" : "#cb4b16", + "selected-text-color" : "#cb4b16" + }, + "Extension" : { + "text-color" : "#268bd2", + "selected-text-color" : "#268bd2", + "bold" : true + }, + "Preprocessor" : { + "text-color" : "#cb4b16", + "selected-text-color" : "#cb4b16" + }, + "Attribute" : { + "text-color" : "#268bd2", + "selected-text-color" : "#268bd2" + }, + "Char" : { + "text-color" : "#2aa198", + "selected-text-color" : "#2aa198" + }, + "SpecialChar" : { + "text-color" : "#dc322f", + "selected-text-color" : "#dc322f" + }, + "String" : { + "text-color" : "#2aa198", + "selected-text-color" : "#2aa198" + }, + "VerbatimString" : { + "text-color" : "#2aa198", + "selected-text-color" : "#2aa198" + }, + "SpecialString" : { + "text-color" : "#dc322f", + "selected-text-color" : "#dc322f" + }, + "Import" : { + "text-color" : "#2aa198", + "selected-text-color" : "#2aa198" + }, + "DataType" : { + "text-color" : "#b58900", + "selected-text-color" : "#b58900", + "bold" : true + }, + "DecVal" : { + "text-color" : "#2aa198", + "selected-text-color" : "#2aa198" + }, + "BaseN" : { + "text-color" : "#2aa198", + "selected-text-color" : "#2aa198" + }, + "Float" : { + "text-color" : "#2aa198", + "selected-text-color" : "#2aa198" + }, + "Constant" : { + "text-color" : "#2aa198", + "selected-text-color" : "#2aa198", + "bold" : true + }, + "Comment" : { + "text-color" : "#93a1a1", + "selected-text-color" : "#586e75", + "italic" : true + }, + "Documentation" : { + "text-color" : "#dc322f", + "selected-text-color" : "#dc322f" + }, + "Annotation" : { + "text-color" : "#268bd2", + "selected-text-color" : "#268bd2" + }, + "CommentVar" : { + "text-color" : "#2aa198", + "selected-text-color" : "#2aa198" + }, + "RegionMarker" : { + "text-color" : "#268bd2", + "selected-text-color" : "#268bd2", + "background-color" : "#eee8d5" + }, + "Information" : { + "text-color" : "#b58900", + "selected-text-color" : "#b58900" + }, + "Warning" : { + "text-color" : "#cb4b16", + "selected-text-color" : "#cb4b16" + }, + "Alert" : { + "text-color" : "#d33682", + "selected-text-color" : "#d33682", + "bold" : true + }, + "Error" : { + "text-color" : "#dc322f", + "selected-text-color" : "#dc322f", + "underline" : true + }, + "Others" : { + "text-color" : "#859900", + "selected-text-color" : "#859900" + } + }, + "editor-colors": { + "background-color" : "#fdf6e3", + "code-folding" : "#6c71c4", + "bracket-matching" : "#eee8d5", + "current-line" : "#eee8d5", + "icon-border" : "#eee8d5", + "indentation-line" : "#eee8d5", + "line-numbers" : "#93a1a1", + "current-line-number" : "#93a1a1", + "mark-bookmark" : "#268bd2", + "mark-breakpoint-active" : "#dc322f", + "mark-breakpoint-reached" : "#b58900", + "mark-breakpoint-disabled" : "#d33682", + "mark-execution" : "#93a1a1", + "mark-warning" : "#cb4b16", + "mark-error" : "#dc322f", + "modified-lines" : "#cb4b16", + "replace-highlight" : "#859900", + "saved-lines" : "#2aa198", + "search-highlight" : "#b58900", + "selection" : "#073642", + "separator" : "#93a1a1", + "spell-checking" : "#dc322f", + "tab-marker" : "#93a1a1", + "template-background" : "#eee8d5", + "template-placeholder" : "#eee8d5", + "template-focused-placeholder" : "#eee8d5", + "template-read-only-placeholder" : "#eee8d5", + "word-wrap-marker" : "#93a1a1" + } +} diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/theme-data.qrc b/src/libs/3rdparty/syntax-highlighting/data/themes/theme-data.qrc new file mode 100644 index 0000000000..46af4213b5 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/data/themes/theme-data.qrc @@ -0,0 +1,10 @@ +<!DOCTYPE RCC> +<RCC version="1.0"> + <qresource prefix="/org.kde.syntax-highlighting/themes"> + <file alias="default.theme">default.theme</file> + <file alias="breeze-dark.theme">breeze-dark.theme</file> + <file alias="printing.theme">printing.theme</file> + <file alias="solarized-dark.theme">solarized-dark.theme</file> + <file alias="solarized-light.theme">solarized-light.theme</file> + </qresource> +</RCC> diff --git a/src/libs/3rdparty/syntax-highlighting/examples/CMakeLists.txt b/src/libs/3rdparty/syntax-highlighting/examples/CMakeLists.txt new file mode 100644 index 0000000000..652b72cb0a --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/examples/CMakeLists.txt @@ -0,0 +1,4 @@ +if(Qt5Widgets_FOUND) + add_executable(codeeditor codeeditor.cpp main.cpp) + target_link_libraries(codeeditor Qt5::Widgets KF5SyntaxHighlighting) +endif() diff --git a/src/libs/3rdparty/syntax-highlighting/examples/codeeditor.cpp b/src/libs/3rdparty/syntax-highlighting/examples/codeeditor.cpp new file mode 100644 index 0000000000..88f315462d --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/examples/codeeditor.cpp @@ -0,0 +1,358 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "codeeditor.h" + +#include <definition.h> +#include <foldingregion.h> +#include <syntaxhighlighter.h> +#include <theme.h> + +#include <QApplication> +#include <QDebug> +#include <QFile> +#include <QFileDialog> +#include <QFontDatabase> +#include <QMenu> +#include <QPainter> +#include <QPalette> + +class CodeEditorSidebar : public QWidget +{ + Q_OBJECT +public: + explicit CodeEditorSidebar(CodeEditor *editor); + QSize sizeHint() const Q_DECL_OVERRIDE; + +protected: + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + +private: + CodeEditor *m_codeEditor; +}; + +CodeEditorSidebar::CodeEditorSidebar(CodeEditor *editor) : + QWidget(editor), + m_codeEditor(editor) +{ +} + +QSize CodeEditorSidebar::sizeHint() const +{ + return QSize(m_codeEditor->sidebarWidth(), 0); +} + +void CodeEditorSidebar::paintEvent(QPaintEvent *event) +{ + m_codeEditor->sidebarPaintEvent(event); +} + +void CodeEditorSidebar::mouseReleaseEvent(QMouseEvent *event) +{ + if (event->x() >= width() - m_codeEditor->fontMetrics().lineSpacing()) { + auto block = m_codeEditor->blockAtPosition(event->y()); + if (!block.isValid() || !m_codeEditor->isFoldable(block)) + return; + m_codeEditor->toggleFold(block); + } + QWidget::mouseReleaseEvent(event); +} + + +CodeEditor::CodeEditor(QWidget *parent) : + QPlainTextEdit(parent), + m_highlighter(new KSyntaxHighlighting::SyntaxHighlighter(document())), + m_sideBar(new CodeEditorSidebar(this)) +{ + setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); + + setTheme((palette().color(QPalette::Base).lightness() < 128) + ? m_repository.defaultTheme(KSyntaxHighlighting::Repository::DarkTheme) + : m_repository.defaultTheme(KSyntaxHighlighting::Repository::LightTheme)); + + connect(this, &QPlainTextEdit::blockCountChanged, this, &CodeEditor::updateSidebarGeometry); + connect(this, &QPlainTextEdit::updateRequest, this, &CodeEditor::updateSidebarArea); + connect(this, &QPlainTextEdit::cursorPositionChanged, this, &CodeEditor::highlightCurrentLine); + + updateSidebarGeometry(); + highlightCurrentLine(); +} + +CodeEditor::~CodeEditor() +{ +} + +void CodeEditor::openFile(const QString& fileName) +{ + QFile f(fileName); + if (!f.open(QFile::ReadOnly)) { + qWarning() << "Failed to open" << fileName << ":" << f.errorString(); + return; + } + + clear(); + + const auto def = m_repository.definitionForFileName(fileName); + m_highlighter->setDefinition(def); + + setWindowTitle(fileName); + setPlainText(QString::fromUtf8(f.readAll())); +} + +void CodeEditor::contextMenuEvent(QContextMenuEvent *event) +{ + auto menu = createStandardContextMenu(event->pos()); + menu->addSeparator(); + auto openAction = menu->addAction(QStringLiteral("Open File...")); + connect(openAction, &QAction::triggered, this, [this]() { + const auto fileName = QFileDialog::getOpenFileName(this, QStringLiteral("Open File")); + if (!fileName.isEmpty()) + openFile(fileName); + }); + + // syntax selection + auto hlActionGroup = new QActionGroup(menu); + hlActionGroup->setExclusive(true); + auto hlGroupMenu = menu->addMenu(QStringLiteral("Syntax")); + QMenu *hlSubMenu = hlGroupMenu; + QString currentGroup; + foreach (const auto &def, m_repository.definitions()) { + if (def.isHidden()) + continue; + if (currentGroup != def.section()) { + currentGroup = def.section(); + hlSubMenu = hlGroupMenu->addMenu(def.translatedSection()); + } + + Q_ASSERT(hlSubMenu); + auto action = hlSubMenu->addAction(def.translatedName()); + action->setCheckable(true); + action->setData(def.name()); + hlActionGroup->addAction(action); + if (def.name() == m_highlighter->definition().name()) + action->setChecked(true); + } + connect(hlActionGroup, &QActionGroup::triggered, this, [this](QAction *action) { + const auto defName = action->data().toString(); + const auto def = m_repository.definitionForName(defName); + m_highlighter->setDefinition(def); + }); + + // theme selection + auto themeGroup = new QActionGroup(menu); + themeGroup->setExclusive(true); + auto themeMenu = menu->addMenu(QStringLiteral("Theme")); + foreach (const auto &theme, m_repository.themes()) { + auto action = themeMenu->addAction(theme.translatedName()); + action->setCheckable(true); + action->setData(theme.name()); + themeGroup->addAction(action); + if (theme.name() == m_highlighter->theme().name()) + action->setChecked(true); + } + connect(themeGroup, &QActionGroup::triggered, this, [this](QAction *action) { + const auto themeName = action->data().toString(); + const auto theme = m_repository.theme(themeName); + setTheme(theme); + }); + + menu->exec(event->globalPos()); + delete menu; +} + +void CodeEditor::resizeEvent(QResizeEvent *event) +{ + QPlainTextEdit::resizeEvent(event); + updateSidebarGeometry(); +} + +void CodeEditor::setTheme(const KSyntaxHighlighting::Theme &theme) +{ + auto pal = qApp->palette(); + if (theme.isValid()) { + pal.setColor(QPalette::Base, theme.editorColor(KSyntaxHighlighting::Theme::BackgroundColor)); + pal.setColor(QPalette::Text, theme.textColor(KSyntaxHighlighting::Theme::Normal)); + pal.setColor(QPalette::Highlight, theme.editorColor(KSyntaxHighlighting::Theme::TextSelection)); + } + setPalette(pal); + + m_highlighter->setTheme(theme); + m_highlighter->rehighlight(); + highlightCurrentLine(); +} + +int CodeEditor::sidebarWidth() const +{ + int digits = 1; + auto count = blockCount(); + while (count >= 10) { + ++digits; + count /= 10; + } + return 4 + fontMetrics().width(QLatin1Char('9')) * digits + fontMetrics().lineSpacing(); +} + +void CodeEditor::sidebarPaintEvent(QPaintEvent *event) +{ + QPainter painter(m_sideBar); + painter.fillRect(event->rect(), m_highlighter->theme().editorColor(KSyntaxHighlighting::Theme::IconBorder)); + + auto block = firstVisibleBlock(); + auto blockNumber = block.blockNumber(); + int top = blockBoundingGeometry(block).translated(contentOffset()).top(); + int bottom = top + blockBoundingRect(block).height(); + const int currentBlockNumber = textCursor().blockNumber(); + + const auto foldingMarkerSize = fontMetrics().lineSpacing(); + + while (block.isValid() && top <= event->rect().bottom()) { + if (block.isVisible() && bottom >= event->rect().top()) { + const auto number = QString::number(blockNumber + 1); + painter.setPen(m_highlighter->theme().editorColor( + (blockNumber == currentBlockNumber) ? KSyntaxHighlighting::Theme::CurrentLineNumber + : KSyntaxHighlighting::Theme::LineNumbers)); + painter.drawText(0, top, m_sideBar->width() - 2 - foldingMarkerSize, fontMetrics().height(), Qt::AlignRight, number); + } + + // folding marker + if (block.isVisible() && isFoldable(block)) { + QPolygonF polygon; + if (isFolded(block)) { + polygon << QPointF(foldingMarkerSize * 0.4, foldingMarkerSize * 0.25); + polygon << QPointF(foldingMarkerSize * 0.4, foldingMarkerSize * 0.75); + polygon << QPointF(foldingMarkerSize * 0.8, foldingMarkerSize * 0.5); + } else { + polygon << QPointF(foldingMarkerSize * 0.25, foldingMarkerSize * 0.4); + polygon << QPointF(foldingMarkerSize * 0.75, foldingMarkerSize * 0.4); + polygon << QPointF(foldingMarkerSize * 0.5, foldingMarkerSize * 0.8); + } + painter.save(); + painter.setRenderHint(QPainter::Antialiasing); + painter.setPen(Qt::NoPen); + painter.setBrush(QColor(m_highlighter->theme().editorColor(KSyntaxHighlighting::Theme::CodeFolding))); + painter.translate(m_sideBar->width() - foldingMarkerSize, top); + painter.drawPolygon(polygon); + painter.restore(); + } + + block = block.next(); + top = bottom; + bottom = top + blockBoundingRect(block).height(); + ++blockNumber; + } +} + +void CodeEditor::updateSidebarGeometry() +{ + setViewportMargins(sidebarWidth(), 0, 0, 0); + const auto r = contentsRect(); + m_sideBar->setGeometry(QRect(r.left(), r.top(), sidebarWidth(), r.height())); +} + +void CodeEditor::updateSidebarArea(const QRect& rect, int dy) +{ + if (dy) + m_sideBar->scroll(0, dy); + else + m_sideBar->update(0, rect.y(), m_sideBar->width(), rect.height()); +} + +void CodeEditor::highlightCurrentLine() +{ + QTextEdit::ExtraSelection selection; + selection.format.setBackground(QColor(m_highlighter->theme().editorColor(KSyntaxHighlighting::Theme::CurrentLine))); + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + selection.cursor = textCursor(); + selection.cursor.clearSelection(); + + QList<QTextEdit::ExtraSelection> extraSelections; + extraSelections.append(selection); + setExtraSelections(extraSelections); +} + +QTextBlock CodeEditor::blockAtPosition(int y) const +{ + auto block = firstVisibleBlock(); + if (!block.isValid()) + return QTextBlock(); + + int top = blockBoundingGeometry(block).translated(contentOffset()).top(); + int bottom = top + blockBoundingRect(block).height(); + do { + if (top <= y && y <= bottom) + return block; + block = block.next(); + top = bottom; + bottom = top + blockBoundingRect(block).height(); + } while (block.isValid()); + return QTextBlock(); +} + +bool CodeEditor::isFoldable(const QTextBlock &block) const +{ + return m_highlighter->startsFoldingRegion(block); +} + +bool CodeEditor::isFolded(const QTextBlock &block) const +{ + if (!block.isValid()) + return false; + const auto nextBlock = block.next(); + if (!nextBlock.isValid()) + return false; + return !nextBlock.isVisible(); +} + +void CodeEditor::toggleFold(const QTextBlock &startBlock) +{ + // we also want to fold the last line of the region, therefore the ".next()" + const auto endBlock = m_highlighter->findFoldingRegionEnd(startBlock).next(); + + if (isFolded(startBlock)) { + // unfold + auto block = startBlock.next(); + while (block.isValid() && !block.isVisible()) { + block.setVisible(true); + block.setLineCount(block.layout()->lineCount()); + block = block.next(); + } + + } else { + // fold + auto block = startBlock.next(); + while (block.isValid() && block != endBlock) { + block.setVisible(false); + block.setLineCount(0); + block = block.next(); + } + } + + // redraw document + document()->markContentsDirty(startBlock.position(), endBlock.position() - startBlock.position() + 1); + + // update scrollbars + emit document()->documentLayout()->documentSizeChanged(document()->documentLayout()->documentSize()); +} + +#include "codeeditor.moc" diff --git a/src/libs/3rdparty/syntax-highlighting/examples/codeeditor.h b/src/libs/3rdparty/syntax-highlighting/examples/codeeditor.h new file mode 100644 index 0000000000..1823b43e85 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/examples/codeeditor.h @@ -0,0 +1,69 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef CODEEDITOR_H +#define CODEEDITOR_H + +#include <repository.h> + +#include <QPlainTextEdit> + +namespace KSyntaxHighlighting { +class SyntaxHighlighter; +} + +class CodeEditorSidebar; + +class CodeEditor : public QPlainTextEdit +{ + Q_OBJECT +public: + explicit CodeEditor(QWidget *parent = nullptr); + ~CodeEditor(); + + void openFile(const QString &fileName); + +protected: + void contextMenuEvent(QContextMenuEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + +private: + friend class CodeEditorSidebar; + void setTheme(const KSyntaxHighlighting::Theme &theme); + int sidebarWidth() const; + void sidebarPaintEvent(QPaintEvent *event); + void updateSidebarGeometry(); + void updateSidebarArea(const QRect &rect, int dy); + void highlightCurrentLine(); + + QTextBlock blockAtPosition(int y) const; + bool isFoldable(const QTextBlock &block) const; + bool isFolded(const QTextBlock &block) const; + void toggleFold(const QTextBlock &block); + + KSyntaxHighlighting::Repository m_repository; + KSyntaxHighlighting::SyntaxHighlighter *m_highlighter; + CodeEditorSidebar *m_sideBar; +}; + +#endif // CODEEDITOR_H diff --git a/src/libs/3rdparty/syntax-highlighting/examples/main.cpp b/src/libs/3rdparty/syntax-highlighting/examples/main.cpp new file mode 100644 index 0000000000..3fb542954d --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/examples/main.cpp @@ -0,0 +1,46 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "codeeditor.h" + +#include <QApplication> +#include <QCommandLineParser> +#include <QFile> +#include <QTextEdit> + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + QCommandLineParser parser; + parser.addHelpOption(); + parser.addPositionalArgument(QStringLiteral("source"), QStringLiteral("The source file to highlight.")); + parser.process(app); + + CodeEditor edit; + edit.resize(1024, 1024); + edit.show(); + if (parser.positionalArguments().size() == 1) + edit.openFile(parser.positionalArguments().at(0)); + return app.exec(); +} diff --git a/src/libs/3rdparty/syntax-highlighting/metainfo.yaml b/src/libs/3rdparty/syntax-highlighting/metainfo.yaml new file mode 100644 index 0000000000..7a3220a31e --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/metainfo.yaml @@ -0,0 +1,21 @@ +maintainer: vkrause +description: Syntax Highlighting +tier: 1 +type: functional +platforms: + - name: Linux + - name: FreeBSD + - name: Windows + - name: MacOSX + - name: Android +portingAid: false +deprecated: false +release: true +libraries: + - qmake: KSyntaxHighlighting + cmake: "KF5::SyntaxHighlighting" +cmakename: KF5SyntaxHighlighting + +public_lib: true +group: Frameworks +subgroup: Tier 1 diff --git a/src/libs/3rdparty/syntax-highlighting/org_kde_ksyntaxhighlighting.categories b/src/libs/3rdparty/syntax-highlighting/org_kde_ksyntaxhighlighting.categories new file mode 100644 index 0000000000..a35cfe2b73 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/org_kde_ksyntaxhighlighting.categories @@ -0,0 +1 @@ +org.kde.ksyntaxhighlighting Syntax Highlighting IDENTIFIER [KSyntaxHighlighting::Log] diff --git a/src/libs/3rdparty/syntax-highlighting/src/CMakeLists.txt b/src/libs/3rdparty/syntax-highlighting/src/CMakeLists.txt new file mode 100644 index 0000000000..b8820252c5 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/CMakeLists.txt @@ -0,0 +1,5 @@ +add_subdirectory(indexer) +if(TARGET Qt5::Gui) + add_subdirectory(lib) + add_subdirectory(cli) +endif() diff --git a/src/libs/3rdparty/syntax-highlighting/src/Messages.sh b/src/libs/3rdparty/syntax-highlighting/src/Messages.sh new file mode 100644 index 0000000000..6fb605ddf0 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/Messages.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +# extract language and section names from XML syntax definition files +# and adapt for lupdate-based extraction to match the rest of the code +$EXTRACTATTR --attr=language,name,Language --attr="language,section,Language Section" ../data/syntax/*.xml >> rc.cpp || exit 12 +sed -i -e 's/^i18nc/QT_TRANSLATE_NOOP/' rc.cpp + +grep --no-filename '"name"' ../data/themes/*.theme | \ + sed -r -e 's/"name"/QT_TRANSLATE_NOOP("Theme", /; s/://; s/,?$/);/' >> rc.cpp + +$EXTRACT_TR_STRINGS `find . -name \*.cpp -o -name \*.h -o -name \*.ui -o -name \*.qml` -o $podir/syntaxhighlighting5_qt.pot diff --git a/src/libs/3rdparty/syntax-highlighting/src/cli/CMakeLists.txt b/src/libs/3rdparty/syntax-highlighting/src/cli/CMakeLists.txt new file mode 100644 index 0000000000..113115359e --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/cli/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(kate-syntax-highlighter kate-syntax-highlighter.cpp) +ecm_mark_nongui_executable(kate-syntax-highlighter) +target_link_libraries(kate-syntax-highlighter KF5SyntaxHighlighting) + +install(TARGETS kate-syntax-highlighter ${INSTALL_TARGETS_DEFAULT_ARGS}) diff --git a/src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp new file mode 100644 index 0000000000..80a15d2589 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp @@ -0,0 +1,164 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "ksyntaxhighlighting_version.h" + +#include <definition.h> +#include <definitiondownloader.h> +#include <htmlhighlighter.h> +#include <repository.h> +#include <theme.h> + +#include <QCommandLineParser> +#include <QCoreApplication> +#include <QFile> +#include <QVector> + +#include <iostream> + +using namespace KSyntaxHighlighting; + +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + QCoreApplication::setApplicationName(QStringLiteral("kate-syntax-highlighter")); + QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org")); + QCoreApplication::setOrganizationName(QStringLiteral("KDE")); + QCoreApplication::setApplicationVersion(QStringLiteral(SyntaxHighlighting_VERSION_STRING)); + + QCommandLineParser parser; + parser.setApplicationDescription(app.translate("SyntaxHighlightingCLI", "Command line syntax highlighter using Kate syntax definitions.")); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument(app.translate("SyntaxHighlightingCLI", "source"), + app.translate("SyntaxHighlightingCLI", "The source file to highlight.")); + + QCommandLineOption listDefs(QStringList() << QStringLiteral("l") << QStringLiteral("list"), + app.translate("SyntaxHighlightingCLI", "List all available syntax definitions.")); + parser.addOption(listDefs); + QCommandLineOption listThemes(QStringList() << QStringLiteral("list-themes"), + app.translate("SyntaxHighlightingCLI", "List all available themes.")); + parser.addOption(listThemes); + + QCommandLineOption updateDefs(QStringList() << QStringLiteral("u") << QStringLiteral("update"), + app.translate("SyntaxHighlightingCLI", "Download new/updated syntax definitions.")); + parser.addOption(updateDefs); + + QCommandLineOption outputName(QStringList() << QStringLiteral("o") << QStringLiteral("output"), + app.translate("SyntaxHighlightingCLI", "File to write HTML output to (default: stdout)."), + app.translate("SyntaxHighlightingCLI", "output")); + parser.addOption(outputName); + + QCommandLineOption syntaxName(QStringList() << QStringLiteral("s") << QStringLiteral("syntax"), + app.translate("SyntaxHighlightingCLI", "Highlight using this syntax definition (default: auto-detect based on input file)."), + app.translate("SyntaxHighlightingCLI", "syntax")); + parser.addOption(syntaxName); + + QCommandLineOption themeName(QStringList() << QStringLiteral("t") << QStringLiteral("theme"), + app.translate("SyntaxHighlightingCLI", "Color theme to use for highlighting."), + app.translate("SyntaxHighlightingCLI", "theme"), QStringLiteral("Default")); + parser.addOption(themeName); + + QCommandLineOption titleOption(QStringList() << QStringLiteral("T") << QStringLiteral("title"), + app.translate("SyntaxHighlightingCLI", "Set HTML page's title\n(default: the filename or \"Kate Syntax Highlighter\" if reading from stdin)."), + app.translate("SyntaxHighlightingCLI", "title")); + parser.addOption(titleOption); + + QCommandLineOption stdinOption(QStringList() << QStringLiteral("stdin"), + app.translate("SyntaxHighlightingCLI", "Read file from stdin. The -s option must also be used.")); + parser.addOption(stdinOption); + + parser.process(app); + + Repository repo; + if (parser.isSet(listDefs)) { + foreach (const auto &def, repo.definitions()) { + std::cout << qPrintable(def.name()) << std::endl; + } + return 0; + } + + if (parser.isSet(listThemes)) { + foreach (const auto &theme, repo.themes()) + std::cout << qPrintable(theme.name()) << std::endl; + return 0; + } + + if (parser.isSet(updateDefs)) { + DefinitionDownloader downloader(&repo); + QObject::connect(&downloader, &DefinitionDownloader::informationMessage, [](const QString &msg) { + std::cout << qPrintable(msg) << std::endl; + }); + QObject::connect(&downloader, &DefinitionDownloader::done, &app, &QCoreApplication::quit); + downloader.start(); + return app.exec(); + } + + bool fromFileName = false; + QString inFileName; + if (parser.positionalArguments().size() == 1) { + fromFileName = true; + inFileName = parser.positionalArguments().at(0); + } + + Definition def; + if (parser.isSet(syntaxName)) { + def = repo.definitionForName(parser.value(syntaxName)); + if (!def.isValid()) + /* see if it's a mimetype instead */ + def = repo.definitionForMimeType(parser.value(syntaxName)); + } else if (fromFileName) { + def = repo.definitionForFileName(inFileName); + } else { + parser.showHelp(1); + } + + QString title; + if (parser.isSet(titleOption)) + title = parser.value(titleOption); + + if (!def.isValid()) { + std::cerr << "Unknown syntax." << std::endl; + return 1; + } + + HtmlHighlighter highlighter; + highlighter.setDefinition(def); + if (parser.isSet(outputName)) + highlighter.setOutputFile(parser.value(outputName)); + else + highlighter.setOutputFile(stdout); + highlighter.setTheme(repo.theme(parser.value(themeName))); + + if (fromFileName) { + highlighter.highlightFile(inFileName, title); + } else if (parser.isSet(stdinOption)) { + QFile inFile; + inFile.open(stdin, QIODevice::ReadOnly); + highlighter.highlightData(&inFile, title); + } else { + parser.showHelp(1); + } + + return 0; +} diff --git a/src/libs/3rdparty/syntax-highlighting/src/indexer/CMakeLists.txt b/src/libs/3rdparty/syntax-highlighting/src/indexer/CMakeLists.txt new file mode 100644 index 0000000000..9fa26b27ce --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/indexer/CMakeLists.txt @@ -0,0 +1,36 @@ +# when cross compiling, use either the executable offered or try to cross-compile it in place + +if(CMAKE_CROSSCOMPILING AND KATEHIGHLIGHTINGINDEXER_EXECUTABLE) + add_executable(katehighlightingindexer IMPORTED GLOBAL) + set_target_properties(katehighlightingindexer PROPERTIES IMPORTED_LOCATION ${KATEHIGHLIGHTINGINDEXER_EXECUTABLE}) +elseif(CMAKE_CROSSCOMPILING) + if (NOT KF5_HOST_TOOLING) + message(FATAL_ERROR "Please provide a prefix with a native Qt build and pass -DKF5_HOST_TOOLING=path") + endif() + + # search native tooling prefix + string(FIND ${KF5_HOST_TOOLING} /lib idx) + string(SUBSTRING ${KF5_HOST_TOOLING} 0 ${idx} NATIVE_PREFIX) + message(STATUS "Building katehighlightingindexer against ${NATIVE_PREFIX}") + + include(ExternalProject) + ExternalProject_Add(native_katehighlightingindexer + SOURCE_DIR ${CMAKE_SOURCE_DIR} + CMAKE_ARGS -DKSYNTAXHIGHLIGHTING_USE_GUI=OFF + -DECM_DIR=${ECM_DIR} -DCMAKE_PREFIX_PATH=${NATIVE_PREFIX} + -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR} + INSTALL_COMMAND "" + ) + add_executable(katehighlightingindexer IMPORTED GLOBAL) + add_dependencies(katehighlightingindexer native_katehighlightingindexer) + set_target_properties(katehighlightingindexer PROPERTIES IMPORTED_LOCATION + ${CMAKE_CURRENT_BINARY_DIR}/native_katehighlightingindexer-prefix/src/native_katehighlightingindexer-build/bin/katehighlightingindexer) +else() + # host build + add_executable(katehighlightingindexer katehighlightingindexer.cpp) + if(Qt5XmlPatterns_FOUND) + target_link_libraries(katehighlightingindexer Qt5::XmlPatterns) + else() + target_link_libraries(katehighlightingindexer Qt5::Core) + endif() +endif() diff --git a/src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp b/src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp new file mode 100644 index 0000000000..489fbec160 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp @@ -0,0 +1,589 @@ +/* + Copyright (C) 2014 Christoph Cullmann <cullmann@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <QCoreApplication> +#include <QFile> +#include <QFileInfo> +#include <QTextStream> +#include <QVariant> +#include <QXmlStreamReader> +#include <QJsonDocument> +#include <QRegularExpression> +#include <QDebug> + +#ifdef QT_XMLPATTERNS_LIB +#include <QXmlSchema> +#include <QXmlSchemaValidator> +#endif + +namespace { + +QStringList readListing(const QString &fileName) +{ + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly)) { + return QStringList(); + } + + QXmlStreamReader xml(&file); + QStringList listing; + while (!xml.atEnd()) { + xml.readNext(); + + // add only .xml files, no .json or stuff + if (xml.isCharacters() && xml.text().toString().contains(QLatin1String(".xml"))) { + listing.append(xml.text().toString()); + } + } + + if (xml.hasError()) { + qWarning() << "XML error while reading" << fileName << " - " + << qPrintable(xml.errorString()) << "@ offset" << xml.characterOffset(); + } + + return listing; +} + +/** + * check if the "extensions" attribute have valid wildcards + * @param extensions extensions string to check + * @return valid? + */ +bool checkExtensions(QString extensions) +{ + // get list of extensions + const QStringList extensionParts = extensions.split(QLatin1Char(';'), QString::SkipEmptyParts); + + // ok if empty + if (extensionParts.isEmpty()) { + return true; + } + + // check that only valid wildcard things are inside the parts + for (const auto& extension : extensionParts) { + for (const auto c : extension) { + // eat normal things + if (c.isDigit() || c.isLetter()) { + continue; + } + + // allow some special characters + if (c == QLatin1Char('.') || c == QLatin1Char('-') || c == QLatin1Char('_') || c == QLatin1Char('+')) { + continue; + } + + // only allowed wildcard things: '?' and '*' + if (c == QLatin1Char('?') || c == QLatin1Char('*')) { + continue; + } + + qWarning() << "invalid character" << c << " seen in extensions wildcard"; + return false; + } + } + + // all checks passed + return true; +} + +//! Check that a regular expression in a RegExpr rule: +//! - is not empty +//! - isValid() +//! - character ranges such as [A-Z] are valid and not accidentally e.g. [A-z]. +bool checkRegularExpression(const QString &hlFilename, QXmlStreamReader &xml) +{ + if (xml.name() == QLatin1String("RegExpr") || xml.name() == QLatin1String("emptyLine")) { + // get right attribute + const QString string (xml.attributes().value((xml.name() == QLatin1String("RegExpr")) ? QLatin1String("String") : QLatin1String("regexpr")).toString()); + + // validate regexp + const QRegularExpression regexp (string); + if (!regexp.isValid()) { + qWarning() << hlFilename << "line" << xml.lineNumber() << "broken regex:" << string << "problem:" << regexp.errorString() << "at offset" << regexp.patternErrorOffset(); + return false; + } else if (string.isEmpty()) { + qWarning() << hlFilename << "line" << xml.lineNumber() << "empty regex not allowed."; + return false; + } + + // catch possible case typos: [A-z] or [a-Z] + const int azOffset = std::max(string.indexOf(QStringLiteral("A-z")), string.indexOf(QStringLiteral("a-Z"))); + if (azOffset >= 0) { + qWarning() << hlFilename << "line" << xml.lineNumber() << "broken regex:" << string << "problem: [a-Z] or [A-z] at offset" << azOffset; + return false; + } + } + + return true; +} + +//! Check that keyword list items do not have trailing or leading spaces, +//! e.g.: <item> keyword </item> +bool checkItemsTrimmed(const QString &hlFilename, QXmlStreamReader &xml) +{ + if (xml.name() == QLatin1String("item")) { + const QString keyword = xml.readElementText(); + if (keyword != keyword.trimmed()) { + qWarning() << hlFilename << "line" << xml.lineNumber() << "keyword with leading/trailing spaces:" << keyword; + return false; + } + } + + return true; +} + +//! Checks that DetectChar and Detect2Chars really only have one char +//! in the attributes 'char' and 'char1'. +bool checkSingleChars(const QString &hlFilename, QXmlStreamReader &xml) +{ + const bool testChar1 = xml.name() == QLatin1String("Detect2Chars"); + const bool testChar = testChar1 || xml.name() == QLatin1String("DetectChar"); + + if (testChar) { + const QString c = xml.attributes().value(QLatin1String("char")).toString(); + if (c.size() != 1) { + qWarning() << hlFilename << "line" << xml.lineNumber() << "'char' must contain exactly one char:" << c; + } + } + + if (testChar1) { + const QString c = xml.attributes().value(QLatin1String("char1")).toString(); + if (c.size() != 1) { + qWarning() << hlFilename << "line" << xml.lineNumber() << "'char1' must contain exactly one char:" << c; + } + } + + return true; +} + +//! Search for rules with lookAhead="true" and context="#stay". +//! This would cause an infinite loop. +bool checkLookAhead(const QString &hlFilename, QXmlStreamReader &xml) +{ + if (xml.attributes().hasAttribute(QStringLiteral("lookAhead"))) { + auto lookAhead = xml.attributes().value(QStringLiteral("lookAhead")); + if (lookAhead == QStringLiteral("true")) { + auto context = xml.attributes().value(QStringLiteral("context")); + if (context == QStringLiteral("#stay")) { + qWarning() << hlFilename << "line" << xml.lineNumber() << "Infinite loop: lookAhead with context #stay"; + return false; + } + } + } + return true; +} + +/** + * Helper class to search for non-existing or unreferenced keyword lists. + */ +class KeywordChecker +{ +public: + KeywordChecker(const QString &filename) + : m_filename(filename) + {} + + void processElement(QXmlStreamReader &xml) + { + if (xml.name() == QLatin1String("list")) { + const QString name = xml.attributes().value(QLatin1String("name")).toString(); + if (m_existingNames.contains(name)) { + qWarning() << m_filename << "list duplicate:" << name; + } + m_existingNames.insert(name); + } else if (xml.name() == QLatin1String("keyword")) { + const QString context = xml.attributes().value(QLatin1String("String")).toString(); + if (!context.isEmpty()) + m_usedNames.insert(context); + } + } + + bool check() const + { + bool success = true; + const auto invalidNames = m_usedNames - m_existingNames; + if (!invalidNames.isEmpty()) { + qWarning() << m_filename << "Reference of non-existing keyword list:" << invalidNames; + success = false; + } + + const auto unusedNames = m_existingNames - m_usedNames; + if (!unusedNames.isEmpty()) { + qWarning() << m_filename << "Unused keyword lists:" << unusedNames; + } + + return success; + } + +private: + QString m_filename; + QSet<QString> m_usedNames; + QSet<QString> m_existingNames; +}; + +/** + * Helper class to search for non-existing contexts + */ +class ContextChecker +{ +public: + void processElement(const QString &hlFilename, const QString &hlName, QXmlStreamReader &xml) + { + if (xml.name() == QLatin1String("context")) { + auto & language = m_contextMap[hlName]; + language.hlFilename = hlFilename; + const QString name = xml.attributes().value(QLatin1String("name")).toString(); + if (language.isFirstContext) { + language.isFirstContext = false; + language.usedContextNames.insert(name); + } + + if (language.existingContextNames.contains(name)) { + qWarning() << hlFilename << "Duplicate context:" << name; + } else { + language.existingContextNames.insert(name); + } + + if (xml.attributes().value(QLatin1String("fallthroughContext")).toString() == QLatin1String("#stay")) { + qWarning() << hlFilename << "possible infinite loop due to fallthroughContext=\"#stay\" in context " << name; + } + + processContext(hlName, xml.attributes().value(QLatin1String("lineEndContext")).toString()); + processContext(hlName, xml.attributes().value(QLatin1String("lineEmptyContext")).toString()); + processContext(hlName, xml.attributes().value(QLatin1String("fallthroughContext")).toString()); + } else { + if (xml.attributes().hasAttribute(QLatin1String("context"))) { + const QString context = xml.attributes().value(QLatin1String("context")).toString(); + if (context.isEmpty()) { + qWarning() << hlFilename << "Missing context name in line" << xml.lineNumber(); + } else { + processContext(hlName, context); + } + } + } + } + + bool check() const + { + bool success = true; + for (auto &language : m_contextMap) { + const auto invalidContextNames = language.usedContextNames - language.existingContextNames; + if (!invalidContextNames.isEmpty()) { + qWarning() << language.hlFilename << "Reference of non-existing contexts:" << invalidContextNames; + success = false; + } + + const auto unusedNames = language.existingContextNames - language.usedContextNames; + if (!unusedNames.isEmpty()) { + qWarning() << language.hlFilename << "Unused contexts:" << unusedNames; + } + } + + return success; + } + +private: + //! Extract the referenced context name and language. + //! Some input / output examples are: + //! - "#stay" -> "" + //! - "#pop" -> "" + //! - "Comment" -> "Comment" + //! - "#pop!Comment" -> "Comment" + //! - "##ISO C++" -> "" + //! - "Comment##ISO C++"-> "Comment" in ISO C++ + void processContext(const QString &language, QString context) + { + if (context.isEmpty()) + return; + + // filter out #stay and #pop + static QRegularExpression stayPop(QStringLiteral("^(#stay|#pop)+")); + context.remove(stayPop); + + // handle cross-language context references + if (context.contains(QStringLiteral("##"))) { + const QStringList list = context.split(QStringLiteral("##"), QString::SkipEmptyParts); + if (list.size() == 1) { + // nothing to do, other language is included: e.g. ##Doxygen + } else if (list.size() == 2) { + // specific context of other language, e.g. Comment##ISO C++ + m_contextMap[list[1]].usedContextNames.insert(list[0]); + } + return; + } + + // handle #pop!context" (#pop was already removed above) + if (context.startsWith(QLatin1Char('!'))) + context.remove(0, 1); + + if (!context.isEmpty()) + m_contextMap[language].usedContextNames.insert(context); + } + +private: + class Language + { + public: + // filename on disk or in Qt resource + QString hlFilename; + + // Is true, if the first context in xml file is encountered, and + // false in all other cases. This is required, since the first context + // is typically not referenced explicitly. So we will simply add the + // first context to the usedContextNames list. + bool isFirstContext = true; + + // holds all contexts that were referenced + QSet<QString> usedContextNames; + + // holds all existing context names + QSet<QString> existingContextNames; + }; + + /** + * "Language name" to "Language" map. + * Example key: "Doxygen" + */ + QHash<QString, Language> m_contextMap; +}; + +/** + * Helper class to search for non-existing itemDatas. + */ +class AttributeChecker +{ +public: + AttributeChecker(const QString &filename) + : m_filename(filename) + {} + + void processElement(QXmlStreamReader &xml) + { + if (xml.name() == QLatin1String("itemData")) { + const QString name = xml.attributes().value(QLatin1String("name")).toString(); + if (!name.isEmpty()) { + if (m_existingAttributeNames.contains(name)) { + qWarning() << m_filename << "itemData duplicate:" << name; + } else { + m_existingAttributeNames.insert(name); + } + } + } else if (xml.attributes().hasAttribute(QLatin1String("attribute"))) { + const QString name = xml.attributes().value(QLatin1String("attribute")).toString(); + if (name.isEmpty()) { + qWarning() << m_filename << "specified attribute is empty:" << xml.name(); + } else { + m_usedAttributeNames.insert(name); + } + } + } + + bool check() const + { + bool success = true; + const auto invalidNames = m_usedAttributeNames - m_existingAttributeNames; + if (!invalidNames.isEmpty()) { + qWarning() << m_filename << "Reference of non-existing itemData attributes:" << invalidNames; + success = false; + } + + auto unusedNames = m_existingAttributeNames - m_usedAttributeNames; + if (!unusedNames.isEmpty()) { + qWarning() << m_filename << "Unused itemData:" << unusedNames; + } + + return success; + } + +private: + QString m_filename; + QSet<QString> m_usedAttributeNames; + QSet<QString> m_existingAttributeNames; +}; + +} + +int main(int argc, char *argv[]) +{ + // get app instance + QCoreApplication app(argc, argv); + + // ensure enough arguments are passed + if (app.arguments().size() < 3) + return 1; + +#ifdef QT_XMLPATTERNS_LIB + // open schema + QXmlSchema schema; + if (!schema.load(QUrl::fromLocalFile(app.arguments().at(2)))) + return 2; +#endif + + const QString hlFilenamesListing = app.arguments().value(3); + if (hlFilenamesListing.isEmpty()) { + return 1; + } + + QStringList hlFilenames = readListing(hlFilenamesListing); + if (hlFilenames.isEmpty()) { + qWarning("Failed to read %s", qPrintable(hlFilenamesListing)); + return 3; + } + + // text attributes + const QStringList textAttributes = QStringList() << QStringLiteral("name") << QStringLiteral("section") << QStringLiteral("mimetype") + << QStringLiteral("extensions") << QStringLiteral("style") + << QStringLiteral("author") << QStringLiteral("license") << QStringLiteral("indenter"); + + // index all given highlightings + ContextChecker contextChecker; + QVariantMap hls; + int anyError = 0; + foreach (const QString &hlFilename, hlFilenames) { + QFile hlFile(hlFilename); + if (!hlFile.open(QIODevice::ReadOnly)) { + qWarning ("Failed to open %s", qPrintable(hlFilename)); + anyError = 3; + continue; + } + +#ifdef QT_XMLPATTERNS_LIB + // validate against schema + QXmlSchemaValidator validator(schema); + if (!validator.validate(&hlFile, QUrl::fromLocalFile(hlFile.fileName()))) { + anyError = 4; + continue; + } +#endif + + // read the needed attributes from toplevel language tag + hlFile.reset(); + QXmlStreamReader xml(&hlFile); + if (xml.readNextStartElement()) { + if (xml.name() != QLatin1String("language")) { + anyError = 5; + continue; + } + } else { + anyError = 6; + continue; + } + + // map to store hl info + QVariantMap hl; + + // transfer text attributes + Q_FOREACH (const QString &attribute, textAttributes) { + hl[attribute] = xml.attributes().value(attribute).toString(); + } + + // check if extensions have the right format + if (!checkExtensions(hl[QStringLiteral("extensions")].toString())) { + qWarning() << hlFilename << "'extensions' wildcards invalid:" << hl[QStringLiteral("extensions")].toString(); + anyError = 23; + } + + // numerical attributes + hl[QStringLiteral("version")] = xml.attributes().value(QLatin1String("version")).toInt(); + hl[QStringLiteral("priority")] = xml.attributes().value(QLatin1String("priority")).toInt(); + + // add boolean one + const QString hidden = xml.attributes().value(QLatin1String("hidden")).toString(); + hl[QStringLiteral("hidden")] = (hidden == QLatin1String("true") || hidden == QLatin1String("1")); + + // remember hl + hls[QFileInfo(hlFile).fileName()] = hl; + + AttributeChecker attributeChecker(hlFilename); + KeywordChecker keywordChecker(hlFilename); + const QString hlName = hl[QStringLiteral("name")].toString(); + + // scan for broken regex or keywords with spaces + while (!xml.atEnd()) { + xml.readNext(); + if (!xml.isStartElement()) { + continue; + } + + // search for used/existing contexts if applicable + contextChecker.processElement(hlFilename, hlName, xml); + + // search for used/existing attributes if applicable + attributeChecker.processElement(xml); + + // search for used/existing keyword lists if applicable + keywordChecker.processElement(xml); + + // scan for bad regex + if (!checkRegularExpression(hlFilename, xml)) { + anyError = 7; + continue; + } + + // scan for bogus <item> lala </item> spaces + if (!checkItemsTrimmed(hlFilename, xml)) { + anyError = 8; + continue; + } + + // check single chars in DetectChar and Detect2Chars + if (!checkSingleChars(hlFilename, xml)) { + anyError = 8; + continue; + } + + // scan for lookAhead="true" with context="#stay" + if (!checkLookAhead(hlFilename, xml)) { + anyError = 7; + continue; + } + } + + if (!attributeChecker.check()) { + anyError = 7; + } + + if (!keywordChecker.check()) { + anyError = 7; + } + } + + if (!contextChecker.check()) + anyError = 7; + + + // bail out if any problem was seen + if (anyError) + return anyError; + + // create outfile, after all has worked! + QFile outFile(app.arguments().at(1)); + if (!outFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) + return 9; + + // write out json + outFile.write(QJsonDocument::fromVariant(QVariant(hls)).toBinaryData()); + + // be done + return 0; +} diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt b/src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt new file mode 100644 index 0000000000..bf729fca71 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt @@ -0,0 +1,86 @@ +ecm_create_qm_loader(syntax_highlighting_QM_LOADER syntaxhighlighting5_qt) + +set(syntax_highlighting_srcs + abstracthighlighter.cpp + context.cpp + contextswitch.cpp + definitiondownloader.cpp + foldingregion.cpp + format.cpp + htmlhighlighter.cpp + keywordlist.cpp + rule.cpp + definition.cpp + repository.cpp + state.cpp + syntaxhighlighter.cpp + theme.cpp + wildcardmatcher.cpp + themedata.cpp + ${syntax_highlighting_QM_LOADER} +) +ecm_qt_declare_logging_category(syntax_highlighting_srcs + HEADER ksyntaxhighlighting_logging.h + IDENTIFIER KSyntaxHighlighting::Log + CATEGORY_NAME org.kde.ksyntaxhighlighting +) + +add_library(KF5SyntaxHighlighting ${syntax_highlighting_srcs} $<TARGET_OBJECTS:SyntaxHighlightingData>) +generate_export_header(KF5SyntaxHighlighting BASE_NAME KSyntaxHighlighting) +set_target_properties(KF5SyntaxHighlighting PROPERTIES + VERSION ${SyntaxHighlighting_VERSION_STRING} + SOVERSION ${SyntaxHighlighting_SOVERSION} + EXPORT_NAME SyntaxHighlighting +) +target_include_directories(KF5SyntaxHighlighting INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR_KF5}/KSyntaxHighlighting;${KDE_INSTALL_INCLUDEDIR_KF5}>") +target_include_directories(KF5SyntaxHighlighting PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_BINARY_DIR};>") +target_link_libraries(KF5SyntaxHighlighting LINK_PUBLIC Qt5::Gui LINK_PRIVATE Qt5::Network) + +ecm_generate_headers(SyntaxHighlighting_HEADERS + HEADER_NAMES + AbstractHighlighter + Definition + FoldingRegion + Format + Repository + State + SyntaxHighlighter + Theme + REQUIRED_HEADERS SyntaxHighlighting_HEADERS +) + +install(TARGETS KF5SyntaxHighlighting EXPORT KF5SyntaxHighlightingTargets ${INSTALL_TARGETS_DEFAULT_ARGS}) +install(FILES + ${SyntaxHighlighting_HEADERS} + ${CMAKE_CURRENT_BINARY_DIR}/ksyntaxhighlighting_export.h + DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/KSyntaxHighlighting) + +if(BUILD_QCH) + ecm_add_qch( + KF5SyntaxHighlighting_QCH + NAME KSyntaxHighlighting + BASE_NAME KF5SyntaxHighlighting + VERSION ${KF5_VERSION} + ORG_DOMAIN org.kde + SOURCES # using only public headers, to cover only public API + ${SyntaxHighlighting_HEADERS} + MD_MAINPAGE "${CMAKE_SOURCE_DIR}/README.md" + LINK_QCHS + Qt5Core_QCH + Qt5Gui_QCH + BLANK_MACROS + KSYNTAXHIGHLIGHTING_EXPORT + KSYNTAXHIGHLIGHTING_DEPRECATED + TAGFILE_INSTALL_DESTINATION ${KDE_INSTALL_QTQCHDIR} + QCH_INSTALL_DESTINATION ${KDE_INSTALL_QTQCHDIR} + COMPONENT Devel + ) +endif() +ecm_generate_pri_file( + BASE_NAME KSyntaxHighlighting LIB_NAME + KF5SyntaxHighlighting + DEPS "gui" + FILENAME_VAR PRI_FILENAME + INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR_KF5}/KSyntaxHighlighting +) +install(FILES ${PRI_FILENAME} DESTINATION ${ECM_MKSPECS_INSTALL_DIR}) diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp new file mode 100644 index 0000000000..f69944debd --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp @@ -0,0 +1,328 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "abstracthighlighter.h" +#include "abstracthighlighter_p.h" +#include "context_p.h" +#include "definition_p.h" +#include "foldingregion.h" +#include "format.h" +#include "repository.h" +#include "rule_p.h" +#include "state.h" +#include "state_p.h" +#include "ksyntaxhighlighting_logging.h" +#include "theme.h" + +using namespace KSyntaxHighlighting; + +AbstractHighlighterPrivate::AbstractHighlighterPrivate() +{ +} + +AbstractHighlighterPrivate::~AbstractHighlighterPrivate() +{ +} + +void AbstractHighlighterPrivate::ensureDefinitionLoaded() +{ + auto defData = DefinitionData::get(m_definition); + if (Q_UNLIKELY(!m_definition.isValid() && defData->repo && !m_definition.name().isEmpty())) { + qCDebug(Log) << "Definition became invalid, trying re-lookup."; + m_definition = defData->repo->definitionForName(m_definition.name()); + defData = DefinitionData::get(m_definition); + } + + if (Q_UNLIKELY(!defData->repo && !defData->name.isEmpty())) + qCCritical(Log) << "Repository got deleted while a highlighter is still active!"; + + if (m_definition.isValid()) + defData->load(); +} + +AbstractHighlighter::AbstractHighlighter() : + d_ptr(new AbstractHighlighterPrivate) +{ +} + +AbstractHighlighter::AbstractHighlighter(AbstractHighlighterPrivate *dd) : + d_ptr(dd) +{ +} + +AbstractHighlighter::~AbstractHighlighter() +{ + delete d_ptr; +} + +Definition AbstractHighlighter::definition() const +{ + return d_ptr->m_definition; +} + +void AbstractHighlighter::setDefinition(const Definition &def) +{ + Q_D(AbstractHighlighter); + d->m_definition = def; +} + +Theme AbstractHighlighter::theme() const +{ + Q_D(const AbstractHighlighter); + return d->m_theme; +} + +void AbstractHighlighter::setTheme(const Theme &theme) +{ + Q_D(AbstractHighlighter); + d->m_theme = theme; +} + +/** + * Returns the index of the first non-space character. If the line is empty, + * or only contains white spaces, text.size() is returned. + */ +static inline int firstNonSpaceChar(const QString & text) +{ + for (int i = 0; i < text.length(); ++i) { + if (!text[i].isSpace()) { + return i; + } + } + return text.size(); +} + +State AbstractHighlighter::highlightLine(const QString& text, const State &state) +{ + Q_D(AbstractHighlighter); + + // verify definition, deal with no highlighting being enabled + d->ensureDefinitionLoaded(); + if (!d->m_definition.isValid()) { + applyFormat(0, text.size(), Format()); + return State(); + } + + // verify/initialize state + auto defData = DefinitionData::get(d->m_definition); + auto newState = state; + auto stateData = StateData::get(newState); + const DefinitionRef currentDefRef(d->m_definition); + if (!stateData->isEmpty() && (stateData->m_defRef != currentDefRef)) { + qCDebug(Log) << "Got invalid state, resetting."; + stateData->clear(); + } + if (stateData->isEmpty()) { + stateData->push(defData->initialContext(), QStringList()); + stateData->m_defRef = currentDefRef; + } + + // process empty lines + if (text.isEmpty()) { + while (!stateData->topContext()->lineEmptyContext().isStay()) { + if (!d->switchContext(stateData, stateData->topContext()->lineEmptyContext(), QStringList())) + break; + } + auto context = stateData->topContext(); + applyFormat(0, 0, context->attributeFormat()); + return newState; + } + + int offset = 0, beginOffset = 0; + bool lineContinuation = false; + QHash<Rule*, int> skipOffsets; + + /** + * current active format + * stored as pointer to avoid deconstruction/constructions inside the internal loop + * the pointers are stable, the formats are either in the contexts or rules + */ + auto currentFormat = &stateData->topContext()->attributeFormat(); + + /** + * cached first non-space character, needs to be computed if < 0 + */ + int firstNonSpace = -1; + int lastOffset = offset; + int endlessLoopingCounter = 0; + do { + /** + * avoid that we loop endless for some broken hl definitions + */ + if (lastOffset == offset) { + ++endlessLoopingCounter; + if (endlessLoopingCounter > 1024) { + qCDebug(Log) << "Endless state transitions, aborting highlighting of line."; + break; + } + } else { + // ensure we made progress, clear the endlessLoopingCounter + Q_ASSERT(offset > lastOffset); + lastOffset = offset; + endlessLoopingCounter = 0; + } + + /** + * try to match all rules in the context in order of declaration in XML + */ + bool isLookAhead = false; + int newOffset = 0; + const Format *newFormat = nullptr; + for (const auto &rule : stateData->topContext()->rules()) { + /** + * filter out rules that require a specific column + */ + if ((rule->requiredColumn() >= 0) && (rule->requiredColumn() != offset)) { + continue; + } + + /** + * filter out rules that only match for leading whitespace + */ + if (rule->firstNonSpace()) { + /** + * compute the first non-space lazy + * avoids computing it for contexts without any such rules + */ + if (firstNonSpace < 0) { + firstNonSpace = firstNonSpaceChar(text); + } + + /** + * can we skip? + */ + if (offset > firstNonSpace) { + continue; + } + } + + /** + * shall we skip application of this rule? two cases: + * - rule can't match at all => currentSkipOffset < 0 + * - rule will only match for some higher offset => currentSkipOffset > offset + */ + const auto currentSkipOffset = skipOffsets.value(rule.get()); + if (currentSkipOffset < 0 || currentSkipOffset > offset) + continue; + + + const auto newResult = rule->doMatch(text, offset, stateData->topCaptures()); + newOffset = newResult.offset(); + + /** + * update skip offset if new one rules out any later match or is larger than current one + */ + if (newResult.skipOffset() < 0 || newResult.skipOffset() > currentSkipOffset) + skipOffsets.insert(rule.get(), newResult.skipOffset()); + + if (newOffset <= offset) + continue; + + // apply folding + if (rule->endRegion().isValid()) + applyFolding(offset, newOffset - offset, rule->endRegion()); + if (rule->beginRegion().isValid()) + applyFolding(offset, newOffset - offset, rule->beginRegion()); + + if (rule->isLookAhead()) { + Q_ASSERT(!rule->context().isStay()); + d->switchContext(stateData, rule->context(), newResult.captures()); + isLookAhead = true; + break; + } + + d->switchContext(stateData, rule->context(), newResult.captures()); + newFormat = rule->attributeFormat().isValid() ? &rule->attributeFormat() : &stateData->topContext()->attributeFormat(); + if (newOffset == text.size() && std::dynamic_pointer_cast<LineContinue>(rule)) + lineContinuation = true; + break; + } + if (isLookAhead) + continue; + + if (newOffset <= offset) { // no matching rule + if (stateData->topContext()->fallthrough()) { + d->switchContext(stateData, stateData->topContext()->fallthroughContext(), QStringList()); + continue; + } + + newOffset = offset + 1; + newFormat = &stateData->topContext()->attributeFormat(); + } + + /** + * if we arrive here, some new format has to be set! + */ + Q_ASSERT(newFormat); + + /** + * on format change, apply the last one and switch to new one + */ + if (newFormat != currentFormat && newFormat->id() != currentFormat->id()) { + if (offset > 0) + applyFormat(beginOffset, offset - beginOffset, *currentFormat); + beginOffset = offset; + currentFormat = newFormat; + } + + /** + * we must have made progress if we arrive here! + */ + Q_ASSERT(newOffset > offset); + offset = newOffset; + + } while (offset < text.size()); + + if (beginOffset < offset) + applyFormat(beginOffset, text.size() - beginOffset, *currentFormat); + + while (!stateData->topContext()->lineEndContext().isStay() && !lineContinuation) { + if (!d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList())) + break; + } + + return newState; +} + +bool AbstractHighlighterPrivate::switchContext(StateData *data, const ContextSwitch &contextSwitch, const QStringList &captures) +{ + // kill as many items as requested from the stack, will always keep the initial context alive! + const bool initialContextSurvived = data->pop(contextSwitch.popCount()); + + // if we have a new context to add, push it + // then we always "succeed" + if (contextSwitch.context()) { + data->push(contextSwitch.context(), captures); + return true; + } + + // else we abort, if we did try to pop the initial context + return initialContextSurvived; +} + +void AbstractHighlighter::applyFolding(int offset, int length, FoldingRegion region) +{ + Q_UNUSED(offset); + Q_UNUSED(length); + Q_UNUSED(region); +} diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.h b/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.h new file mode 100644 index 0000000000..2b88729697 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.h @@ -0,0 +1,195 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_ABSTRACTHIGHLIGHTERM_H +#define KSYNTAXHIGHLIGHTING_ABSTRACTHIGHLIGHTERM_H + +#include "ksyntaxhighlighting_export.h" + +#include <QObject> + +#include <memory> + +QT_BEGIN_NAMESPACE +class QString; +QT_END_NAMESPACE + +namespace KSyntaxHighlighting { + +class AbstractHighlighterPrivate; +class Definition; +class FoldingRegion; +class Format; +class State; +class Theme; + +/** + * Abstract base class for highlighters. + * + * @section abshl_intro Introduction + * + * The AbstractHighlighter provides an interface to highlight text. + * + * The SyntaxHighlighting framework already ships with one implementation, + * namely the SyntaxHighlighter, which also derives from QSyntaxHighlighter, + * meaning that it can be used to highlight a QTextDocument or a QML TextEdit. + * In order to use the SyntaxHighlighter, just call setDefinition() and + * setTheme(), and the associated documents will automatically be highlighted. + * + * However, if you want to use the SyntaxHighlighting framework to implement + * your own syntax highlighter, you need to sublcass from AbstractHighlighter. + * + * @section abshl_impl Implementing your own Syntax Highlighter + * + * In order to implement your own syntax highlighter, you need to inherit from + * AbstractHighlighter. Then, pass each text line that needs to be highlighted + * in order to highlightLine(). Internally, highlightLine() uses the Definition + * initially set through setDefinition() and the State of the previous text line + * to parse and highlight the given text line. For each visual highlighting + * change, highlightLine() will call applyFormat(). Therefore, reimplement + * applyFormat() to get notified of the Format that is valid in the range + * starting at the given offset with the specified length. Similarly, for each + * text part that starts or ends a code folding region, highlightLine() will + * call applyFolding(). Therefore, if you are interested in code folding, + * reimplement applyFolding() to get notified of the starting and ending code + * folding regions, again specified in the range starting at the given offset + * with the given length. + * + * The Format class itself depends on the current Theme. A theme must be + * initially set once such that the Format%s instances can be queried for + * concrete colors. + * + * Optionally, you can also reimplement setTheme() and setDefinition() to get + * notified whenever the Definition or the Theme changes. + * + * @see SyntaxHighlighter + * @since 5.28 + */ +class KSYNTAXHIGHLIGHTING_EXPORT AbstractHighlighter +{ +public: + virtual ~AbstractHighlighter(); + + /** + * Returns the syntax definition used for highlighting. + * + * @see setDefinition() + */ + Definition definition() const; + + /** + * Sets the syntax definition used for highlighting. + * + * Subclasses can re-implement this method to e.g. trigger + * re-highlighting or clear internal data structures if needed. + */ + virtual void setDefinition(const Definition &def); + + /** + * Returns the currently selected theme for highlighting. + * + * @note If no Theme was set through setTheme(), the returned Theme will be + * invalid, see Theme::isValid(). + */ + Theme theme() const; + + /** + * Sets the theme used for highlighting. + * + * Subclasses can re-implement this method to e.g. trigger + * re-highlighing or to do general palette color setup. + */ + virtual void setTheme(const Theme &theme); + +protected: + AbstractHighlighter(); + AbstractHighlighter(AbstractHighlighterPrivate *dd); + + // TODO KF6: add an optional void* context argument that is passed through + // to the applyX() calls, so highlighters dealing with some form of line object + // (such as QSyntaxHighlighter or KTextEditor) can avoid some ugly hacks to have + // this context available in their applyX methods + /** + * Highlight the given line. Call this from your derived class + * where appropriate. This will result in any number of applyFormat() + * and applyFolding() calls as a result. + * @param text A string containing the text of the line to highlight. + * @param state The highlighting state handle returned by the call + * to highlightLine() for the previous line. For the very first line, + * just pass a default constructed State(). + * @returns The state of the highlighing engine after processing the + * given line. This needs to passed into highlightLine() for the + * next line. You can store the state for efficient partial + * re-highlighting for example during editing. + * + * @see applyFormat(), applyFolding() + */ + State highlightLine(const QString &text, const State &state); + + /** + * Reimplement this to apply formats to your output. The provided @p format + * is valid for the interval [@p offset, @p offset + @p length). + * + * @param offset The start column of the interval for which @p format matches + * @param length The length of the matching text + * @param format The Format that applies to the range [offset, offset + length) + * + * @note Make sure to set a valid Definition, otherwise the parameter + * @p format is invalid for the entire line passed to highlightLine() + * (cf. Format::isValid()). + * + * @see applyFolding(), highlightLine() + */ + virtual void applyFormat(int offset, int length, const Format &format) = 0; + + /** + * Reimplement this to apply folding to your output. The provided + * FoldingRegion @p region either stars or ends a code folding region in the + * interval [@p offset, @p offset + @p length). + * + * @param offset The start column of the FoldingRegion + * @param length The length of the matching text that starts / ends a + * folding region + * @param region The FoldingRegion that applies to the range [offset, offset + length) + * + * @note The FoldingRegion @p region is @e always either of type + * FoldingRegion::Type::Begin or FoldingRegion::Type::End. + * + * @see applyFormat(), highlightLine(), FoldingRegion + */ + virtual void applyFolding(int offset, int length, FoldingRegion region); + +protected: + AbstractHighlighterPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(AbstractHighlighter) + Q_DISABLE_COPY(AbstractHighlighter) +}; +} + +QT_BEGIN_NAMESPACE +Q_DECLARE_INTERFACE(KSyntaxHighlighting::AbstractHighlighter, "org.kde.SyntaxHighlighting.AbstractHighlighter") +QT_END_NAMESPACE + +#endif // KSYNTAXHIGHLIGHTING_ABSTRACTHIGHLIGHTERM_H diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter_p.h new file mode 100644 index 0000000000..bdfdf23bc1 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter_p.h @@ -0,0 +1,54 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_ABSTRACTHIGHLIGHTER_P_H +#define KSYNTAXHIGHLIGHTING_ABSTRACTHIGHLIGHTER_P_H + +#include "definition.h" +#include "theme.h" + +QT_BEGIN_NAMESPACE +class QStringList; +QT_END_NAMESPACE + +namespace KSyntaxHighlighting { + +class ContextSwitch; +class StateData; + +class AbstractHighlighterPrivate +{ +public: + AbstractHighlighterPrivate(); + virtual ~AbstractHighlighterPrivate(); + + void ensureDefinitionLoaded(); + bool switchContext(StateData* data, const ContextSwitch &contextSwitch, const QStringList &captures); + + Definition m_definition; + Theme m_theme; +}; + +} + +#endif diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/context.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/context.cpp new file mode 100644 index 0000000000..9887b959d0 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/context.cpp @@ -0,0 +1,206 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "context_p.h" +#include "definition_p.h" +#include "format.h" +#include "repository.h" +#include "rule_p.h" +#include "ksyntaxhighlighting_logging.h" +#include "xml_p.h" + +#include <QString> +#include <QXmlStreamReader> + +using namespace KSyntaxHighlighting; + +Definition Context::definition() const +{ + return m_def.definition(); +} + +void Context::setDefinition(const DefinitionRef &def) +{ + m_def = def; +} + +bool Context::indentationBasedFoldingEnabled() const +{ + if (m_noIndentationBasedFolding) + return false; + + return m_def.definition().indentationBasedFoldingEnabled(); +} + +void Context::load(QXmlStreamReader& reader) +{ + Q_ASSERT(reader.name() == QLatin1String("context")); + Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement); + + m_name = reader.attributes().value(QStringLiteral("name")).toString(); + m_attribute = reader.attributes().value(QStringLiteral("attribute")).toString(); + m_lineEndContext.parse(reader.attributes().value(QStringLiteral("lineEndContext"))); + m_lineEmptyContext.parse(reader.attributes().value(QStringLiteral("lineEmptyContext"))); + m_fallthrough = Xml::attrToBool(reader.attributes().value(QStringLiteral("fallthrough"))); + m_fallthroughContext.parse(reader.attributes().value(QStringLiteral("fallthroughContext"))); + if (m_fallthroughContext.isStay()) + m_fallthrough = false; + m_noIndentationBasedFolding = Xml::attrToBool(reader.attributes().value(QStringLiteral("noIndentationBasedFolding"))); + + reader.readNext(); + while (!reader.atEnd()) { + switch (reader.tokenType()) { + case QXmlStreamReader::StartElement: + { + auto rule = Rule::create(reader.name()); + if (rule) { + rule->setDefinition(m_def.definition()); + if (rule->load(reader)) + m_rules.push_back(rule); + } else { + reader.skipCurrentElement(); + } + reader.readNext(); + break; + } + case QXmlStreamReader::EndElement: + return; + default: + reader.readNext(); + break; + } + } +} + +void Context::resolveContexts() +{ + const auto def = m_def.definition(); + m_lineEndContext.resolve(def); + m_lineEmptyContext.resolve(def); + m_fallthroughContext.resolve(def); + for (const auto &rule : m_rules) + rule->resolveContext(); +} + +Context::ResolveState Context::resolveState() +{ + if (m_resolveState == Unknown) { + for (const auto &rule : m_rules) { + auto inc = std::dynamic_pointer_cast<IncludeRules>(rule); + if (inc) { + m_resolveState = Unresolved; + return m_resolveState; + } + } + m_resolveState = Resolved; + } + return m_resolveState; +} + +void Context::resolveIncludes() +{ + if (resolveState() == Resolved) + return; + if (resolveState() == Resolving) { + qCWarning(Log) << "Cyclic dependency!"; + return; + } + + Q_ASSERT(resolveState() == Unresolved); + m_resolveState = Resolving; // cycle guard + + for (auto it = m_rules.begin(); it != m_rules.end();) { + auto inc = std::dynamic_pointer_cast<IncludeRules>(*it); + if (!inc) { + ++it; + continue; + } + Context* context = nullptr; + auto myDefData = DefinitionData::get(m_def.definition()); + if (inc->definitionName().isEmpty()) { // local include + context = myDefData->contextByName(inc->contextName()); + } else { + auto def = myDefData->repo->definitionForName(inc->definitionName()); + if (!def.isValid()) { + qCWarning(Log) << "Unable to resolve external include rule for definition" << inc->definitionName() << "in" << m_def.definition().name(); + ++it; + continue; + } + auto defData = DefinitionData::get(def); + defData->load(); + if (inc->contextName().isEmpty()) + context = defData->initialContext(); + else + context = defData->contextByName(inc->contextName()); + } + if (!context) { + qCWarning(Log) << "Unable to resolve include rule for definition" << inc->contextName() << "##" << inc->definitionName() << "in" << m_def.definition().name(); + ++it; + continue; + } + context->resolveIncludes(); + + /** + * handle included attribute + * transitive closure: we might include attributes included from somewhere else + */ + if (inc->includeAttribute()) { + m_attribute = context->m_attribute; + m_attributeContext = context->m_attributeContext ? context->m_attributeContext : context; + } + + it = m_rules.erase(it); + for (const auto &rule : context->rules()) { + it = m_rules.insert(it, rule); + ++it; + } + } + + m_resolveState = Resolved; +} + +void Context::resolveAttributeFormat() +{ + /** + * try to get our format from the definition we stem from + * we need to handle included attributes via m_attributeContext + */ + if (!m_attribute.isEmpty()) { + const auto def = m_attributeContext ? m_attributeContext->m_def.definition() : m_def.definition(); + m_attributeFormat = DefinitionData::get(def)->formatByName(m_attribute); + if (!m_attributeFormat.isValid()) { + if (m_attributeContext) { + qCWarning(Log) << "Context: Unknown format" << m_attribute << "in context" << m_name << "of definition" << m_def.definition().name() << "from included context" << m_attributeContext->m_name << "of definition" << def.name(); + } else { + qCWarning(Log) << "Context: Unknown format" << m_attribute << "in context" << m_name << "of definition" << m_def.definition().name(); + } + } + } + + /** + * lookup formats for our rules + */ + for (const auto &rule : m_rules) { + rule->resolveAttributeFormat(this); + } +} diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/context_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/context_p.h new file mode 100644 index 0000000000..a034d0e27d --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/context_p.h @@ -0,0 +1,139 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_CONTEXT_P_H +#define KSYNTAXHIGHLIGHTING_CONTEXT_P_H + +#include "rule_p.h" +#include "contextswitch_p.h" +#include "definition.h" +#include "definitionref_p.h" +#include "format.h" + +#include <QString> + +#include <vector> + +QT_BEGIN_NAMESPACE +class QXmlStreamReader; +QT_END_NAMESPACE + +namespace KSyntaxHighlighting { + +class Context +{ +public: + Context() = default; + ~Context() = default; + + Definition definition() const; + void setDefinition(const DefinitionRef &def); + + const QString &name() const + { + return m_name; + } + + const ContextSwitch &lineEndContext() const + { + return m_lineEndContext; + } + + const ContextSwitch &lineEmptyContext() const + { + return m_lineEmptyContext; + } + + bool fallthrough() const + { + return m_fallthrough; + } + + const ContextSwitch &fallthroughContext() const + { + return m_fallthroughContext; + } + + const Format &attributeFormat() const + { + return m_attributeFormat; + } + + const std::vector<Rule::Ptr> &rules() const + { + return m_rules; + } + + /** + * Returns @c true, when indentationBasedFolding is enabled for the + * associated Definition and when "noIndentationBasedFolding" is NOT set. + */ + bool indentationBasedFoldingEnabled() const; + + void load(QXmlStreamReader &reader); + void resolveContexts(); + void resolveIncludes(); + void resolveAttributeFormat(); + +private: + Q_DISABLE_COPY(Context) + + enum ResolveState { + Unknown, + Unresolved, + Resolving, + Resolved + }; + ResolveState resolveState(); + + DefinitionRef m_def; + QString m_name; + + /** + * attribute name, to lookup our format + */ + QString m_attribute; + + /** + * context to use for lookup, if != this context + */ + const Context *m_attributeContext = nullptr; + + /** + * resolved format for our attribute, done in resolveAttributeFormat + */ + Format m_attributeFormat; + + ContextSwitch m_lineEndContext; + ContextSwitch m_lineEmptyContext; + ContextSwitch m_fallthroughContext; + + std::vector<Rule::Ptr> m_rules; + + ResolveState m_resolveState = Unknown; + bool m_fallthrough = false; + bool m_noIndentationBasedFolding = false; +}; +} + +#endif // KSYNTAXHIGHLIGHTING_CONTEXT_P_H diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/contextswitch.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/contextswitch.cpp new file mode 100644 index 0000000000..a4d1dbbd85 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/contextswitch.cpp @@ -0,0 +1,90 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "contextswitch_p.h" +#include "definition.h" +#include "definition_p.h" +#include "repository.h" +#include "ksyntaxhighlighting_logging.h" + + +using namespace KSyntaxHighlighting; + +bool ContextSwitch::isStay() const +{ + return m_popCount == 0 && !m_context && m_contextName.isEmpty() && m_defName.isEmpty(); +} + +int ContextSwitch::popCount() const +{ + return m_popCount; +} + +Context* ContextSwitch::context() const +{ + return m_context; +} + +void ContextSwitch::parse(const QStringRef& contextInstr) +{ + if (contextInstr.isEmpty() || contextInstr == QLatin1String("#stay")) + return; + + if (contextInstr.startsWith(QLatin1String("#pop!"))) { + ++m_popCount; + m_contextName = contextInstr.mid(5).toString(); + return; + } + + if (contextInstr.startsWith(QLatin1String("#pop"))) { + ++m_popCount; + parse(contextInstr.mid(4)); + return; + } + + const auto idx = contextInstr.indexOf(QLatin1String("##")); + if (idx >= 0) { + m_contextName = contextInstr.left(idx).toString(); + m_defName = contextInstr.mid(idx + 2).toString(); + } else { + m_contextName = contextInstr.toString(); + } +} + +void ContextSwitch::resolve(const Definition &def) +{ + auto d = def; + if (!m_defName.isEmpty()) { + d = DefinitionData::get(def)->repo->definitionForName(m_defName); + auto data = DefinitionData::get(d); + data->load(); + if (m_contextName.isEmpty()) + m_context = data->initialContext(); + } + + if (!m_contextName.isEmpty()) { + m_context = DefinitionData::get(d)->contextByName(m_contextName); + if (!m_context) + qCWarning(Log) << "cannot find context" << m_contextName << "in" << def.name(); + } +} diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/contextswitch_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/contextswitch_p.h new file mode 100644 index 0000000000..669855af7a --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/contextswitch_p.h @@ -0,0 +1,56 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_CONTEXTSWITCH_P_H +#define KSYNTAXHIGHLIGHTING_CONTEXTSWITCH_P_H + +#include <QString> + +namespace KSyntaxHighlighting { + +class Context; +class Definition; + +class ContextSwitch +{ +public: + ContextSwitch() = default; + ~ContextSwitch() = default; + + bool isStay() const; + + int popCount() const; + Context* context() const; + + void parse(const QStringRef &contextInstr); + void resolve(const Definition &def); + +private: + QString m_defName; + QString m_contextName; + Context *m_context = nullptr; + int m_popCount = 0; +}; +} + +#endif // KSYNTAXHIGHLIGHTING_CONTEXTSWITCH_P_H diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp new file mode 100644 index 0000000000..c03d23dc48 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp @@ -0,0 +1,798 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + Copyright (C) 2018 Dominik Haumann <dhaumann@kde.org> + Copyright (C) 2018 Christoph Cullmann <cullmann@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + + +#include "definition.h" +#include "definition_p.h" +#include "definitionref_p.h" + +#include "context_p.h" +#include "format.h" +#include "format_p.h" +#include "repository_p.h" +#include "rule_p.h" +#include "ksyntaxhighlighting_logging.h" +#include "ksyntaxhighlighting_version.h" +#include "xml_p.h" + +#include <QCoreApplication> +#include <QDebug> +#include <QFile> +#include <QHash> +#include <QJsonObject> +#include <QStringList> +#include <QVector> +#include <QXmlStreamReader> + +#include <algorithm> + +using namespace KSyntaxHighlighting; + +DefinitionData::DefinitionData() + : wordDelimiters(QStringLiteral("\t !%&()*+,-./:;<=>?[\\]^{|}~")) // must be sorted! + , wordWrapDelimiters(wordDelimiters) +{ +} + +DefinitionData::~DefinitionData() +{ + qDeleteAll(contexts); +} + +DefinitionData* DefinitionData::get(const Definition &def) +{ + return def.d.get(); +} + +Definition::Definition() : + d(new DefinitionData) +{ +} + +Definition::Definition(const Definition &other) : + d(other.d) +{ + d->q = *this; +} + +Definition::Definition(const std::shared_ptr<DefinitionData> &dd) : + d(dd) +{ +} + +Definition::~Definition() +{ +} + +Definition& Definition::operator=(const Definition &rhs) +{ + d = rhs.d; + return *this; +} + +bool Definition::operator==(const Definition &other) const +{ + return d->fileName == other.d->fileName; +} + +bool Definition::operator!=(const Definition& other) const +{ + return d->fileName != other.d->fileName; +} + +bool Definition::isValid() const +{ + return d->repo && !d->fileName.isEmpty() && !d->name.isEmpty(); +} + +QString Definition::filePath() const +{ + return d->fileName; +} + +QString Definition::name() const +{ + return d->name; +} + +QString Definition::translatedName() const +{ + return QCoreApplication::instance()->translate("Language", d->name.toUtf8().constData()); +} + +QString Definition::section() const +{ + return d->section; +} + +QString Definition::translatedSection() const +{ + return QCoreApplication::instance()->translate("Language Section", d->section.toUtf8().constData()); +} + +QVector<QString> Definition::mimeTypes() const +{ + return d->mimetypes; +} + +QVector<QString> Definition::extensions() const +{ + return d->extensions; +} + +int Definition::version() const +{ + return d->version; +} + +int Definition::priority() const +{ + return d->priority; +} + +bool Definition::isHidden() const +{ + return d->hidden; +} + +QString Definition::style() const +{ + return d->style; +} + +QString Definition::indenter() const +{ + return d->indenter; +} + +QString Definition::author() const +{ + return d->author; +} + +QString Definition::license() const +{ + return d->license; +} + +bool Definition::isWordDelimiter(QChar c) const +{ + d->load(); + return d->isWordDelimiter(c); +} + +bool Definition::isWordWrapDelimiter(QChar c) const +{ + d->load(); + return std::binary_search(d->wordWrapDelimiters.constBegin(), d->wordWrapDelimiters.constEnd(), c); +} + +bool Definition::foldingEnabled() const +{ + d->load(); + if (d->hasFoldingRegions || indentationBasedFoldingEnabled()) { + return true; + } + + // check included definitions + const auto defs = includedDefinitions(); + for (const auto &def : defs) { + if (def.foldingEnabled()) { + d->hasFoldingRegions = true; + break; + } + } + + return d->hasFoldingRegions; +} + +bool Definition::indentationBasedFoldingEnabled() const +{ + d->load(); + return d->indentationBasedFolding; +} + +QStringList Definition::foldingIgnoreList() const +{ + d->load(); + return d->foldingIgnoreList; +} + +QStringList Definition::keywordLists() const +{ + d->load(); + return d->keywordLists.keys(); +} + +QStringList Definition::keywordList(const QString& name) const +{ + d->load(); + const auto list = d->keywordList(name); + return list ? list->keywords() : QStringList(); +} + +QVector<Format> Definition::formats() const +{ + d->load(); + + // sort formats so that the order matches the order of the itemDatas in the xml files. + auto formatList = QVector<Format>::fromList(d->formats.values()); + std::sort(formatList.begin(), formatList.end(), [](const KSyntaxHighlighting::Format & lhs, const KSyntaxHighlighting::Format & rhs){ + return lhs.id() < rhs.id(); + }); + + return formatList; +} + +QVector<Definition> Definition::includedDefinitions() const +{ + d->load(); + + // init worklist and result used as guard with this definition + QVector<Definition> queue{*this}; + QVector<Definition> definitions{*this}; + while (!queue.isEmpty()) { + // Iterate all context rules to find associated Definitions. This will + // automatically catch other Definitions referenced with IncludeRuldes or ContextSwitch. + const auto definition = queue.takeLast(); + for (const auto & context : qAsConst(definition.d->contexts)) { + // handle context switch attributes of this context itself + for (const auto switchContext : {context->lineEndContext().context(), context->lineEmptyContext().context(), context->fallthroughContext().context()}) { + if (switchContext) { + if (!definitions.contains(switchContext->definition())) { + queue.push_back(switchContext->definition()); + definitions.push_back(switchContext->definition()); + } + } + } + + // handle the embedded rules + for (const auto &rule : context->rules()) { + // handle include rules like inclusion + if (!definitions.contains(rule->definition())) { + queue.push_back(rule->definition()); + definitions.push_back(rule->definition()); + } + + // handle context switch context inclusion + if (auto switchContext = rule->context().context()) { + if (!definitions.contains(switchContext->definition())) { + queue.push_back(switchContext->definition()); + definitions.push_back(switchContext->definition()); + } + } + } + } + } + + // remove the 1st entry, since it is this Definition + definitions.pop_front(); + + return definitions; +} + +QString Definition::singleLineCommentMarker() const +{ + d->load(); + return d->singleLineCommentMarker; +} + +CommentPosition Definition::singleLineCommentPosition() const +{ + d->load(); + return d->singleLineCommentPosition; +} + +QPair<QString, QString> Definition::multiLineCommentMarker() const +{ + d->load(); + return { d->multiLineCommentStartMarker, d->multiLineCommentEndMarker }; +} + +QVector<QPair<QChar, QString>> Definition::characterEncodings() const +{ + d->load(); + return d->characterEncodings; +} + +Context* DefinitionData::initialContext() const +{ + Q_ASSERT(!contexts.isEmpty()); + return contexts.first(); +} + +Context* DefinitionData::contextByName(const QString& name) const +{ + foreach (auto context, contexts) { + if (context->name() == name) + return context; + } + return nullptr; +} + +KeywordList *DefinitionData::keywordList(const QString& name) +{ + auto it = keywordLists.find(name); + return (it == keywordLists.end()) ? nullptr : &it.value(); +} + +bool DefinitionData::isWordDelimiter(QChar c) const +{ + return std::binary_search(wordDelimiters.constBegin(), wordDelimiters.constEnd(), c); +} + +Format DefinitionData::formatByName(const QString& name) const +{ + const auto it = formats.constFind(name); + if (it != formats.constEnd()) + return it.value(); + + return Format(); +} + +bool DefinitionData::isLoaded() const +{ + return !contexts.isEmpty(); +} + +bool DefinitionData::load() +{ + if (fileName.isEmpty()) + return false; + + if (isLoaded()) + return true; + + QFile file(fileName); + if (!file.open(QFile::ReadOnly)) + return false; + + QXmlStreamReader reader(&file); + while (!reader.atEnd()) { + const auto token = reader.readNext(); + if (token != QXmlStreamReader::StartElement) + continue; + + if (reader.name() == QLatin1String("highlighting")) + loadHighlighting(reader); + + else if (reader.name() == QLatin1String("general")) + loadGeneral(reader); + } + + for (auto it = keywordLists.begin(); it != keywordLists.end(); ++it) + (*it).setCaseSensitivity(caseSensitive); + + foreach (auto context, contexts) { + context->resolveContexts(); + context->resolveIncludes(); + context->resolveAttributeFormat(); + } + + Q_ASSERT(std::is_sorted(wordDelimiters.constBegin(), wordDelimiters.constEnd())); + return true; +} + +void DefinitionData::clear() +{ + // keep only name and repo, so we can re-lookup to make references persist over repo reloads + keywordLists.clear(); + qDeleteAll(contexts); + contexts.clear(); + formats.clear(); + + fileName.clear(); + section.clear(); + style.clear(); + indenter.clear(); + author.clear(); + license.clear(); + mimetypes.clear(); + extensions.clear(); + wordDelimiters = QStringLiteral("\t !%&()*+,-./:;<=>?[\\]^{|}~"); // must be sorted! + wordWrapDelimiters = wordDelimiters; + caseSensitive = Qt::CaseSensitive; + version = 0.0f; + priority = 0; + hidden = false; +} + +bool DefinitionData::loadMetaData(const QString& definitionFileName) +{ + fileName = definitionFileName; + + QFile file(definitionFileName); + if (!file.open(QFile::ReadOnly)) + return false; + + QXmlStreamReader reader(&file); + while (!reader.atEnd()) { + const auto token = reader.readNext(); + if (token != QXmlStreamReader::StartElement) + continue; + if (reader.name() == QLatin1String("language")) { + return loadLanguage(reader); + } + } + + return false; +} + +bool DefinitionData::loadMetaData(const QString &file, const QJsonObject &obj) +{ + name = obj.value(QLatin1String("name")).toString(); + section = obj.value(QLatin1String("section")).toString(); + version = obj.value(QLatin1String("version")).toInt(); + priority = obj.value(QLatin1String("priority")).toInt(); + style = obj.value(QLatin1String("style")).toString(); + author = obj.value(QLatin1String("author")).toString(); + license = obj.value(QLatin1String("license")).toString(); + indenter = obj.value(QLatin1String("indenter")).toString(); + hidden = obj.value(QLatin1String("hidden")).toBool(); + fileName = file; + + const auto exts = obj.value(QLatin1String("extensions")).toString(); + foreach (const auto &ext, exts.split(QLatin1Char(';'), QString::SkipEmptyParts)) + extensions.push_back(ext); + const auto mts = obj.value(QLatin1String("mimetype")).toString(); + foreach (const auto &mt, mts.split(QLatin1Char(';'), QString::SkipEmptyParts)) + mimetypes.push_back(mt); + + return true; +} + +bool DefinitionData::loadLanguage(QXmlStreamReader &reader) +{ + Q_ASSERT(reader.name() == QLatin1String("language")); + Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement); + + if (!checkKateVersion(reader.attributes().value(QStringLiteral("kateversion")))) + return false; + + name = reader.attributes().value(QStringLiteral("name")).toString(); + section = reader.attributes().value(QStringLiteral("section")).toString(); + // toFloat instead of toInt for backward compatibility with old Kate files + version = reader.attributes().value(QStringLiteral("version")).toFloat(); + priority = reader.attributes().value(QStringLiteral("priority")).toInt(); + hidden = Xml::attrToBool(reader.attributes().value(QStringLiteral("hidden"))); + style = reader.attributes().value(QStringLiteral("style")).toString(); + indenter = reader.attributes().value(QStringLiteral("indenter")).toString(); + author = reader.attributes().value(QStringLiteral("author")).toString(); + license = reader.attributes().value(QStringLiteral("license")).toString(); + const auto exts = reader.attributes().value(QStringLiteral("extensions")).toString(); + foreach (const auto &ext, exts.split(QLatin1Char(';'), QString::SkipEmptyParts)) + extensions.push_back(ext); + const auto mts = reader.attributes().value(QStringLiteral("mimetype")).toString(); + foreach (const auto &mt, mts.split(QLatin1Char(';'), QString::SkipEmptyParts)) + mimetypes.push_back(mt); + if (reader.attributes().hasAttribute(QStringLiteral("casesensitive"))) + caseSensitive = Xml::attrToBool(reader.attributes().value(QStringLiteral("casesensitive"))) ? Qt::CaseSensitive : Qt::CaseInsensitive; + return true; +} + +void DefinitionData::loadHighlighting(QXmlStreamReader& reader) +{ + Q_ASSERT(reader.name() == QLatin1String("highlighting")); + Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement); + + while (!reader.atEnd()) { + switch (reader.tokenType()) { + case QXmlStreamReader::StartElement: + if (reader.name() == QLatin1String("list")) { + KeywordList keywords; + keywords.load(reader); + keywordLists.insert(keywords.name(), keywords); + } else if (reader.name() == QLatin1String("contexts")) { + loadContexts(reader); + reader.readNext(); + } else if (reader.name() == QLatin1String("itemDatas")) { + loadItemData(reader); + } else { + reader.readNext(); + } + break; + case QXmlStreamReader::EndElement: + return; + default: + reader.readNext(); + break; + } + } +} + +void DefinitionData::loadContexts(QXmlStreamReader& reader) +{ + Q_ASSERT(reader.name() == QLatin1String("contexts")); + Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement); + + while (!reader.atEnd()) { + switch (reader.tokenType()) { + case QXmlStreamReader::StartElement: + if (reader.name() == QLatin1String("context")) { + auto context = new Context; + context->setDefinition(q); + context->load(reader); + contexts.push_back(context); + } + reader.readNext(); + break; + case QXmlStreamReader::EndElement: + return; + default: + reader.readNext(); + break; + } + } +} + +void DefinitionData::loadItemData(QXmlStreamReader& reader) +{ + Q_ASSERT(reader.name() == QLatin1String("itemDatas")); + Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement); + + while (!reader.atEnd()) { + switch (reader.tokenType()) { + case QXmlStreamReader::StartElement: + if (reader.name() == QLatin1String("itemData")) { + Format f; + auto formatData = FormatPrivate::detachAndGet(f); + formatData->definition = q; + formatData->load(reader); + formatData->id = RepositoryPrivate::get(repo)->nextFormatId(); + formats.insert(f.name(), f); + reader.readNext(); + } + reader.readNext(); + break; + case QXmlStreamReader::EndElement: + return; + default: + reader.readNext(); + break; + } + } +} + +void DefinitionData::loadGeneral(QXmlStreamReader& reader) +{ + Q_ASSERT(reader.name() == QLatin1String("general")); + Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement); + reader.readNext(); + + // reference counter to count XML child elements, to not return too early + int elementRefCounter = 1; + + while (!reader.atEnd()) { + switch (reader.tokenType()) { + case QXmlStreamReader::StartElement: + ++elementRefCounter; + + if (reader.name() == QLatin1String("keywords")) { + if (reader.attributes().hasAttribute(QStringLiteral("casesensitive"))) + caseSensitive = Xml::attrToBool(reader.attributes().value(QStringLiteral("casesensitive"))) ? Qt::CaseSensitive : Qt::CaseInsensitive; + + // adapt sorted wordDelimiters + wordDelimiters += reader.attributes().value(QStringLiteral("additionalDeliminator")); + std::sort(wordDelimiters.begin(), wordDelimiters.end()); + auto it = std::unique(wordDelimiters.begin(), wordDelimiters.end()); + wordDelimiters.truncate(std::distance(wordDelimiters.begin(), it)); + foreach (const auto c, reader.attributes().value(QLatin1String("weakDeliminator"))) + wordDelimiters.remove(c); + + // adaptWordWrapDelimiters, and sort + wordWrapDelimiters = reader.attributes().value(QStringLiteral("wordWrapDeliminator")).toString(); + std::sort(wordWrapDelimiters.begin(), wordWrapDelimiters.end()); + if (wordWrapDelimiters.isEmpty()) + wordWrapDelimiters = wordDelimiters; + } else if (reader.name() == QLatin1String("folding")) { + if (reader.attributes().hasAttribute(QStringLiteral("indentationsensitive"))) + indentationBasedFolding = Xml::attrToBool(reader.attributes().value(QStringLiteral("indentationsensitive"))); + } else if (reader.name() == QLatin1String("emptyLines")) { + loadFoldingIgnoreList(reader); + } else if (reader.name() == QLatin1String("comments")) { + loadComments(reader); + } else if (reader.name() == QLatin1String("spellchecking")) { + loadSpellchecking(reader); + } else { + reader.skipCurrentElement(); + } + reader.readNext(); + break; + case QXmlStreamReader::EndElement: + --elementRefCounter; + if (elementRefCounter == 0) + return; + reader.readNext(); + break; + default: + reader.readNext(); + break; + } + } +} + +void DefinitionData::loadComments(QXmlStreamReader &reader) +{ + Q_ASSERT(reader.name() == QLatin1String("comments")); + Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement); + reader.readNext(); + + // reference counter to count XML child elements, to not return too early + int elementRefCounter = 1; + + while (!reader.atEnd()) { + switch (reader.tokenType()) { + case QXmlStreamReader::StartElement: + ++elementRefCounter; + if (reader.name() == QLatin1String("comment")) { + const bool isSingleLine = reader.attributes().value(QStringLiteral("name")) == QStringLiteral("singleLine"); + if (isSingleLine) { + singleLineCommentMarker = reader.attributes().value(QStringLiteral("start")).toString(); + const bool afterWhiteSpace = reader.attributes().value(QStringLiteral("position")).toString() == QStringLiteral("afterwhitespace"); + singleLineCommentPosition = afterWhiteSpace ? CommentPosition::AfterWhitespace : CommentPosition::StartOfLine; + } else { + multiLineCommentStartMarker = reader.attributes().value(QStringLiteral("start")).toString(); + multiLineCommentEndMarker = reader.attributes().value(QStringLiteral("end")).toString(); + } + } + reader.readNext(); + break; + case QXmlStreamReader::EndElement: + --elementRefCounter; + if (elementRefCounter == 0) + return; + reader.readNext(); + break; + default: + reader.readNext(); + break; + } + } +} + +void DefinitionData::loadFoldingIgnoreList(QXmlStreamReader& reader) +{ + Q_ASSERT(reader.name() == QLatin1String("emptyLines")); + Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement); + reader.readNext(); + + // reference counter to count XML child elements, to not return too early + int elementRefCounter = 1; + + while (!reader.atEnd()) { + switch (reader.tokenType()) { + case QXmlStreamReader::StartElement: + ++elementRefCounter; + if (reader.name() == QLatin1String("emptyLine")) { + foldingIgnoreList << reader.attributes().value(QStringLiteral("regexpr")).toString(); + } + reader.readNext(); + break; + case QXmlStreamReader::EndElement: + --elementRefCounter; + if (elementRefCounter == 0) + return; + reader.readNext(); + break; + default: + reader.readNext(); + break; + } + } +} + +void DefinitionData::loadSpellchecking(QXmlStreamReader &reader) +{ + Q_ASSERT(reader.name() == QLatin1String("spellchecking")); + Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement); + reader.readNext(); + + // reference counter to count XML child elements, to not return too early + int elementRefCounter = 1; + + while (!reader.atEnd()) { + switch (reader.tokenType()) { + case QXmlStreamReader::StartElement: + ++elementRefCounter; + if (reader.name() == QLatin1String("encoding")) { + const auto charRef = reader.attributes().value(QStringLiteral("char")); + if (!charRef.isEmpty()) { + const auto str = reader.attributes().value(QStringLiteral("string")).toString(); + characterEncodings.push_back({ charRef[0], str }); + } + } + reader.readNext(); + break; + case QXmlStreamReader::EndElement: + --elementRefCounter; + if (elementRefCounter == 0) + return; + reader.readNext(); + break; + default: + reader.readNext(); + break; + } + } +} + +bool DefinitionData::checkKateVersion(const QStringRef& verStr) +{ + const auto idx = verStr.indexOf(QLatin1Char('.')); + if (idx <= 0) { + qCWarning(Log) << "Skipping" << fileName << "due to having no valid kateversion attribute:" << verStr; + return false; + } + const auto major = verStr.left(idx).toInt(); + const auto minor = verStr.mid(idx + 1).toInt(); + + if (major > SyntaxHighlighting_VERSION_MAJOR || (major == SyntaxHighlighting_VERSION_MAJOR && minor > SyntaxHighlighting_VERSION_MINOR)) { + qCWarning(Log) << "Skipping" << fileName << "due to being too new, version:" << verStr; + return false; + } + + return true; +} + +quint16 DefinitionData::foldingRegionId(const QString &foldName) +{ + hasFoldingRegions = true; + return RepositoryPrivate::get(repo)->foldingRegionId(name, foldName); +} + +DefinitionRef::DefinitionRef() +{ +} + +DefinitionRef::DefinitionRef(const Definition &def) : + d(def.d) +{ +} + +DefinitionRef::~DefinitionRef() +{ +} + +DefinitionRef& DefinitionRef::operator=(const Definition &def) +{ + d = def.d; + return *this; +} + +Definition DefinitionRef::definition() const +{ + if (!d.expired()) + return Definition(d.lock()); + return Definition(); +} + +bool DefinitionRef::operator==(const DefinitionRef &other) const +{ + if (d.expired() != other.d.expired()) { + return false; + } + + return d.expired() || d.lock().get() == other.d.lock().get(); +} diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/definition.h b/src/libs/3rdparty/syntax-highlighting/src/lib/definition.h new file mode 100644 index 0000000000..6f0dba9a45 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/definition.h @@ -0,0 +1,400 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_DEFINITION_H +#define KSYNTAXHIGHLIGHTING_DEFINITION_H + +#include "ksyntaxhighlighting_export.h" + +#include <QTypeInfo> +#include <QPair> + +#include <memory> + +QT_BEGIN_NAMESPACE +class QChar; +class QString; +class QStringList; +template <typename T> class QVector; +QT_END_NAMESPACE + +namespace KSyntaxHighlighting { + +class Context; +class Format; +class KeywordList; + +class DefinitionData; + +/** + * Defines the insert position when commenting code. + * @since 5.50 + * @see Definition::singleLineCommentPosition() + */ +enum class CommentPosition +{ + //! The comment marker is inserted at the beginning of a line at column 0 + StartOfLine = 0, + //! The comment marker is inserted after leading whitespaces right befire + //! the first non-whitespace character. + AfterWhitespace +}; + +/** + * Represents a syntax definition. + * + * @section def_intro Introduction to Definitions + * + * A Definition is the short term for a syntax highlighting definition. It + * typically is defined in terms of an XML syntax highlighting file, containing + * all information about a particular syntax highlighting. This includes the + * highlighting of keywords, information about code folding regions, and + * indentation preferences. + * + * @section def_info General Header Data + * + * Each Definition contains a non-translated unique name() and a section(). + * In addition, for putting this information e.g. into menus, the functions + * translatedName() and translatedSection() are provided. However, if isHidden() + * returns @e true, the Definition should not be visible in the UI. The location + * of the Definition can be obtained through filePath(), which either is the + * location on disk or a path to a compiled-in Qt resource. + * + * The supported files of a Definition are defined by the list of extensions(), + * and additionally by the list of mimeTypes(). Note, that extensions() returns + * wildcards that need to be matched against the filename of the file that + * requires highlighting. If multiple Definition%s match the file, then the one + * with higher priority() wins. + * + * @section def_metadata Advanced Definition Data + * + * Advanced text editors such as Kate require additional information from a + * Definition. For instance, foldingEnabled() defines whether a Definition has + * code folding regions that can be shown in a code folding pane. Or + * singleLineCommentMarker() and multiLineCommentMarker() provide comment + * markers that can be used for commenting/uncommenting code. Similarly, + * formats() returns a list of Format items defined by this Definition (which + * equal the itemDatas of a highlighing definition file). includedDefinitions() + * returns a list of all included Definition%s referenced by this Definition via + * the rule IncludeRules, which is useful for displaying all Format items for + * color configuration in the user interface. + * + * @see Repository + * @since 5.28 + */ +class KSYNTAXHIGHLIGHTING_EXPORT Definition +{ +public: + /** + * Default constructor, creating an empty (invalid) Definition instance. + * isValid() for this instance returns @e false. + * + * Use the Repository instead to obtain valid instances. + */ + Definition(); + + /** + * Copy constructor. + * Both this definition as well as @p other share the Definition data. + */ + Definition(const Definition &other); + + /** + * Destructor. + */ + ~Definition(); + + /** + * Assignment operator. + * Both this definition as well as @p rhs share the Definition data. + */ + Definition& operator=(const Definition &rhs); + + /** + * Checks two definitions for equality. + */ + bool operator==(const Definition &other) const; + + /** + * Checks two definitions for inequality. + */ + bool operator!=(const Definition &other) const; + + /** + * @name General Header Data + * + * @{ + */ + + /** + * Checks whether this object refers to a valid syntax definition. + */ + bool isValid() const; + + /** + * Returns the full path to the definition XML file containing + * the syntax definition. Note that this can be a path to QRC content. + */ + QString filePath() const; + + /** Name of the syntax. + * Used for internal references, prefer translatedName() for display. + */ + QString name() const; + + /** + * Translated name for display. + */ + QString translatedName() const; + + /** + * The group this syntax definition belongs to. + * For display, consider translatedSection(). + */ + QString section() const; + + /** + * Translated group name for display. + */ + QString translatedSection() const; + + /** + * Mime types associated with this syntax definition. + */ + QVector<QString> mimeTypes() const; + + /** + * File extensions associated with this syntax definition. + * The returned list contains wildcards. + */ + QVector<QString> extensions() const; + + /** + * Returns the definition version. + */ + int version() const; + + /** + * Returns the definition priority. + * A Definition with higher priority wins over Definitions with lower priorities. + */ + int priority() const; + + /** + * Returns @c true if this is an internal definition that should not be + * displayed to the user. + */ + bool isHidden() const; + + /** + * Generalized language style, used for indentation. + */ + QString style() const; + + /** + * Indentation style to be used for this syntax. + */ + QString indenter() const; + + /** + * Name and email of the author of this syntax definition. + */ + QString author() const; + + /** + * License of this syntax definition. + */ + QString license() const; + + /** + * @} + * + * @name Advanced Definition Data + */ + + /** + * Returns whether the character @p c is a word delimiter. + * A delimiter defines whether a characters is a word boundary. Internally, + * delimiters are used for matching keyword lists. As example, typically the + * dot '.' is a word delimiter. However, if you have a keyword in a keyword + * list that contains a dot, you have to add the dot to the + * @e weakDeliminator attribute of the @e general section in your + * highlighting definition. Similarly, sometimes additional delimiters are + * required, which can be specified in @e additionalDeliminator. + * + * Checking whether a character is a delimiter is useful for instance if + * text is selected with double click. Typically, the whole word should be + * selected in this case. Similarly to the example above, the dot '.' + * usually acts as word delimiter. However, using this function you can + * implement text selection in such a way that keyword lists are correctly + * selected. + * + * @note By default, the list of delimiters contains the following + * characters: \\t !%&()*+,-./:;<=>?[\\]^{|}~ + * + * @since 5.50 + * @see isWordWrapDelimiter() + */ + bool isWordDelimiter(QChar c) const; + + /** + * Returns whether it is safe to break a line at before the character @c. + * This is useful when wrapping a line e.g. by applying static word wrap. + * + * As example, consider the LaTeX code + * @code + * \command1\command2 + * @endcode + * Applying static word wrap could lead to the following code: + * @code + * \command1\ + * command2 + * @endcode + * command2 without a leading backslash is invalid in LaTeX. If '\\' is set + * as word wrap delimiter, isWordWrapDelimiter('\\') then returns true, + * meaning that it is safe to break the line before @c. The resulting code + * then would be + * @code + * \command1 + * \command2 + * @endcode + * + * @note By default, the word wrap delimiters are equal to the word + * delimiters in isWordDelimiter(). + * + * @since 5.50 + * @see isWordDelimiter() + */ + bool isWordWrapDelimiter(QChar c) const; + + /** + * Returns whether the highlighting supports code folding. + * Code folding is supported either if the highlighting defines code folding + * regions or if indentationBasedFoldingEnabled() returns @e true. + * @since 5.50 + * @see indentationBasedFoldingEnabled() + */ + bool foldingEnabled() const; + + /** + * Returns whether indentation-based folding is enabled. + * An example for indentation-based folding is Python. + * When indentation-based folding is enabled, make sure to also check + * foldingIgnoreList() for lines that should be treated as empty. + * + * @see foldingIgnoreList(), State::indentationBasedFoldingEnabled() + */ + bool indentationBasedFoldingEnabled() const; + + /** + * If indentationBasedFoldingEnabled() returns @c true, this function returns + * a list of regular expressions that represent empty lines. That is, all + * lines matching entirely one of the regular expressions should be treated + * as empty lines when calculating the indentation-based folding ranges. + * + * @note This list is only of relevance, if indentationBasedFoldingEnabled() + * returns @c true. + * + * @see indentationBasedFoldingEnabled() + */ + QStringList foldingIgnoreList() const; + + /** + * Returns the section names of keywords. + * @since 5.49 + * @see keywordList() + */ + QStringList keywordLists() const; + + /** + * Returns the list of keywords for the keyword list @p name. + * @since 5.49 + * @see keywordLists() + */ + QStringList keywordList(const QString& name) const; + + /** + * Returns a list of all Format items used by this definition. + * The order of the Format items equals the order of the itemDatas in the xml file. + * @since 5.49 + */ + QVector<Format> formats() const; + + /** + * Returns a list of Definitions that are referenced with the IncludeRules rule. + * The returned list does not include this Definition. In case no other + * Definitions are referenced via IncludeRules, the returned list is empty. + * + * @since 5.49 + */ + QVector<Definition> includedDefinitions() const; + + /** + * Returns the marker that starts a single line comment. + * For instance, in C++ the single line comment marker is "//". + * @since 5.50 + * @see singleLineCommentPosition(); + */ + QString singleLineCommentMarker() const; + + /** + * Returns the insert position of the comment marker for sinle line + * comments. + * @since 5.50 + * @see singleLineCommentMarker(); + */ + CommentPosition singleLineCommentPosition() const; + + /** + * Returns the markers that start and end multiline comments. + * For instance, in XML this is defined as "<!--" and "-->". + * @since 5.50 + */ + QPair<QString, QString> multiLineCommentMarker() const; + + /** + * Returns a list of character/string mapping that can be used for spell + * checking. This is useful for instance when spell checking LaTeX, where + * the string \"{A} represents the character Ä. + * @since 5.50 + */ + QVector<QPair<QChar, QString>> characterEncodings() const; + + /** + * @} + */ + +private: + friend class DefinitionData; + friend class DefinitionRef; + explicit Definition(const std::shared_ptr<DefinitionData> &dd); + std::shared_ptr<DefinitionData> d; +}; + +} + +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(KSyntaxHighlighting::Definition, Q_MOVABLE_TYPE); +QT_END_NAMESPACE + +#endif diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/definition_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/definition_p.h new file mode 100644 index 0000000000..ab95a9552c --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/definition_p.h @@ -0,0 +1,111 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_DEFINITION_P_H +#define KSYNTAXHIGHLIGHTING_DEFINITION_P_H + +#include "definitionref_p.h" +#include "definition.h" + +#include <QHash> +#include <QString> +#include <QVector> + +QT_BEGIN_NAMESPACE +class QXmlStreamReader; +class QJsonObject; +QT_END_NAMESPACE + +namespace KSyntaxHighlighting { + +class Repository; + +class DefinitionData +{ +public: + DefinitionData(); + ~DefinitionData(); + + static DefinitionData* get(const Definition &def); + + bool isLoaded() const; + bool loadMetaData(const QString &definitionFileName); + bool loadMetaData(const QString &fileName, const QJsonObject &obj); + + void clear(); + + bool load(); + bool loadLanguage(QXmlStreamReader &reader); + void loadHighlighting(QXmlStreamReader &reader); + void loadContexts(QXmlStreamReader &reader); + void loadItemData(QXmlStreamReader &reader); + void loadGeneral(QXmlStreamReader &reader); + void loadComments(QXmlStreamReader &reader); + void loadFoldingIgnoreList(QXmlStreamReader &reader); + void loadSpellchecking(QXmlStreamReader &reader); + bool checkKateVersion(const QStringRef &verStr); + + KeywordList *keywordList(const QString &name); + bool isWordDelimiter(QChar c) const; + + Context* initialContext() const; + Context* contextByName(const QString &name) const; + + Format formatByName(const QString &name) const; + + quint16 foldingRegionId(const QString &foldName); + + DefinitionRef q; + + Repository *repo = nullptr; + QHash<QString, KeywordList> keywordLists; + QVector<Context*> contexts; + QHash<QString, Format> formats; + QString wordDelimiters; + QString wordWrapDelimiters; + bool hasFoldingRegions = false; + bool indentationBasedFolding = false; + QStringList foldingIgnoreList; + QString singleLineCommentMarker; + CommentPosition singleLineCommentPosition = CommentPosition::StartOfLine; + QString multiLineCommentStartMarker; + QString multiLineCommentEndMarker; + QVector<QPair<QChar, QString>> characterEncodings; + + QString fileName; + QString name = QStringLiteral(QT_TRANSLATE_NOOP("Syntax highlighting", "None")); + QString section; + QString style; + QString indenter; + QString author; + QString license; + QVector<QString> mimetypes; + QVector<QString> extensions; + Qt::CaseSensitivity caseSensitive = Qt::CaseSensitive; + int version = 0; + int priority = 0; + bool hidden = false; +}; +} + +#endif diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/definitiondownloader.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/definitiondownloader.cpp new file mode 100644 index 0000000000..4c3e5f5f1e --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/definitiondownloader.cpp @@ -0,0 +1,193 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "definitiondownloader.h" +#include "definition.h" +#include "repository.h" +#include "ksyntaxhighlighting_logging.h" +#include "ksyntaxhighlighting_version.h" + +#include <QDebug> +#include <QDir> +#include <QFile> +#include <QNetworkAccessManager> +#include <QNetworkReply> +#include <QNetworkRequest> +#include <QStandardPaths> +#include <QTimer> +#include <QXmlStreamReader> + +using namespace KSyntaxHighlighting; + +class KSyntaxHighlighting::DefinitionDownloaderPrivate +{ +public: + DefinitionDownloader *q; + Repository *repo; + QNetworkAccessManager *nam; + QString downloadLocation; + int pendingDownloads; + bool needsReload; + + void definitionListDownloadFinished(QNetworkReply *reply); + void updateDefinition(QXmlStreamReader &parser); + void downloadDefinition(const QUrl &url); + void downloadDefinitionFinished(QNetworkReply *reply); + void checkDone(); +}; + +void DefinitionDownloaderPrivate::definitionListDownloadFinished(QNetworkReply *reply) +{ + if (reply->error() != QNetworkReply::NoError) { + qCWarning(Log) << reply->error(); + emit q->done(); // TODO return error + return; + } + + QXmlStreamReader parser(reply); + while (!parser.atEnd()) { + switch (parser.readNext()) { + case QXmlStreamReader::StartElement: + if (parser.name() == QLatin1String("Definition")) + updateDefinition(parser); + break; + default: + break; + } + } + + if (pendingDownloads == 0) + emit q->informationMessage(QObject::tr("All syntax definitions are up-to-date.")); + checkDone(); +} + +void DefinitionDownloaderPrivate::updateDefinition(QXmlStreamReader &parser) +{ + const auto name = parser.attributes().value(QLatin1String("name")); + if (name.isEmpty()) + return; + + auto localDef = repo->definitionForName(name.toString()); + if (!localDef.isValid()) { + emit q->informationMessage(QObject::tr("Downloading new syntax definition for '%1'...").arg(name.toString())); + downloadDefinition(QUrl(parser.attributes().value(QLatin1String("url")).toString())); + return; + } + + const auto version = parser.attributes().value(QLatin1String("version")); + if (localDef.version() < version.toFloat()) { + emit q->informationMessage(QObject::tr("Updating syntax definition for '%1' to version %2...").arg(name.toString(), version.toString())); + downloadDefinition(QUrl(parser.attributes().value(QLatin1String("url")).toString())); + } +} + +void DefinitionDownloaderPrivate::downloadDefinition(const QUrl& downloadUrl) +{ + if (!downloadUrl.isValid()) + return; + auto url = downloadUrl; + if (url.scheme() == QLatin1String("http")) + url.setScheme(QStringLiteral("https")); + + QNetworkRequest req(url); + auto reply = nam->get(req); + QObject::connect(reply, &QNetworkReply::finished, q, [this, reply]() { + downloadDefinitionFinished(reply); + }); + ++pendingDownloads; + needsReload = true; +} + +void DefinitionDownloaderPrivate::downloadDefinitionFinished(QNetworkReply *reply) +{ + --pendingDownloads; + if (reply->error() != QNetworkReply::NoError) { + qCWarning(Log) << "Failed to download definition file" << reply->url() << reply->error(); + checkDone(); + return; + } + + // handle redirects + // needs to be done manually, download server redirects to unsafe http links + const auto redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); + if (!redirectUrl.isEmpty()) { + downloadDefinition(reply->url().resolved(redirectUrl)); + checkDone(); + return; + } + + QFile file(downloadLocation + QLatin1Char('/') + reply->url().fileName()); + if (!file.open(QFile::WriteOnly)) { + qCWarning(Log) << "Failed to open" << file.fileName() << file.error(); + } else { + file.write(reply->readAll()); + } + checkDone(); +} + +void DefinitionDownloaderPrivate::checkDone() +{ + if (pendingDownloads == 0) { + if (needsReload) + repo->reload(); + + emit QTimer::singleShot(0, q, &DefinitionDownloader::done); + } +} + + +DefinitionDownloader::DefinitionDownloader(Repository *repo, QObject *parent) + : QObject(parent) + , d(new DefinitionDownloaderPrivate()) +{ + Q_ASSERT(repo); + + d->q = this; + d->repo = repo; + d->nam = new QNetworkAccessManager(this); + d->pendingDownloads = 0; + d->needsReload = false; + + d->downloadLocation = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/org.kde.syntax-highlighting/syntax"); + QDir().mkpath(d->downloadLocation); + Q_ASSERT(QFile::exists(d->downloadLocation)); +} + +DefinitionDownloader::~DefinitionDownloader() +{ +} + +void DefinitionDownloader::start() +{ + const QString url = QLatin1String("https://www.kate-editor.org/syntax/update-") + + QString::number(SyntaxHighlighting_VERSION_MAJOR) + + QLatin1Char('.') + + QString::number(SyntaxHighlighting_VERSION_MINOR) + + QLatin1String(".xml"); + auto req = QNetworkRequest(QUrl(url)); + req.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); + auto reply = d->nam->get(req); + QObject::connect(reply, &QNetworkReply::finished, this, [=]() { + d->definitionListDownloadFinished(reply); + }); +} diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/definitiondownloader.h b/src/libs/3rdparty/syntax-highlighting/src/lib/definitiondownloader.h new file mode 100644 index 0000000000..06e28f6a65 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/definitiondownloader.h @@ -0,0 +1,113 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_DEFINITIONDOWNLOADER_H +#define KSYNTAXHIGHLIGHTING_DEFINITIONDOWNLOADER_H + +#include "ksyntaxhighlighting_export.h" + +#include <QObject> +#include <memory> + +namespace KSyntaxHighlighting { + +class DefinitionDownloaderPrivate; +class Repository; + +/** + * Helper class to download definition file updates. + * + * With the DefinitionDownloader you can download new and update existing + * syntax highlighting definition files (xml files). + * + * An example that updates the highlighting Definition%s and prints the current + * update progress to the console may look as follows: + * + * @code + * auto downloader = new DefinitionDownloader(repo); // repo is a pointer to a Repository + * + * // print update progress to console + * QObject::connect(downloader, &DefinitionDownloader::informationMessage, [](const QString &msg) { + * std::cout << qPrintable(msg) << std::endl; + * }); + * + * // connect to signal done to delete the downloader later + * QObject::connect(downloader, &DefinitionDownloader::done, + * downloader, &DefinitionDownloader::deleteLater); + * downloader->start(); + * @endcode + * + * @see Repository, Definition + * @since 5.28 + */ +class KSYNTAXHIGHLIGHTING_EXPORT DefinitionDownloader : public QObject +{ + Q_OBJECT +public: + /** + * Constructor. + * The Repository @p repo is used as reference to compare the versions of + * the existing Definition%s with the ones that are available online. + * + * Optionally, @p parent is a pointer to the owner of this instance. + */ + explicit DefinitionDownloader(Repository *repo, QObject *parent = nullptr); + + /** + * Destructor. + */ + ~DefinitionDownloader(); + + /** + * Starts the update procedure. + * Once no more updates are available (i.e. either the local definition files + * are up-to-date, or all updates have been downloaded), the signal done() + * is emitted. + * + * During the update process, the signal informationMessage() can be used + * to display the current update progress to the user. + * + * @see done(), informationMessage() + */ + void start(); + +Q_SIGNALS: + /** + * Prints the information about the current state of the definition files. + * If all files are up-to-date, this signal is emitted informing you that + * all highlighting files are up-to-date. If there are updates, this signal + * is emitted for each update being downloaded. + */ + void informationMessage(const QString &msg); + + /** + * This signal is emitted when there are no pending downloads anymore. + */ + void done(); + +private: + std::unique_ptr<DefinitionDownloaderPrivate> d; +}; +} + +#endif // KSYNTAXHIGHLIGHTING_DEFINITIONDOWNLOADER_H diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/definitionref_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/definitionref_p.h new file mode 100644 index 0000000000..08604a4821 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/definitionref_p.h @@ -0,0 +1,74 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_DEFINITIONREF_P_H +#define KSYNTAXHIGHLIGHTING_DEFINITIONREF_P_H + +#include <memory> + +namespace KSyntaxHighlighting { + +class Definition; +class DefinitionData; +class DefinitionPrivate; + +/** Weak reference for Definition instances. + * + * This must be used when holding Definition instances + * in objects hold directly or indirectly by Definition + * to avoid reference count loops and thus memory leaks. + * + * @internal + */ +class DefinitionRef +{ +public: + DefinitionRef(); + explicit DefinitionRef(const Definition &def); + ~DefinitionRef(); + DefinitionRef& operator=(const Definition &def); + + Definition definition() const; + + /** + * Checks two definition references for equality. + */ + bool operator==(const DefinitionRef &other) const; + + /** + * Checks two definition references for inequality. + */ + bool operator!=(const DefinitionRef &other) const + { + return !(*this == other); + } + +private: + friend class DefinitionData; + std::weak_ptr<DefinitionData> d; +}; + +} + +#endif + diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/foldingregion.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/foldingregion.cpp new file mode 100644 index 0000000000..e8f89bd788 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/foldingregion.cpp @@ -0,0 +1,60 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "foldingregion.h" + +using namespace KSyntaxHighlighting; + +static_assert(sizeof(FoldingRegion) == 2, "FoldingRegion is size-sensitive to frequent use in KTextEditor!"); + +FoldingRegion::FoldingRegion() : + m_type(None), + m_id(0) +{ +} + +FoldingRegion::FoldingRegion(Type type, quint16 id) : + m_type(type), + m_id(id) +{ +} + +bool FoldingRegion::operator==(const FoldingRegion &other) const +{ + return m_id == other.m_id && m_type == other.m_type; +} + +bool FoldingRegion::isValid() const +{ + return type() != None; +} + +quint16 FoldingRegion::id() const +{ + return m_id; +} + +FoldingRegion::Type FoldingRegion::type() const +{ + return static_cast<FoldingRegion::Type>(m_type); +} diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/foldingregion.h b/src/libs/3rdparty/syntax-highlighting/src/lib/foldingregion.h new file mode 100644 index 0000000000..074b9478be --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/foldingregion.h @@ -0,0 +1,108 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_FOLDINGREGION_H +#define KSYNTAXHIGHLIGHTING_FOLDINGREGION_H + +#include "ksyntaxhighlighting_export.h" + +#include <QTypeInfo> + +namespace KSyntaxHighlighting { + +/** Represents a begin or end of a folding region. + * @since 5.28 */ +class KSYNTAXHIGHLIGHTING_EXPORT FoldingRegion +{ +public: + /** + * Defines whether a FoldingRegion starts or ends a folding region. + */ + enum Type { + //! Used internally as indicator for invalid FoldingRegion%s. + None, + //! Indicates the start of a FoldingRegion. + Begin, + //! Indicates the end of a FoldingRegion. + End + }; + + /** + * Constructs an invalid folding region, meaning that isValid() returns @e false. + * To obtain valid instances, see AbstractHighlighter::applyFolding(). + */ + FoldingRegion(); + + /** Compares two FoldingRegion instances for equality. */ + bool operator==(const FoldingRegion &other) const; + + /** + * Returns @c true if this is a valid folding region. + * A valid FoldingRegion is defined by a type() other than Type::None. + * + * @note The FoldingRegion%s passed in AbstractHighlighter::applyFolding() + * are always valid. + */ + bool isValid() const; + + /** + * Returns a unique identifier for this folding region. + * + * As example, the C/C++ highlighter starts and ends a folding region for + * scopes, e.g.: + * \code + * void foo() { // '{' starts a folding region + * if (bar()) { // '{' starts a (nested) folding region + * } // '}' ends the (nested) folding region + * } // '}' ends the outer folding region + * \endcode + * In this example, all braces '{' and '}' have the same id(), meaning that + * if you want to find the matching closing region for the first opening + * brace, you need to do kind of a reference counting to find the correct + * closing brace. + */ + quint16 id() const; + + /** + * Returns whether this is the begin or end of a region. + * + * @note The FoldingRegion%s passed in AbstractHighlighter::applyFolding() + * are always valid, i.e. either Type::Begin or Type::End. + */ + Type type() const; + +private: + friend class Rule; + FoldingRegion(Type type, quint16 id); + + quint16 m_type : 2; + quint16 m_id: 14; +}; + +} + +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(KSyntaxHighlighting::FoldingRegion, Q_PRIMITIVE_TYPE); +QT_END_NAMESPACE + +#endif diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp new file mode 100644 index 0000000000..397da6d700 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp @@ -0,0 +1,264 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "format.h" +#include "format_p.h" +#include "definition.h" +#include "definitionref_p.h" +#include "textstyledata_p.h" +#include "themedata_p.h" +#include "xml_p.h" + +#include <QColor> +#include <QDebug> +#include <QMetaEnum> +#include <QXmlStreamReader> + +using namespace KSyntaxHighlighting; + +static Theme::TextStyle stringToDefaultFormat(const QStringRef &str) +{ + if (!str.startsWith(QLatin1String("ds"))) + return Theme::Normal; + + static const auto idx = Theme::staticMetaObject.indexOfEnumerator("TextStyle"); + Q_ASSERT(idx >= 0); + const auto metaEnum = Theme::staticMetaObject.enumerator(idx); + + bool ok = false; + const auto value = metaEnum.keyToValue(str.mid(2).toLatin1().constData(), &ok); + if (!ok || value < 0) + return Theme::Normal; + return static_cast<Theme::TextStyle>(value); +} + +FormatPrivate* FormatPrivate::detachAndGet(Format &format) +{ + format.d.detach(); + return format.d.data(); +} + +TextStyleData FormatPrivate::styleOverride(const Theme &theme) const +{ + const auto themeData = ThemeData::get(theme); + if (themeData) + return themeData->textStyleOverride(definition.definition().name(), name); + return TextStyleData(); +} + +static QExplicitlySharedDataPointer<FormatPrivate> &sharedDefaultPrivate() +{ + static QExplicitlySharedDataPointer<FormatPrivate> def(new FormatPrivate); + return def; +} + +Format::Format() : d(sharedDefaultPrivate()) +{ +} + +Format::Format(const Format &other) : + d(other.d) +{ +} + +Format::~Format() +{ +} + +Format& Format::operator=(const Format& other) +{ + d = other.d; + return *this; +} + +bool Format::isValid() const +{ + return !d->name.isEmpty(); +} + +QString Format::name() const +{ + return d->name; +} + +quint16 Format::id() const +{ + return d->id; +} + +Theme::TextStyle Format::textStyle() const +{ + return d->defaultStyle; +} + +bool Format::isDefaultTextStyle(const Theme &theme) const +{ + return (!hasTextColor(theme)) + && (!hasBackgroundColor(theme)) + && (selectedTextColor(theme) == theme.selectedTextColor(Theme::Normal)) + && (selectedBackgroundColor(theme) == theme.selectedBackgroundColor(Theme::Normal)) + && (isBold(theme) == theme.isBold(Theme::Normal)) + && (isItalic(theme) == theme.isItalic(Theme::Normal)) + && (isUnderline(theme) == theme.isUnderline(Theme::Normal)) + && (isStrikeThrough(theme) == theme.isStrikeThrough(Theme::Normal)); +} + +bool Format::hasTextColor(const Theme &theme) const +{ + const auto overrideStyle = d->styleOverride(theme); + return textColor(theme) != theme.textColor(Theme::Normal) + && (d->style.textColor || theme.textColor(d->defaultStyle) || overrideStyle.textColor); +} + +QColor Format::textColor(const Theme &theme) const +{ + const auto overrideStyle = d->styleOverride(theme); + if (overrideStyle.textColor) + return overrideStyle.textColor; + return d->style.textColor ? d->style.textColor : theme.textColor(d->defaultStyle); +} + +QColor Format::selectedTextColor(const Theme &theme) const +{ + const auto overrideStyle = d->styleOverride(theme); + if (overrideStyle.selectedTextColor) + return overrideStyle.selectedTextColor; + return d->style.selectedTextColor ? d->style.selectedTextColor : theme.selectedTextColor(d->defaultStyle); +} + +bool Format::hasBackgroundColor(const Theme &theme) const +{ + const auto overrideStyle = d->styleOverride(theme); + return backgroundColor(theme) != theme.backgroundColor(Theme::Normal) + && (d->style.backgroundColor || theme.backgroundColor(d->defaultStyle) || overrideStyle.backgroundColor); +} + +QColor Format::backgroundColor(const Theme &theme) const +{ + const auto overrideStyle = d->styleOverride(theme); + if (overrideStyle.backgroundColor) + return overrideStyle.backgroundColor; + return d->style.backgroundColor ? d->style.backgroundColor : theme.backgroundColor(d->defaultStyle); +} + +QColor Format::selectedBackgroundColor(const Theme &theme) const +{ + const auto overrideStyle = d->styleOverride(theme); + if (overrideStyle.selectedBackgroundColor) + return overrideStyle.selectedBackgroundColor; + return d->style.selectedBackgroundColor ? d->style.selectedBackgroundColor + : theme.selectedBackgroundColor(d->defaultStyle); +} + +bool Format::isBold(const Theme &theme) const +{ + const auto overrideStyle = d->styleOverride(theme); + if (overrideStyle.hasBold) + return overrideStyle.bold; + return d->style.hasBold ? d->style.bold : theme.isBold(d->defaultStyle); +} + +bool Format::isItalic(const Theme &theme) const +{ + const auto overrideStyle = d->styleOverride(theme); + if (overrideStyle.hasItalic) + return overrideStyle.italic; + return d->style.hasItalic ? d->style.italic : theme.isItalic(d->defaultStyle); +} + +bool Format::isUnderline(const Theme &theme) const +{ + const auto overrideStyle = d->styleOverride(theme); + if (overrideStyle.hasUnderline) + return overrideStyle.underline; + return d->style.hasUnderline ? d->style.underline : theme.isUnderline(d->defaultStyle); +} + +bool Format::isStrikeThrough(const Theme &theme) const +{ + const auto overrideStyle = d->styleOverride(theme); + if (overrideStyle.hasStrikeThrough) + return overrideStyle.strikeThrough; + return d->style.hasStrikeThrough ? d->style.strikeThrough : theme.isStrikeThrough(d->defaultStyle); +} + +bool Format::spellCheck() const +{ + return d->spellCheck; +} + + +void FormatPrivate::load(QXmlStreamReader& reader) +{ + name = reader.attributes().value(QStringLiteral("name")).toString(); + defaultStyle = stringToDefaultFormat(reader.attributes().value(QStringLiteral("defStyleNum"))); + + QStringRef ref = reader.attributes().value(QStringLiteral("color")); + if (!ref.isEmpty()) { + style.textColor = QColor(ref.toString()).rgba(); + } + + ref = reader.attributes().value(QStringLiteral("selColor")); + if (!ref.isEmpty()) { + style.selectedTextColor = QColor(ref.toString()).rgba(); + } + + ref = reader.attributes().value(QStringLiteral("backgroundColor")); + if (!ref.isEmpty()) { + style.backgroundColor = QColor(ref.toString()).rgba(); + } + + ref = reader.attributes().value(QStringLiteral("selBackgroundColor")); + if (!ref.isEmpty()) { + style.selectedBackgroundColor = QColor(ref.toString()).rgba(); + } + + ref = reader.attributes().value(QStringLiteral("italic")); + if (!ref.isEmpty()) { + style.hasItalic = true; + style.italic = Xml::attrToBool(ref); + } + + ref = reader.attributes().value(QStringLiteral("bold")); + if (!ref.isEmpty()) { + style.hasBold = true; + style.bold = Xml::attrToBool(ref); + } + + ref = reader.attributes().value(QStringLiteral("underline")); + if (!ref.isEmpty()) { + style.hasUnderline = true; + style.underline = Xml::attrToBool(ref); + } + + ref = reader.attributes().value(QStringLiteral("strikeOut")); + if (!ref.isEmpty()) { + style.hasStrikeThrough = true; + style.strikeThrough = Xml::attrToBool(ref); + } + + ref = reader.attributes().value(QStringLiteral("spellChecking")); + if (!ref.isEmpty()) { + spellCheck = Xml::attrToBool(ref); + } +} diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/format.h b/src/libs/3rdparty/syntax-highlighting/src/lib/format.h new file mode 100644 index 0000000000..24c58e73f6 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/format.h @@ -0,0 +1,152 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_FORMAT_H +#define KSYNTAXHIGHLIGHTING_FORMAT_H + +#include "ksyntaxhighlighting_export.h" +#include "theme.h" + +#include <QExplicitlySharedDataPointer> +#include <QTypeInfo> + +QT_BEGIN_NAMESPACE +class QColor; +class QString; +class QXmlStreamReader; +QT_END_NAMESPACE + +namespace KSyntaxHighlighting { + +class DefinitionRef; +class FormatPrivate; + +/** Describes the format to be used for a specific text fragment. + * The actual format used for displaying is merged from the format information + * in the syntax definition file, and a theme. + * + * @see Theme + * @since 5.28 + */ +class KSYNTAXHIGHLIGHTING_EXPORT Format +{ +public: + /** Creates an empty/invalid format. */ + Format(); + Format(const Format &other); + ~Format(); + + Format& operator=(const Format &other); + + /** Returns @c true if this is a valid format, ie. one that + * was read from a syntax definition file. + */ + bool isValid() const; + + /** The name of this format as used in the syntax definition file. */ + QString name() const; + + /** Returns a unique identifier of this format. + * This is useful for efficient storing of formats in a text line. The + * identifier is unique per Repository instance, but will change when + * the repository is reloaded (which also invalidatess the corresponding + * Definition anyway). + */ + quint16 id() const; + + /** Returns the underlying TextStyle of this Format. + * Every Theme::TextStyle is visually defined by a Theme. A Format uses one + * of the Theme::TextStyle%s and on top allows modifications such as setting + * a different foreground color etc. + * @see Theme::TextStyle + * @since 5.49 + */ + Theme::TextStyle textStyle() const; + + /** Returns @c true if the combination of this format and the theme @p theme + * do not change the default text format in any way. + * This is useful for output formats where changing formatting implies cost, + * and thus benefit from optimizing the default case of not having any format + * applied. If you make use of this, make sure to set the default text style + * to what the corresponding theme sets for Theme::Normal. + */ + bool isDefaultTextStyle(const Theme &theme) const; + + /** Returns @c true if the combination of this format and the theme @p theme + * change the foreground color compared to the default format. + */ + bool hasTextColor(const Theme &theme) const; + /** Returns the foreground color of the combination of this format and the + * given theme. + */ + QColor textColor(const Theme &theme) const; + /** Returns the foreground color for selected text of the combination of + * this format and the given theme. + */ + QColor selectedTextColor(const Theme &theme) const; + /** Returns @c true if the combination of this format and the theme @p theme + * change the background color compared to the default format. + */ + bool hasBackgroundColor(const Theme &theme) const; + /** Returns the background color of the combination of this format and the + * given theme. + */ + QColor backgroundColor(const Theme &theme) const; + /** Returns the background color of selected text of the combination of + * this format and the given theme. + */ + QColor selectedBackgroundColor(const Theme &theme) const; + + /** Returns @c true if the combination of this format and the given theme + * results in bold text formatting. + */ + bool isBold(const Theme &theme) const; + /** Returns @c true if the combination of this format and the given theme + * results in italic text formatting. + */ + bool isItalic(const Theme &theme) const; + /** Returns @c true if the combination of this format and the given theme + * results in underlined text. + */ + bool isUnderline(const Theme &theme) const; + /** Returns @c true if the combination of this format and the given theme + * results in struck through text. + */ + bool isStrikeThrough(const Theme &theme) const; + + /** + * Returns whether characters with this format should be spell checked. + */ + bool spellCheck() const; + +private: + friend class FormatPrivate; + QExplicitlySharedDataPointer<FormatPrivate> d; +}; +} + +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(KSyntaxHighlighting::Format, Q_MOVABLE_TYPE); +QT_END_NAMESPACE + +#endif // KSYNTAXHIGHLIGHTING_FORMAT_H diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/format_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/format_p.h new file mode 100644 index 0000000000..e79b26b6a7 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/format_p.h @@ -0,0 +1,55 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_FORMAT_P_H +#define KSYNTAXHIGHLIGHTING_FORMAT_P_H + +#include "definitionref_p.h" +#include "textstyledata_p.h" +#include "theme.h" + +#include <QSharedData> +#include <QString> + +namespace KSyntaxHighlighting { + +class FormatPrivate : public QSharedData +{ +public: + FormatPrivate() = default; + static FormatPrivate* detachAndGet(Format &format); + + TextStyleData styleOverride(const Theme &theme) const; + void load(QXmlStreamReader &reader); + + DefinitionRef definition; + QString name; + TextStyleData style; + Theme::TextStyle defaultStyle = Theme::Normal; + quint16 id = 0; + bool spellCheck = true; +}; + +} + +#endif diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/htmlhighlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/htmlhighlighter.cpp new file mode 100644 index 0000000000..4ebd465b77 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/htmlhighlighter.cpp @@ -0,0 +1,161 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + Copyright (C) 2018 Christoph Cullmann <cullmann@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "htmlhighlighter.h" +#include "definition.h" +#include "format.h" +#include "state.h" +#include "theme.h" +#include "ksyntaxhighlighting_logging.h" + +#include <QDebug> +#include <QFile> +#include <QFileInfo> +#include <QTextStream> +#include <QVarLengthArray> + +using namespace KSyntaxHighlighting; + +class KSyntaxHighlighting::HtmlHighlighterPrivate +{ +public: + std::unique_ptr<QTextStream> out; + std::unique_ptr<QFile> file; + QString currentLine; +}; + +HtmlHighlighter::HtmlHighlighter() + : d(new HtmlHighlighterPrivate()) +{ +} + +HtmlHighlighter::~HtmlHighlighter() +{ +} + +void HtmlHighlighter::setOutputFile(const QString& fileName) +{ + d->file.reset(new QFile(fileName)); + if (!d->file->open(QFile::WriteOnly | QFile::Truncate)) { + qCWarning(Log) << "Failed to open output file" << fileName << ":" << d->file->errorString(); + return; + } + d->out.reset(new QTextStream(d->file.get())); + d->out->setCodec("UTF-8"); +} + +void HtmlHighlighter::setOutputFile(FILE *fileHandle) +{ + d->out.reset(new QTextStream(fileHandle, QIODevice::WriteOnly)); + d->out->setCodec("UTF-8"); +} + +void HtmlHighlighter::highlightFile(const QString& fileName, const QString& title) +{ + QFileInfo fi(fileName); + QFile f(fileName); + if (!f.open(QFile::ReadOnly)) { + qCWarning(Log) << "Failed to open input file" << fileName << ":" << f.errorString(); + return; + } + + if (title.isEmpty()) + highlightData(&f, fi.fileName()); + else + highlightData(&f, title); +} + +void HtmlHighlighter::highlightData(QIODevice *dev, const QString& title) +{ + if (!d->out) { + qCWarning(Log) << "No output stream defined!"; + return; + } + + QString htmlTitle; + if (title.isEmpty()) + htmlTitle = QStringLiteral("Kate Syntax Highlighter"); + else + htmlTitle = title.toHtmlEscaped(); + + State state; + *d->out << "<!DOCTYPE html>\n"; + *d->out << "<html><head>\n"; + *d->out << "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>\n"; + *d->out << "<title>" << htmlTitle << "</title>\n"; + *d->out << "<meta name=\"generator\" content=\"KF5::SyntaxHighlighting (" << definition().name() << ")\"/>\n"; + *d->out << "</head><body"; + if (theme().textColor(Theme::Normal)) + *d->out << " style=\"color:" << QColor(theme().textColor(Theme::Normal)).name() << "\""; + *d->out << "><pre>\n"; + + QTextStream in(dev); + in.setCodec("UTF-8"); + while (!in.atEnd()) { + d->currentLine = in.readLine(); + state = highlightLine(d->currentLine, state); + *d->out << "\n"; + } + + *d->out << "</pre></body></html>\n"; + d->out->flush(); + + d->out.reset(); + d->file.reset(); +} + +void HtmlHighlighter::applyFormat(int offset, int length, const Format& format) +{ + if (length == 0) + return; + + // collect potential output, cheaper than thinking about "is there any?" + QVarLengthArray<QString, 16> formatOutput; + if (format.hasTextColor(theme())) + formatOutput << QStringLiteral("color:") << format.textColor(theme()).name() << QStringLiteral(";"); + if (format.hasBackgroundColor(theme())) + formatOutput << QStringLiteral("background-color:") << format.backgroundColor(theme()).name() << QStringLiteral(";"); + if (format.isBold(theme())) + formatOutput << QStringLiteral("font-weight:bold;"); + if (format.isItalic(theme())) + formatOutput << QStringLiteral("font-style:italic;"); + if (format.isUnderline(theme())) + formatOutput << QStringLiteral("text-decoration:underline;"); + if (format.isStrikeThrough(theme())) + formatOutput << QStringLiteral("text-decoration:line-through;"); + + if (!formatOutput.isEmpty()) { + *d->out << "<span style=\""; + for (const auto &out : qAsConst(formatOutput)) { + *d->out << out; + } + *d->out << "\">"; + } + + *d->out << d->currentLine.mid(offset, length).toHtmlEscaped(); + + if (!formatOutput.isEmpty()) { + *d->out << "</span>"; + } +} diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/htmlhighlighter.h b/src/libs/3rdparty/syntax-highlighting/src/lib/htmlhighlighter.h new file mode 100644 index 0000000000..b7eda02d54 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/htmlhighlighter.h @@ -0,0 +1,64 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_HTMLHIGHLIGHTER_H +#define KSYNTAXHIGHLIGHTING_HTMLHIGHLIGHTER_H + +#include "ksyntaxhighlighting_export.h" +#include "abstracthighlighter.h" + +#include <QString> +#include <QIODevice> + +#include <memory> + +QT_BEGIN_NAMESPACE +class QFile; +class QTextStream; +QT_END_NAMESPACE + +namespace KSyntaxHighlighting { + +class HtmlHighlighterPrivate; + +class KSYNTAXHIGHLIGHTING_EXPORT HtmlHighlighter : public AbstractHighlighter +{ +public: + HtmlHighlighter(); + ~HtmlHighlighter() override; + + void highlightFile(const QString &fileName, const QString &title = QString()); + void highlightData(QIODevice *device, const QString &title = QString()); + + void setOutputFile(const QString &fileName); + void setOutputFile(FILE *fileHandle); + +protected: + void applyFormat(int offset, int length, const Format &format) override; + +private: + std::unique_ptr<HtmlHighlighterPrivate> d; +}; +} + +#endif // KSYNTAXHIGHLIGHTING_HTMLHIGHLIGHTER_H diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp new file mode 100644 index 0000000000..fe5f77586a --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp @@ -0,0 +1,104 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "keywordlist_p.h" + +#include <QDebug> +#include <QXmlStreamReader> + +#include <algorithm> + +using namespace KSyntaxHighlighting; + +bool KeywordList::contains(const QStringRef &str, Qt::CaseSensitivity caseSensitive) const +{ + /** + * get right vector to search in + */ + const auto &vectorToSearch = (caseSensitive == Qt::CaseSensitive) ? m_keywordsSortedCaseSensitive : m_keywordsSortedCaseInsensitive; + + /** + * search with right predicate + */ + return std::binary_search(vectorToSearch.begin(), vectorToSearch.end(), str, [caseSensitive] (const QStringRef &a, const QStringRef &b) { return a.compare(b, caseSensitive) < 0; }); +} + +void KeywordList::load(QXmlStreamReader& reader) +{ + Q_ASSERT(reader.name() == QLatin1String("list")); + Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement); + + m_name = reader.attributes().value(QStringLiteral("name")).toString(); + + while (!reader.atEnd()) { + switch (reader.tokenType()) { + case QXmlStreamReader::StartElement: + if (reader.name() == QLatin1String("item")) { + m_keywords.append(reader.readElementText().trimmed()); + reader.readNextStartElement(); + break; + } + reader.readNext(); + break; + case QXmlStreamReader::EndElement: + reader.readNext(); + return; + default: + reader.readNext(); + break; + } + } +} + +void KeywordList::setCaseSensitivity(Qt::CaseSensitivity caseSensitive) +{ + /** + * remember default case-sensitivity and init lookup for it + */ + m_caseSensitive = caseSensitive; + initLookupForCaseSensitivity(m_caseSensitive); +} + +void KeywordList::initLookupForCaseSensitivity(Qt::CaseSensitivity caseSensitive) +{ + /** + * get right vector to sort, if non-empty, we are done + */ + auto &vectorToSort = (caseSensitive == Qt::CaseSensitive) ? m_keywordsSortedCaseSensitive : m_keywordsSortedCaseInsensitive; + if (!vectorToSort.empty()) { + return; + } + + /** + * fill vector with refs to keywords + */ + vectorToSort.reserve(m_keywords.size()); + for (const auto &keyword : qAsConst(m_keywords)) { + vectorToSort.push_back(&keyword); + } + + /** + * sort with right predicate + */ + std::sort(vectorToSort.begin(), vectorToSort.end(), [caseSensitive] (const QStringRef &a, const QStringRef &b) { return a.compare(b, caseSensitive) < 0; }); +} diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist_p.h new file mode 100644 index 0000000000..8c41aabe0c --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist_p.h @@ -0,0 +1,101 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_KEYWORDLIST_P_H +#define KSYNTAXHIGHLIGHTING_KEYWORDLIST_P_H + +#include <QSet> +#include <QString> +#include <QVector> + +#include <vector> + +QT_BEGIN_NAMESPACE +class QXmlStreamReader; +QT_END_NAMESPACE + +namespace KSyntaxHighlighting { + +class KeywordList +{ +public: + KeywordList() = default; + ~KeywordList() = default; + + bool isEmpty() const + { + return m_keywords.isEmpty(); + } + + const QString &name() const + { + return m_name; + } + + const QStringList &keywords() const + { + return m_keywords; + } + + /** Checks if @p str is a keyword in this list. */ + bool contains(const QStringRef &str) const + { + return contains(str, m_caseSensitive); + } + + /** Checks if @p str is a keyword in this list, overriding the global case-sensitivity setting. */ + bool contains(const QStringRef &str, Qt::CaseSensitivity caseSensitive) const; + + void load(QXmlStreamReader &reader); + void setCaseSensitivity(Qt::CaseSensitivity caseSensitive); + void initLookupForCaseSensitivity(Qt::CaseSensitivity caseSensitive); + +private: + /** + * name of keyword list as in XML + */ + QString m_name; + + /** + * raw list of keywords, as seen in XML (but trimmed) + */ + QStringList m_keywords; + + /** + * default case-sensitivity setting + */ + Qt::CaseSensitivity m_caseSensitive = Qt::CaseSensitive; + + /** + * case-sensitive sorted string references to m_keywords for lookup + */ + std::vector<QStringRef> m_keywordsSortedCaseSensitive; + + /** + * case-insensitive sorted string references to m_keywords for lookup + */ + std::vector<QStringRef> m_keywordsSortedCaseInsensitive; +}; +} + +#endif // KSYNTAXHIGHLIGHTING_KEYWORDLIST_P_H diff --git a/tests/auto/generichighlighter/highlighterengine/tabsettings.h b/src/libs/3rdparty/syntax-highlighting/src/lib/ksyntaxhighlighting_export.h index 968946be54..a39adb5ed6 100644 --- a/tests/auto/generichighlighter/highlighterengine/tabsettings.h +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/ksyntaxhighlighting_export.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. @@ -25,16 +25,10 @@ #pragma once -#include <QString> +#include <QtGlobal> -// Replaces the "real" tabsettings.h file. - -namespace TextEditor { - -class TabSettings -{ -public: - int indentationColumn(const QString &) const { return 0; } -}; - -} +#if defined(KSYNTAXHIGHLIGHTING_LIBRARY) +# define KSYNTAXHIGHLIGHTING_EXPORT Q_DECL_EXPORT +#else +# define KSYNTAXHIGHLIGHTING_EXPORT Q_DECL_IMPORT +#endif diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/matchresult_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/matchresult_p.h new file mode 100644 index 0000000000..b1a05ee636 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/matchresult_p.h @@ -0,0 +1,113 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_MATCHRESULT_P_H +#define KSYNTAXHIGHLIGHTING_MATCHRESULT_P_H + +#include <QStringList> + +namespace KSyntaxHighlighting { + +/** + * Storage for match result of a Rule. + * Heavily used internally during highlightLine, therefore completely inline. + */ +class MatchResult +{ +public: + /** + * Match at given offset found. + * @param offset offset of match + */ + MatchResult(const int offset) + : m_offset(offset) + { + } + + /** + * Match at given offset found with additional skip offset. + */ + explicit MatchResult(const int offset, const int skipOffset) + : m_offset(offset) + , m_skipOffset(skipOffset) + { + } + + /** + * Match at given offset found with additional captures. + * @param offset offset of match + * @param captures captures of the match + */ + explicit MatchResult(const int offset, const QStringList &captures) + : m_offset(offset) + , m_captures(captures) + { + } + + /** + * Offset of the match + * @return offset of the match + */ + int offset() const + { + return m_offset; + } + + + /** + * Skip offset of the match + * @return skip offset of the match, no match possible until this offset is reached + */ + int skipOffset() const + { + return m_skipOffset; + } + + /** + * Captures of the match. + * @return captured text of this match + */ + const QStringList &captures() const + { + return m_captures; + } + +private: + /** + * match offset, filled in all constructors + */ + int m_offset; + + /** + * skip offset, optional + */ + int m_skipOffset = 0; + + /** + * captures, optional + */ + QStringList m_captures; +}; +} + +#endif // KSYNTAXHIGHLIGHTING_MATCHRESULT_P_H diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp new file mode 100644 index 0000000000..6b2fabd07a --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp @@ -0,0 +1,325 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "repository.h" +#include "repository_p.h" +#include "definition.h" +#include "definition_p.h" +#include "theme.h" +#include "themedata_p.h" +#include "ksyntaxhighlighting_logging.h" +#include "wildcardmatcher_p.h" + +#include <QDebug> +#include <QDirIterator> +#include <QFile> +#include <QFileInfo> +#include <QJsonDocument> +#include <QJsonObject> + +#ifndef NO_STANDARD_PATHS +#include <QStandardPaths> +#endif + +#include <limits> + +using namespace KSyntaxHighlighting; + +static void initResource() +{ +#ifdef HAS_SYNTAX_RESOURCE + Q_INIT_RESOURCE(syntax_data); +#endif + Q_INIT_RESOURCE(theme_data); +} + +RepositoryPrivate* RepositoryPrivate::get(Repository *repo) +{ + return repo->d.get(); +} + +Repository::Repository() : + d(new RepositoryPrivate) +{ + initResource(); + d->load(this); +} + +Repository::~Repository() +{ + // reset repo so we can detect in still alive definition instances + // that the repo was deleted + foreach (const auto &def, d->m_sortedDefs) + DefinitionData::get(def)->repo = nullptr; +} + +Definition Repository::definitionForName(const QString& defName) const +{ + return d->m_defs.value(defName); +} + +static Definition bestCandidate(QVector<Definition>& candidates) +{ + if (candidates.isEmpty()) + return Definition(); + + std::partial_sort(candidates.begin(), candidates.begin() + 1, candidates.end(), [](const Definition &lhs, const Definition &rhs) { + return lhs.priority() > rhs.priority(); + }); + + return candidates.at(0); +} + +Definition Repository::definitionForFileName(const QString& fileName) const +{ + QFileInfo fi(fileName); + const auto name = fi.fileName(); + + QVector<Definition> candidates; + for (auto it = d->m_defs.constBegin(); it != d->m_defs.constEnd(); ++it) { + auto def = it.value(); + foreach (const auto &pattern, def.extensions()) { + if (WildcardMatcher::exactMatch(name, pattern)) { + candidates.push_back(def); + break; + } + } + } + + return bestCandidate(candidates); +} + +Definition Repository::definitionForMimeType(const QString& mimeType) const +{ + QVector<Definition> candidates; + for (auto it = d->m_defs.constBegin(); it != d->m_defs.constEnd(); ++it) { + auto def = it.value(); + foreach (const auto &matchType, def.mimeTypes()) { + if (mimeType == matchType) { + candidates.push_back(def); + break; + } + } + } + + return bestCandidate(candidates); +} + +QVector<Definition> Repository::definitions() const +{ + return d->m_sortedDefs; +} + +QVector<Theme> Repository::themes() const +{ + return d->m_themes; +} + +Theme Repository::theme(const QString &themeName) const +{ + for (const auto &theme : qAsConst(d->m_themes)) { + if (theme.name() == themeName) { + return theme; + } + } + + return Theme(); +} + +Theme Repository::defaultTheme(Repository::DefaultTheme t) +{ + if (t == DarkTheme) + return theme(QLatin1String("Breeze Dark")); + return theme(QLatin1String("Default")); +} + +void RepositoryPrivate::load(Repository *repo) +{ + // always add invalid default "None" highlighting + addDefinition(Definition()); + + // do lookup in standard paths, if not disabled +#ifndef NO_STANDARD_PATHS + foreach (const auto &dir, QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("org.kde.syntax-highlighting/syntax"), QStandardPaths::LocateDirectory)) + loadSyntaxFolder(repo, dir); + + // backward compatibility with Kate + foreach (const auto &dir, QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("katepart5/syntax"), QStandardPaths::LocateDirectory)) + loadSyntaxFolder(repo, dir); +#endif + + // default resources are always used + loadSyntaxFolder(repo, QStringLiteral(":/org.kde.syntax-highlighting/syntax")); + + // user given extra paths + foreach (const auto &path, m_customSearchPaths) + loadSyntaxFolder(repo, path + QStringLiteral("/syntax")); + + m_sortedDefs.reserve(m_defs.size()); + for (auto it = m_defs.constBegin(); it != m_defs.constEnd(); ++it) + m_sortedDefs.push_back(it.value()); + std::sort(m_sortedDefs.begin(), m_sortedDefs.end(), [](const Definition &left, const Definition &right) { + auto comparison = left.translatedSection().compare(right.translatedSection(), Qt::CaseInsensitive); + if (comparison == 0) + comparison = left.translatedName().compare(right.translatedName(), Qt::CaseInsensitive); + return comparison < 0; + }); + + // load themes + + // do lookup in standard paths, if not disabled +#ifndef NO_STANDARD_PATHS + foreach (const auto &dir, QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("org.kde.syntax-highlighting/themes"), QStandardPaths::LocateDirectory)) + loadThemeFolder(dir); +#endif + + // default resources are always used + loadThemeFolder(QStringLiteral(":/org.kde.syntax-highlighting/themes")); + + // user given extra paths + foreach (const auto &path, m_customSearchPaths) + loadThemeFolder(path + QStringLiteral("/themes")); +} + +void RepositoryPrivate::loadSyntaxFolder(Repository *repo, const QString &path) +{ + if (loadSyntaxFolderFromIndex(repo, path)) + return; + + QDirIterator it(path, QStringList() << QLatin1String("*.xml"), QDir::Files); + while (it.hasNext()) { + Definition def; + auto defData = DefinitionData::get(def); + defData->repo = repo; + if (defData->loadMetaData(it.next())) + addDefinition(def); + } +} + +bool RepositoryPrivate::loadSyntaxFolderFromIndex(Repository *repo, const QString &path) +{ + QFile indexFile(path + QLatin1String("/index.katesyntax")); + if (!indexFile.open(QFile::ReadOnly)) + return false; + + const auto indexDoc(QJsonDocument::fromBinaryData(indexFile.readAll())); + const auto index = indexDoc.object(); + for (auto it = index.begin(); it != index.end(); ++it) { + if (!it.value().isObject()) + continue; + const auto fileName = QString(path + QLatin1Char('/') + it.key()); + const auto defMap = it.value().toObject(); + Definition def; + auto defData = DefinitionData::get(def); + defData->repo = repo; + if (defData->loadMetaData(fileName, defMap)) + addDefinition(def); + } + return true; +} + +void RepositoryPrivate::addDefinition(const Definition &def) +{ + const auto it = m_defs.constFind(def.name()); + if (it == m_defs.constEnd()) { + m_defs.insert(def.name(), def); + return; + } + + if (it.value().version() >= def.version()) + return; + m_defs.insert(def.name(), def); +} + +void RepositoryPrivate::loadThemeFolder(const QString &path) +{ + QDirIterator it(path, QStringList() << QLatin1String("*.theme"), QDir::Files); + while (it.hasNext()) { + auto themeData = std::unique_ptr<ThemeData>(new ThemeData); + if (themeData->load(it.next())) + addTheme(Theme(themeData.release())); + } +} + +static int themeRevision(const Theme &theme) +{ + auto data = ThemeData::get(theme); + return data->revision(); +} + +void RepositoryPrivate::addTheme(const Theme &theme) +{ + const auto it = std::lower_bound(m_themes.begin(), m_themes.end(), theme, [](const Theme &lhs, const Theme &rhs) { + return lhs.name() < rhs.name(); + }); + if (it == m_themes.end() || (*it).name() != theme.name()) { + m_themes.insert(it, theme); + return; + } + if (themeRevision(*it) < themeRevision(theme)) + *it = theme; +} + +quint16 RepositoryPrivate::foldingRegionId(const QString &defName, const QString &foldName) +{ + const auto it = m_foldingRegionIds.constFind(qMakePair(defName, foldName)); + if (it != m_foldingRegionIds.constEnd()) + return it.value(); + m_foldingRegionIds.insert(qMakePair(defName, foldName), ++m_foldingRegionId); + return m_foldingRegionId; +} + +quint16 RepositoryPrivate::nextFormatId() +{ + Q_ASSERT(m_formatId < std::numeric_limits<quint16>::max()); + return ++m_formatId; +} + +void Repository::reload() +{ + qCDebug(Log) << "Reloading syntax definitions!"; + foreach (const auto &def, d->m_sortedDefs) + DefinitionData::get(def)->clear(); + d->m_defs.clear(); + d->m_sortedDefs.clear(); + + d->m_themes.clear(); + + d->m_foldingRegionId = 0; + d->m_foldingRegionIds.clear(); + + d->m_formatId = 0; + + d->load(this); +} + +void Repository::addCustomSearchPath(const QString &path) +{ + d->m_customSearchPaths.append(path); + reload(); +} + +QVector<QString> Repository::customSearchPaths() const +{ + return d->m_customSearchPaths; +} diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h new file mode 100644 index 0000000000..c35da5ec37 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h @@ -0,0 +1,257 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_REPOSITORY_H +#define KSYNTAXHIGHLIGHTING_REPOSITORY_H + +#include "ksyntaxhighlighting_export.h" + +#include <qglobal.h> +#include <memory> + +QT_BEGIN_NAMESPACE +class QString; +template <typename T> class QVector; +QT_END_NAMESPACE + +/** + * @namespace KSyntaxHighlighting + * + * Syntax highlighting engine for Kate syntax definitions. + * In order to access the syntax highlighting Definition files, use the + * class Repository. + * + * @see Repository + */ +namespace KSyntaxHighlighting { + +class Definition; +class RepositoryPrivate; +class Theme; + +/** + * @brief Syntax highlighting repository. + * + * @section repo_intro Introduction + * + * The Repository gives access to all syntax Definitions available on the + * system, typically described in *.xml files. The Definition files are read + * from the resource that is compiled into the executable, and from the file + * system. If a Definition exists in the resource and on the file system, + * then the one from the file system is chosen. + * + * @section repo_access Definitions and Themes + * + * Typically, only one instance of the Repository is needed. This single + * instance can be thought of as a singleton you keep alive throughout the + * lifetime of your application. Then, either call definitionForName() with the + * given language name (e.g. "QML" or "Java"), or definitionForFileName() to + * obtain a Definition based on the filename/mimetype of the file. The + * function definitions() returns a list of all available syntax Definition%s. + * + * In addition to Definitions, the Repository also provides a list of Themes. + * A Theme is defined by a set of default text style colors as well as editor + * colors. These colors together provide all required colros for drawing all + * primitives of a text editor. All available Theme%s can be queried through + * themes(), and a Theme with a specific name is obtained through theme(). + * Additionally, defaultTheme() provides a way to obtain a default theme for + * either a light or a black color theme. + * + * @section repo_search_paths Search Paths + * + * All highlighting Definition and Theme files are compiled into the shared + * KSyntaxHighlighting library by using the Qt resource system. Loading + * additional files from disk is supported as well. + * + * Loading syntax Definition files works as follows: + * + * -# First, all syntax highlighting files are loaded that are located in + * QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("org.kde.syntax-highlighting/syntax"), QStandardPaths::LocateDirectory); + * Under Unix, this uses $XDG_DATA_HOME and $XDG_DATA_DIRS, which could + * map to $HOME/.local5/share/org.kde.syntax-highlighting/syntax and + * /usr/share/org.kde.syntax-highlighting/syntax. + * + * -# Next, for backwards compatibility with Kate, all syntax highlighting + * files are loaded that are located in + * QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("katepart5/syntax"), QStandardPaths::LocateDirectory); + * Again, under Unix, this uses $XDG_DATA_HOME and $XDG_DATA_DIRS, which + * could map to $HOME/.local5/share/katepart5/syntax and + * /usr/share/katepart5/syntax. + * + * -# Then, all files compiled into the library through resources are loaded. + * The internal resource path is ":/org.kde.syntax-highlighting/syntax". + * This path should never be touched by other applications. + * + * -# Finally, the search path can be extended by calling addCustomSearchPath(). + * A custom search path can either be a path on disk or again a path to + * a Qt resource. + * + * Similarly, loading Theme files works as follows: + * + * -# First, all Theme files are loaded that are located in + * QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("org.kde.syntax-highlighting/themes"), QStandardPaths::LocateDirectory); + * Under Unix, this uses $XDG_DATA_HOME and $XDG_DATA_DIRS, which could + * map to $HOME/.local5/share/org.kde.syntax-highlighting/themes and + * /usr/share/org.kde.syntax-highlighting/themes. + * + * -# Then, all files compiled into the library through resources are loaded. + * The internal resource path is ":/org.kde.syntax-highlighting/themes". + * This path should never be touched by other applications. + * + * -# Finally, all Theme%s located in the paths added addCustomSearchPath() + * are loaded. + * + * @note Whenever a Definition or a Theme exists twice, the variant with + * higher version is used. + * + * @note The QStandardPaths lookup can be disabled by compiling the framework with the -DNO_STANDARD_PATHS define. + * + * @see Definition, Theme, AbstractHighlighter + * @since 5.28 + */ +class KSYNTAXHIGHLIGHTING_EXPORT Repository +{ +public: + /** + * Create a new syntax definition repository. + * This will read the meta data information of all available syntax + * definition, which is a moderately expensive operation, it's therefore + * recommended to keep a single instance of Repository around as long + * as you need highlighting in your application. + */ + Repository(); + ~Repository(); + + /** + * Returns the Definition named @p defName. + * + * If no Definition is found, Definition::isValid() of the returned instance + * returns false. + * + * @note This uses case sensitive, untranslated names. For instance, + * the javascript.xml definition file sets its name to @e JavaScript. + * Therefore, only the string "JavaScript" will return a valid + * Definition file. + */ + Definition definitionForName(const QString &defName) const; + + /** + * Returns the best matching Definition for the file named @p fileName. + * The match is performed based on the \e extensions and @e mimetype of + * the definition files. If multiple matches are found, the one with the + * highest priority is returned. + * + * If no match is found, Definition::isValid() of the returned instance + * returns false. + */ + Definition definitionForFileName(const QString &fileName) const; + + /** + * Returns the best matching Definition to the type named @p mimeType + * + * If no match is found, Definition::isValid() of the returned instance + * returns false. + * + * @since 5.50 + */ + Definition definitionForMimeType(const QString &mimeType) const; + + /** + * Returns all available Definition%s. + * Definition%ss are ordered by translated section and translated names, + * for consistent displaying. + */ + QVector<Definition> definitions() const; + + /** + * Returns all available color themes. + * The returned list should never be empty. + */ + QVector<Theme> themes() const; + + /** + * Returns the theme called @p themeName. + * If the requested theme cannot be found, the retunred Theme is invalid, + * see Theme::isValid(). + */ + Theme theme(const QString &themeName) const; + + /** + * Built-in default theme types. + * @see defaultTheme() + */ + enum DefaultTheme { + //! Theme with a light background color. + LightTheme, + //! Theme with a dark background color. + DarkTheme + }; + + /** + * Returns a default theme instance of the given type. + * The returned Theme is guaranteed to be a valid theme. + */ + Theme defaultTheme(DefaultTheme t = LightTheme); + + /** + * Reloads the repository. + * This is a moderately expensive operations and should thus only be + * triggered when the installed syntax definition files changed. + */ + void reload(); + + /** + * Add a custom search path to the repository. + * This path will be searched in addition to the usual locations for syntax + * and theme definition files. Both locations on disk as well as Qt + * resource paths are supported. + * + * @note Internally, the two sub-folders @p path/syntax as well as + * @p path/themes are searched for additional Definition%s and + * Theme%s. Do not append @e syntax or @e themes to @p path + * yourself. + * + * @note Calling this triggers a reload() of the repository. + * + * @since 5.39 + */ + void addCustomSearchPath(const QString &path); + + /** + * Returns the list of custom search paths added to the repository. + * By default, this list is empty. + * + * @see addCustomSearchPath() + * @since 5.39 + */ + QVector<QString> customSearchPaths() const; + +private: + Q_DISABLE_COPY(Repository) + friend class RepositoryPrivate; + std::unique_ptr<RepositoryPrivate> d; +}; + +} + +#endif // KSYNTAXHIGHLIGHTING_REPOSITORY_H diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/repository_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/repository_p.h new file mode 100644 index 0000000000..9db876be59 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/repository_p.h @@ -0,0 +1,72 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_REPOSITORY_P_H +#define KSYNTAXHIGHLIGHTING_REPOSITORY_P_H + +#include <QHash> +#include <QVector> + +QT_BEGIN_NAMESPACE +class QString; +QT_END_NAMESPACE + +namespace KSyntaxHighlighting { + +class Definition; +class Repository; +class Theme; + +class RepositoryPrivate +{ +public: + RepositoryPrivate() = default; + + static RepositoryPrivate* get(Repository *repo); + + void load(Repository *repo); + void loadSyntaxFolder(Repository *repo, const QString &path); + bool loadSyntaxFolderFromIndex(Repository *repo, const QString &path); + + void addDefinition(const Definition &def); + + void loadThemeFolder(const QString &path); + void addTheme(const Theme &theme); + + quint16 foldingRegionId(const QString &defName, const QString &foldName); + quint16 nextFormatId(); + + QVector<QString> m_customSearchPaths; + + QHash<QString, Definition> m_defs; + QVector<Definition> m_sortedDefs; + + QVector<Theme> m_themes; + + QHash<QPair<QString, QString>, quint16> m_foldingRegionIds; + quint16 m_foldingRegionId = 0; + quint16 m_formatId = 0; +}; +} + +#endif diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp new file mode 100644 index 0000000000..c48753bf0c --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp @@ -0,0 +1,663 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + Copyright (C) 2018 Christoph Cullmann <cullmann@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "rule_p.h" +#include "context_p.h" +#include "definition_p.h" +#include "ksyntaxhighlighting_logging.h" +#include "xml_p.h" + +#include <QString> +#include <QXmlStreamReader> + +using namespace KSyntaxHighlighting; + +static bool isOctalChar(QChar c) +{ + return c.isNumber() && c != QLatin1Char('9') && c != QLatin1Char('8'); +} + +static bool isHexChar(QChar c) +{ + return c.isNumber() + || c == QLatin1Char('a') || c == QLatin1Char('A') + || c == QLatin1Char('b') || c == QLatin1Char('B') + || c == QLatin1Char('c') || c == QLatin1Char('C') + || c == QLatin1Char('d') || c == QLatin1Char('D') + || c == QLatin1Char('e') || c == QLatin1Char('E') + || c == QLatin1Char('f') || c == QLatin1Char('F'); +} + +static int matchEscapedChar(const QString &text, int offset) +{ + if (text.at(offset) != QLatin1Char('\\') || text.size() < offset + 2) + return offset; + + const auto c = text.at(offset + 1); + static const auto controlChars = QStringLiteral("abefnrtv\"'?\\"); + if (controlChars.contains(c)) + return offset + 2; + + if (c == QLatin1Char('x')) { // hex encoded character + auto newOffset = offset + 2; + for (int i = 0; i < 2 && newOffset + i < text.size(); ++i, ++newOffset) { + if (!isHexChar(text.at(newOffset))) + break; + } + if (newOffset == offset + 2) + return offset; + return newOffset; + } + + if (isOctalChar(c)) { // octal encoding + auto newOffset = offset + 2; + for (int i = 0; i < 2 && newOffset + i < text.size(); ++i, ++newOffset) { + if (!isOctalChar(text.at(newOffset))) + break; + } + if (newOffset == offset + 2) + return offset; + return newOffset; + } + + return offset; +} + +static QString replaceCaptures(const QString &pattern, const QStringList &captures, bool quote) +{ + auto result = pattern; + for (int i = captures.size() - 1; i >= 1; --i) { + result.replace(QLatin1Char('%') + QString::number(i), quote ? QRegularExpression::escape(captures.at(i)) : captures.at(i)); + } + return result; +} + +Definition Rule::definition() const +{ + return m_def.definition(); +} + +void Rule::setDefinition(const Definition &def) +{ + m_def = def; + + // cache for DefinitionData::wordDelimiters, is accessed VERY often + m_wordDelimiter = &DefinitionData::get(m_def.definition())->wordDelimiters; +} + +bool Rule::load(QXmlStreamReader &reader) +{ + Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement); + + m_attribute = reader.attributes().value(QStringLiteral("attribute")).toString(); + if (reader.name() != QLatin1String("IncludeRules")) // IncludeRules uses this with a different semantic + m_context.parse(reader.attributes().value(QStringLiteral("context"))); + m_firstNonSpace = Xml::attrToBool(reader.attributes().value(QStringLiteral("firstNonSpace"))); + m_lookAhead = Xml::attrToBool(reader.attributes().value(QStringLiteral("lookAhead"))); + bool colOk = false; + m_column = reader.attributes().value(QStringLiteral("column")).toInt(&colOk); + if (!colOk) + m_column = -1; + + auto regionName = reader.attributes().value(QLatin1String("beginRegion")); + if (!regionName.isEmpty()) + m_beginRegion = FoldingRegion(FoldingRegion::Begin, DefinitionData::get(m_def.definition())->foldingRegionId(regionName.toString())); + regionName = reader.attributes().value(QLatin1String("endRegion")); + if (!regionName.isEmpty()) + m_endRegion = FoldingRegion(FoldingRegion::End, DefinitionData::get(m_def.definition())->foldingRegionId(regionName.toString())); + + auto result = doLoad(reader); + + if (m_lookAhead && m_context.isStay()) + result = false; + + // be done with this rule, skip all subelements, e.g. no longer supported sub-rules + reader.skipCurrentElement(); + return result; +} + +void Rule::resolveContext() +{ + m_context.resolve(m_def.definition()); +} + +void Rule::resolveAttributeFormat(Context *lookupContext) +{ + /** + * try to get our format from the definition we stem from + */ + if (!m_attribute.isEmpty()) { + m_attributeFormat = DefinitionData::get(definition())->formatByName(m_attribute); + if (!m_attributeFormat.isValid()) { + qCWarning(Log) << "Rule: Unknown format" << m_attribute << "in context" << lookupContext->name() << "of definition" << definition().name(); + } + } +} + +bool Rule::doLoad(QXmlStreamReader& reader) +{ + Q_UNUSED(reader); + return true; +} + +Rule::Ptr Rule::create(const QStringRef& name) +{ + Rule *rule = nullptr; + if (name == QLatin1String("AnyChar")) + rule = new AnyChar; + else if (name == QLatin1String("DetectChar")) + rule = new DetectChar; + else if (name == QLatin1String("Detect2Chars")) + rule = new Detect2Char; + else if (name == QLatin1String("DetectIdentifier")) + rule = new DetectIdentifier; + else if (name == QLatin1String("DetectSpaces")) + rule = new DetectSpaces; + else if (name == QLatin1String("Float")) + rule = new Float; + else if (name == QLatin1String("Int")) + rule = new Int; + else if (name == QLatin1String("HlCChar")) + rule = new HlCChar; + else if (name == QLatin1String("HlCHex")) + rule = new HlCHex; + else if (name == QLatin1String("HlCOct")) + rule = new HlCOct; + else if (name == QLatin1String("HlCStringChar")) + rule = new HlCStringChar; + else if (name == QLatin1String("IncludeRules")) + rule = new IncludeRules; + else if (name == QLatin1String("keyword")) + rule = new KeywordListRule; + else if (name == QLatin1String("LineContinue")) + rule = new LineContinue; + else if (name == QLatin1String("RangeDetect")) + rule = new RangeDetect; + else if (name == QLatin1String("RegExpr")) + rule = new RegExpr; + else if (name == QLatin1String("StringDetect")) + rule = new StringDetect; + else if (name == QLatin1String("WordDetect")) + rule = new WordDetect; + else + qCWarning(Log) << "Unknown rule type:" << name; + + return Ptr(rule); +} + +bool Rule::isWordDelimiter(QChar c) const +{ + // perf tells contains is MUCH faster than binary search here, very short array + return m_wordDelimiter.contains(c); +} + + +bool AnyChar::doLoad(QXmlStreamReader& reader) +{ + m_chars = reader.attributes().value(QStringLiteral("String")).toString(); + if (m_chars.size() == 1) + qCDebug(Log) << "AnyChar rule with just one char: use DetectChar instead."; + return !m_chars.isEmpty(); +} + +MatchResult AnyChar::doMatch(const QString& text, int offset, const QStringList&) const +{ + if (m_chars.contains(text.at(offset))) + return offset + 1; + return offset; +} + + +bool DetectChar::doLoad(QXmlStreamReader& reader) +{ + const auto s = reader.attributes().value(QStringLiteral("char")); + if (s.isEmpty()) + return false; + m_char = s.at(0); + m_dynamic = Xml::attrToBool(reader.attributes().value(QStringLiteral("dynamic"))); + if (m_dynamic) { + m_captureIndex = m_char.digitValue(); + } + return true; +} + +MatchResult DetectChar::doMatch(const QString& text, int offset, const QStringList &captures) const +{ + if (m_dynamic) { + if (m_captureIndex == 0 || captures.size() <= m_captureIndex || captures.at(m_captureIndex).isEmpty()) + return offset; + if (text.at(offset) == captures.at(m_captureIndex).at(0)) + return offset + 1; + return offset; + } + + if (text.at(offset) == m_char) + return offset + 1; + return offset; +} + + +bool Detect2Char::doLoad(QXmlStreamReader& reader) +{ + const auto s1 = reader.attributes().value(QStringLiteral("char")); + const auto s2 = reader.attributes().value(QStringLiteral("char1")); + if (s1.isEmpty() || s2.isEmpty()) + return false; + m_char1 = s1.at(0); + m_char2 = s2.at(0); + return true; +} + +MatchResult Detect2Char::doMatch(const QString& text, int offset, const QStringList &) const +{ + if (text.size() - offset < 2) + return offset; + if (text.at(offset) == m_char1 && text.at(offset + 1) == m_char2) + return offset + 2; + return offset; +} + + +MatchResult DetectIdentifier::doMatch(const QString& text, int offset, const QStringList&) const +{ + if (!text.at(offset).isLetter() && text.at(offset) != QLatin1Char('_')) + return offset; + + for (int i = offset + 1; i < text.size(); ++i) { + const auto c = text.at(i); + if (!c.isLetterOrNumber() && c != QLatin1Char('_')) + return i; + } + + return text.size(); +} + + +MatchResult DetectSpaces::doMatch(const QString& text, int offset, const QStringList&) const +{ + while(offset < text.size() && text.at(offset).isSpace()) + ++offset; + return offset; +} + + +MatchResult Float::doMatch(const QString& text, int offset, const QStringList&) const +{ + if (offset > 0 && !isWordDelimiter(text.at(offset - 1))) + return offset; + + auto newOffset = offset; + while (newOffset < text.size() && text.at(newOffset).isDigit()) + ++newOffset; + + if (newOffset >= text.size() || text.at(newOffset) != QLatin1Char('.')) + return offset; + ++newOffset; + + while (newOffset < text.size() && text.at(newOffset).isDigit()) + ++newOffset; + + if (newOffset == offset + 1) // we only found a decimal point + return offset; + + auto expOffset = newOffset; + if (expOffset >= text.size() || (text.at(expOffset) != QLatin1Char('e') && text.at(expOffset) != QLatin1Char('E'))) + return newOffset; + ++expOffset; + + if (expOffset < text.size() && (text.at(expOffset) == QLatin1Char('+') || text.at(expOffset) == QLatin1Char('-'))) + ++expOffset; + bool foundExpDigit = false; + while (expOffset < text.size() && text.at(expOffset).isDigit()) { + ++expOffset; + foundExpDigit = true; + } + + if (!foundExpDigit) + return newOffset; + return expOffset; +} + + +MatchResult HlCChar::doMatch(const QString& text, int offset, const QStringList&) const +{ + if (text.size() < offset + 3) + return offset; + + if (text.at(offset) != QLatin1Char('\'') || text.at(offset + 1) == QLatin1Char('\'')) + return offset; + + auto newOffset = matchEscapedChar(text, offset + 1); + if (newOffset == offset + 1) { + if (text.at(newOffset) == QLatin1Char('\\')) + return offset; + else + ++newOffset; + } + if (newOffset >= text.size()) + return offset; + + if (text.at(newOffset) == QLatin1Char('\'')) + return newOffset + 1; + + return offset; +} + + +MatchResult HlCHex::doMatch(const QString& text, int offset, const QStringList&) const +{ + if (offset > 0 && !isWordDelimiter(text.at(offset - 1))) + return offset; + + if (text.size() < offset + 3) + return offset; + + if (text.at(offset) != QLatin1Char('0') || (text.at(offset + 1) != QLatin1Char('x') && text.at(offset + 1) != QLatin1Char('X'))) + return offset; + + if (!isHexChar(text.at(offset + 2))) + return offset; + + offset += 3; + while (offset < text.size() && isHexChar(text.at(offset))) + ++offset; + + // TODO Kate matches U/L suffix, QtC does not? + + return offset; +} + + +MatchResult HlCOct::doMatch(const QString& text, int offset, const QStringList&) const +{ + if (offset > 0 && !isWordDelimiter(text.at(offset - 1))) + return offset; + + if (text.size() < offset + 2) + return offset; + + if (text.at(offset) != QLatin1Char('0')) + return offset; + + if (!isOctalChar(text.at(offset + 1))) + return offset; + + offset += 2; + while (offset < text.size() && isOctalChar(text.at(offset))) + ++offset; + + return offset; +} + + +MatchResult HlCStringChar::doMatch(const QString& text, int offset, const QStringList&) const +{ + return matchEscapedChar(text, offset); +} + + +QString IncludeRules::contextName() const +{ + return m_contextName; +} + +QString IncludeRules::definitionName() const +{ + return m_defName; +} + +bool IncludeRules::includeAttribute() const +{ + return m_includeAttribute; +} + +bool IncludeRules::doLoad(QXmlStreamReader& reader) +{ + const auto s = reader.attributes().value(QLatin1String("context")); + const auto split = s.split(QLatin1String("##"), QString::KeepEmptyParts); + if (split.isEmpty()) + return false; + m_contextName = split.at(0).toString(); + if (split.size() > 1) + m_defName = split.at(1).toString(); + m_includeAttribute = Xml::attrToBool(reader.attributes().value(QLatin1String("includeAttrib"))); + + return !m_contextName.isEmpty() || !m_defName.isEmpty(); +} + +MatchResult IncludeRules::doMatch(const QString& text, int offset, const QStringList&) const +{ + Q_UNUSED(text); + qCWarning(Log) << "Unresolved include rule for" << m_contextName << "##" << m_defName; + return offset; +} + + +MatchResult Int::doMatch(const QString& text, int offset, const QStringList &) const +{ + if (offset > 0 && !isWordDelimiter(text.at(offset - 1))) + return offset; + + while(offset < text.size() && text.at(offset).isDigit()) + ++offset; + return offset; +} + + +bool KeywordListRule::doLoad(QXmlStreamReader& reader) +{ + /** + * get our keyword list, if not found => bail out + */ + auto defData = DefinitionData::get(definition()); + m_keywordList = defData->keywordList(reader.attributes().value(QLatin1String("String")).toString()); + if (!m_keywordList) { + return false; + } + + /** + * we might overwrite the case sensitivity + * then we need to init the list for lookup of that sensitivity setting + */ + if (reader.attributes().hasAttribute(QLatin1String("insensitive"))) { + m_hasCaseSensitivityOverride = true; + m_caseSensitivityOverride = Xml::attrToBool(reader.attributes().value(QLatin1String("insensitive"))) ? + Qt::CaseInsensitive : Qt::CaseSensitive; + m_keywordList->initLookupForCaseSensitivity(m_caseSensitivityOverride); + } else { + m_hasCaseSensitivityOverride = false; + } + + return !m_keywordList->isEmpty(); +} + +MatchResult KeywordListRule::doMatch(const QString& text, int offset, const QStringList&) const +{ + auto newOffset = offset; + while (text.size() > newOffset && !isWordDelimiter(text.at(newOffset))) + ++newOffset; + if (newOffset == offset) + return offset; + + if (m_hasCaseSensitivityOverride) { + if (m_keywordList->contains(text.midRef(offset, newOffset - offset), m_caseSensitivityOverride)) + return newOffset; + } else { + if (m_keywordList->contains(text.midRef(offset, newOffset - offset))) + return newOffset; + } + + // we don't match, but we can skip until newOffset as we can't start a keyword in-between + return MatchResult(offset, newOffset); +} + + +bool LineContinue::doLoad(QXmlStreamReader& reader) +{ + const auto s = reader.attributes().value(QStringLiteral("char")); + if (s.isEmpty()) + m_char = QLatin1Char('\\'); + else + m_char = s.at(0); + return true; +} + +MatchResult LineContinue::doMatch(const QString& text, int offset, const QStringList&) const +{ + if (offset == text.size() - 1 && text.at(offset) == m_char) + return offset + 1; + return offset; +} + + +bool RangeDetect::doLoad(QXmlStreamReader& reader) +{ + const auto s1 = reader.attributes().value(QStringLiteral("char")); + const auto s2 = reader.attributes().value(QStringLiteral("char1")); + if (s1.isEmpty() || s2.isEmpty()) + return false; + m_begin = s1.at(0); + m_end = s2.at(0); + return true; +} + +MatchResult RangeDetect::doMatch(const QString& text, int offset, const QStringList&) const +{ + if (text.size() - offset < 2) + return offset; + if (text.at(offset) != m_begin) + return offset; + + auto newOffset = offset + 1; + while (newOffset < text.size()) { + if (text.at(newOffset) == m_end) + return newOffset + 1; + ++newOffset; + } + return offset; +} + +bool RegExpr::doLoad(QXmlStreamReader& reader) +{ + m_regexp.setPattern(reader.attributes().value(QStringLiteral("String")).toString()); + + const auto isMinimal = Xml::attrToBool(reader.attributes().value(QStringLiteral("minimal"))); + const auto isCaseInsensitive = Xml::attrToBool(reader.attributes().value(QStringLiteral("insensitive"))); + m_regexp.setPatternOptions( + (isMinimal ? QRegularExpression::InvertedGreedinessOption : QRegularExpression::NoPatternOption) | + (isCaseInsensitive ? QRegularExpression::CaseInsensitiveOption : QRegularExpression::NoPatternOption)); + + // optimize the pattern for the non-dynamic case, we use them OFTEN + m_dynamic = Xml::attrToBool(reader.attributes().value(QStringLiteral("dynamic"))); + if (!m_dynamic) { + m_regexp.optimize(); + } + + // always using m_regexp.isValid() would be better, but parses the regexp and thus is way too expensive for release builds + + if (Log().isDebugEnabled()) { + if (!m_regexp.isValid()) + qCDebug(Log) << "Invalid regexp:" << m_regexp.pattern(); + } + return !m_regexp.pattern().isEmpty(); +} + +MatchResult RegExpr::doMatch(const QString& text, int offset, const QStringList &captures) const +{ + /** + * for dynamic case: create new pattern with right instantiation + */ + const auto ®exp = m_dynamic ? QRegularExpression(replaceCaptures(m_regexp.pattern(), captures, true), m_regexp.patternOptions()) : m_regexp; + + /** + * match the pattern + */ + const auto result = regexp.match(text, offset, QRegularExpression::NormalMatch, QRegularExpression::DontCheckSubjectStringMatchOption); + if (result.capturedStart() == offset) { + /** + * we only need to compute the captured texts if we have real capture groups + * highlightings should only address %1..%.., see e.g. replaceCaptures + * DetectChar ignores %0, too + */ + if (result.lastCapturedIndex() > 0) { + return MatchResult(offset + result.capturedLength(), result.capturedTexts()); + } + + /** + * else: ignore the implicit 0 group we always capture, no need to allocate stuff for that + */ + return MatchResult(offset + result.capturedLength()); + } + + /** + * no match + */ + return MatchResult(offset, result.capturedStart()); +} + + +bool StringDetect::doLoad(QXmlStreamReader& reader) +{ + m_string = reader.attributes().value(QStringLiteral("String")).toString(); + m_caseSensitivity = Xml::attrToBool(reader.attributes().value(QStringLiteral("insensitive"))) ? Qt::CaseInsensitive : Qt::CaseSensitive; + m_dynamic = Xml::attrToBool(reader.attributes().value(QStringLiteral("dynamic"))); + return !m_string.isEmpty(); +} + +MatchResult StringDetect::doMatch(const QString& text, int offset, const QStringList &captures) const +{ + /** + * for dynamic case: create new pattern with right instantiation + */ + const auto &pattern = m_dynamic ? replaceCaptures(m_string, captures, false) : m_string; + + if (text.midRef(offset, pattern.size()).compare(pattern, m_caseSensitivity) == 0) + return offset + pattern.size(); + return offset; +} + + +bool WordDetect::doLoad(QXmlStreamReader& reader) +{ + m_word = reader.attributes().value(QStringLiteral("String")).toString(); + m_caseSensitivity = Xml::attrToBool(reader.attributes().value(QStringLiteral("insensitive"))) ? Qt::CaseInsensitive : Qt::CaseSensitive; + return !m_word.isEmpty(); +} + +MatchResult WordDetect::doMatch(const QString& text, int offset, const QStringList &) const +{ + if (text.size() - offset < m_word.size()) + return offset; + + if (offset > 0 && !isWordDelimiter(text.at(offset - 1))) + return offset; + + if (text.midRef(offset, m_word.size()).compare(m_word, m_caseSensitivity) != 0) + return offset; + + if (text.size() == offset + m_word.size() || isWordDelimiter(text.at(offset + m_word.size()))) + return offset + m_word.size(); + + return offset; +} diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/rule_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/rule_p.h new file mode 100644 index 0000000000..538fdeda8a --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/rule_p.h @@ -0,0 +1,291 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_RULE_P_H +#define KSYNTAXHIGHLIGHTING_RULE_P_H + +#include "contextswitch_p.h" +#include "definition.h" +#include "definitionref_p.h" +#include "foldingregion.h" +#include "format.h" +#include "keywordlist_p.h" +#include "matchresult_p.h" + +#include <QRegularExpression> +#include <QString> +#include <QVector> + +#include <memory> + +QT_BEGIN_NAMESPACE +class QXmlStreamReader; +QT_END_NAMESPACE + +namespace KSyntaxHighlighting { + +class Rule +{ +public: + Rule() = default; + virtual ~Rule() = default; + + typedef std::shared_ptr<Rule> Ptr; + + Definition definition() const; + void setDefinition(const Definition &def); + + const Format &attributeFormat() const + { + return m_attributeFormat; + } + + const ContextSwitch &context() const + { + return m_context; + } + + bool isLookAhead() const + { + return m_lookAhead; + } + + bool firstNonSpace() const + { + return m_firstNonSpace; + } + + int requiredColumn() const + { + return m_column; + } + + const FoldingRegion &beginRegion() const + { + return m_beginRegion; + } + + const FoldingRegion &endRegion() const + { + return m_endRegion; + } + + bool load(QXmlStreamReader &reader); + void resolveContext(); + void resolveAttributeFormat(Context *lookupContext); + + virtual MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const = 0; + + static Rule::Ptr create(const QStringRef &name); + +protected: + virtual bool doLoad(QXmlStreamReader &reader); + + bool isWordDelimiter(QChar c) const; + +private: + Q_DISABLE_COPY(Rule) + + DefinitionRef m_def; + QString m_attribute; + Format m_attributeFormat; + ContextSwitch m_context; + int m_column = -1; + FoldingRegion m_beginRegion; + FoldingRegion m_endRegion; + bool m_firstNonSpace = false; + bool m_lookAhead = false; + + // cache for DefinitionData::wordDelimiters, is accessed VERY often + QStringRef m_wordDelimiter; +}; + + +class AnyChar : public Rule +{ +protected: + bool doLoad(QXmlStreamReader & reader) override; + MatchResult doMatch(const QString & text, int offset, const QStringList&) const override; + +private: + QString m_chars; +}; + +class DetectChar : public Rule +{ +protected: + bool doLoad(QXmlStreamReader & reader) override; + MatchResult doMatch(const QString & text, int offset, const QStringList &captures) const override; + +private: + QChar m_char; + bool m_dynamic = false; + int m_captureIndex = 0; +}; + +class Detect2Char : public Rule +{ +protected: + bool doLoad(QXmlStreamReader & reader) override; + MatchResult doMatch(const QString & text, int offset, const QStringList &captures) const override; + +private: + QChar m_char1; + QChar m_char2; +}; + +class DetectIdentifier : public Rule +{ +protected: + MatchResult doMatch(const QString & text, int offset, const QStringList&) const override; +}; + +class DetectSpaces : public Rule +{ +protected: + MatchResult doMatch(const QString & text, int offset, const QStringList&) const override; +}; + +class Float : public Rule +{ +protected: + MatchResult doMatch(const QString & text, int offset, const QStringList&) const override; +}; + +class IncludeRules : public Rule +{ +public: + QString contextName() const; + QString definitionName() const; + bool includeAttribute() const; + +protected: + bool doLoad(QXmlStreamReader & reader) override; + MatchResult doMatch(const QString & text, int offset, const QStringList&) const override; + +private: + QString m_contextName; + QString m_defName; + bool m_includeAttribute; +}; + +class Int : public Rule +{ +protected: + MatchResult doMatch(const QString & text, int offset, const QStringList &captures) const override; +}; + +class HlCChar : public Rule +{ +protected: + MatchResult doMatch(const QString & text, int offset, const QStringList&) const override; +}; + +class HlCHex : public Rule +{ +protected: + MatchResult doMatch(const QString & text, int offset, const QStringList&) const override; +}; + +class HlCOct : public Rule +{ +protected: + MatchResult doMatch(const QString & text, int offset, const QStringList&) const override; +}; + +class HlCStringChar : public Rule +{ +protected: + MatchResult doMatch(const QString & text, int offset, const QStringList&) const override; +}; + +class KeywordListRule : public Rule +{ +protected: + bool doLoad(QXmlStreamReader & reader) override; + MatchResult doMatch(const QString & text, int offset, const QStringList&) const override; + +private: + KeywordList *m_keywordList; + bool m_hasCaseSensitivityOverride; + Qt::CaseSensitivity m_caseSensitivityOverride; +}; + +class LineContinue : public Rule +{ +protected: + bool doLoad(QXmlStreamReader & reader) override; + MatchResult doMatch(const QString & text, int offset, const QStringList&) const override; + +private: + QChar m_char; +}; + +class RangeDetect : public Rule +{ +protected: + bool doLoad(QXmlStreamReader & reader) override; + MatchResult doMatch(const QString & text, int offset, const QStringList&) const override; + +private: + QChar m_begin; + QChar m_end; +}; + +class RegExpr : public Rule +{ +protected: + bool doLoad(QXmlStreamReader & reader) override; + MatchResult doMatch(const QString & text, int offset, const QStringList &captures) const override; + +private: + QRegularExpression m_regexp; + bool m_dynamic = false; +}; + +class StringDetect : public Rule +{ +protected: + bool doLoad(QXmlStreamReader & reader) override; + MatchResult doMatch(const QString & text, int offset, const QStringList &captures) const override; + +private: + QString m_string; + Qt::CaseSensitivity m_caseSensitivity; + bool m_dynamic = false; +}; + +class WordDetect : public Rule +{ +protected: + bool doLoad(QXmlStreamReader & reader) override; + MatchResult doMatch(const QString & text, int offset, const QStringList &captures) const override; + +private: + QString m_word; + Qt::CaseSensitivity m_caseSensitivity; +}; + +} + +#endif // KSYNTAXHIGHLIGHTING_RULE_P_H diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/state.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/state.cpp new file mode 100644 index 0000000000..f970e13f8b --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/state.cpp @@ -0,0 +1,123 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + Copyright (C) 2018 Christoph Cullmann <cullmann@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "state.h" +#include "state_p.h" + +#include "context_p.h" + +#include <QStringList> + +using namespace KSyntaxHighlighting; + +StateData* StateData::get(State &state) +{ + state.d.detach(); + return state.d.data(); +} + +bool StateData::isEmpty() const +{ + return m_contextStack.isEmpty(); +} + +void StateData::clear() +{ + m_contextStack.clear(); +} + +int StateData::size() const +{ + return m_contextStack.size(); +} + +void StateData::push(Context *context, const QStringList &captures) +{ + Q_ASSERT(context); + m_contextStack.push_back(qMakePair(context, captures)); +} + +bool StateData::pop(int popCount) +{ + // nop if nothing to pop + if (popCount <= 0) { + return true; + } + + // keep the initial context alive in any case + Q_ASSERT(!isEmpty()); + const bool initialContextSurvived = m_contextStack.size() > popCount; + m_contextStack.resize(std::max(1, m_contextStack.size() - popCount)); + return initialContextSurvived; +} + +Context* StateData::topContext() const +{ + Q_ASSERT(!isEmpty()); + return m_contextStack.last().first; +} + +const QStringList &StateData::topCaptures() const +{ + Q_ASSERT(!isEmpty()); + return m_contextStack.last().second; +} + +State::State() : + d(new StateData) +{ +} + +State::State(const State &other) : + d(other.d) +{ +} + +State::~State() +{ +} + +State& State::operator=(const State &other) +{ + d = other.d; + return *this; +} + +bool State::operator==(const State &other) const +{ + // use pointer equal as shortcut for shared states + return (d == other.d) || (d->m_contextStack == other.d->m_contextStack && d->m_defRef == other.d->m_defRef); +} + +bool State::operator!=(const State &other) const +{ + return !(*this == other); +} + +bool State::indentationBasedFoldingEnabled() const +{ + if (d->m_contextStack.isEmpty()) + return false; + return d->m_contextStack.last().first->indentationBasedFoldingEnabled(); +} diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/state.h b/src/libs/3rdparty/syntax-highlighting/src/lib/state.h new file mode 100644 index 0000000000..fce4bc71e8 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/state.h @@ -0,0 +1,86 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_STATE_H +#define KSYNTAXHIGHLIGHTING_STATE_H + +#include "ksyntaxhighlighting_export.h" + +#include <QExplicitlySharedDataPointer> +#include <QTypeInfo> + +namespace KSyntaxHighlighting { + +class StateData; + +/** Opaque handle to the state of the highlighting engine. + * This needs to be fed into AbstractHighlighter for every line of text + * and allows concrete highlighter implementations to store state per + * line for fast re-highlighting of specific lines (e.g. during editing). + * + * @since 5.28 + */ +class KSYNTAXHIGHLIGHTING_EXPORT State +{ +public: + /** Creates an initial state, ie. what should be used for the first line + * in a document. + */ + State(); + State(const State &other); + ~State(); + State& operator=(const State &rhs); + + /** Compares two states for equality. + * For two equal states and identical text input, AbstractHighlighter + * guarantees to produce equal results. This can be used to only + * re-highlight as many lines as necessary during editing. + */ + bool operator==(const State &other) const; + /** Compares two states for inequality. + * This is the opposite of operator==(). + */ + bool operator!=(const State &other) const; + + /** + * Returns whether or not indentation-based folding is enabled in this state. + * When using a Definition with indentation-based folding, use + * this method to check if indentation-based folding has been + * suspended in the current line. + * + * @see Definition::indentationBasedFoldingEnabled() + */ + bool indentationBasedFoldingEnabled() const; + +private: + friend class StateData; + QExplicitlySharedDataPointer<StateData> d; +}; + +} + +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(KSyntaxHighlighting::State, Q_MOVABLE_TYPE); +QT_END_NAMESPACE + +#endif // KSYNTAXHIGHLIGHTING_STATE_H diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/state_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/state_p.h new file mode 100644 index 0000000000..a99192b4c6 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/state_p.h @@ -0,0 +1,81 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + Copyright (C) 2018 Christoph Cullmann <cullmann@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_STATE_P_H +#define KSYNTAXHIGHLIGHTING_STATE_P_H + +#include <QSharedData> +#include <QVector> + +#include "definitionref_p.h" + +QT_BEGIN_NAMESPACE +class QStringList; +QT_END_NAMESPACE + +namespace KSyntaxHighlighting +{ + +class Context; + +class StateData : public QSharedData +{ + friend class State; + friend class AbstractHighlighter; + +public: + StateData() = default; + static StateData* get(State &state); + + bool isEmpty() const; + void clear(); + int size() const; + void push(Context *context, const QStringList &captures); + + /** + * Pop the number of elements given from the top of the current stack. + * Will not pop the initial element. + * @param popCount number of elements to pop + * @return false if one has tried to pop the initial context, else true + */ + bool pop(int popCount); + + Context* topContext() const; + const QStringList &topCaptures() const; + +private: + /** + * weak reference to the used definition to filter out invalid states + */ + DefinitionRef m_defRef; + + /** + * the context stack combines the active context + valid captures + */ + QVector<QPair<Context *, QStringList>> m_contextStack; +}; + +} + +#endif diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp new file mode 100644 index 0000000000..2bb61a7ae6 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp @@ -0,0 +1,198 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "syntaxhighlighter.h" +#include "abstracthighlighter_p.h" +#include "definition.h" +#include "foldingregion.h" +#include "format.h" +#include "state.h" +#include "theme.h" + +#include <QDebug> + +Q_DECLARE_METATYPE(QTextBlock) + +using namespace KSyntaxHighlighting; + +namespace KSyntaxHighlighting { +class TextBlockUserData : public QTextBlockUserData +{ +public: + State state; + QVector<FoldingRegion> foldingRegions; +}; + +class SyntaxHighlighterPrivate : public AbstractHighlighterPrivate +{ +public: + static FoldingRegion foldingRegion(const QTextBlock &startBlock); + QVector<FoldingRegion> foldingRegions; +}; + +} + +FoldingRegion SyntaxHighlighterPrivate::foldingRegion(const QTextBlock& startBlock) +{ + const auto data = dynamic_cast<TextBlockUserData*>(startBlock.userData()); + if (!data) + return FoldingRegion(); + for (int i = data->foldingRegions.size() - 1; i >= 0; --i) { + if (data->foldingRegions.at(i).type() == FoldingRegion::Begin) + return data->foldingRegions.at(i); + } + return FoldingRegion(); +} + +SyntaxHighlighter::SyntaxHighlighter(QObject* parent) : + QSyntaxHighlighter(parent), + AbstractHighlighter(new SyntaxHighlighterPrivate) +{ + qRegisterMetaType<QTextBlock>(); +} + +SyntaxHighlighter::SyntaxHighlighter(QTextDocument *document) : + QSyntaxHighlighter(document), + AbstractHighlighter(new SyntaxHighlighterPrivate) +{ + qRegisterMetaType<QTextBlock>(); +} + +SyntaxHighlighter::~SyntaxHighlighter() +{ +} + +void SyntaxHighlighter::setDefinition(const Definition& def) +{ + const auto needsRehighlight = definition() != def; + AbstractHighlighter::setDefinition(def); + if (needsRehighlight) + rehighlight(); +} + +bool SyntaxHighlighter::startsFoldingRegion(const QTextBlock &startBlock) const +{ + return SyntaxHighlighterPrivate::foldingRegion(startBlock).type() == FoldingRegion::Begin; +} + +QTextBlock SyntaxHighlighter::findFoldingRegionEnd(const QTextBlock &startBlock) const +{ + const auto region = SyntaxHighlighterPrivate::foldingRegion(startBlock); + + auto block = startBlock; + int depth = 1; + while (block.isValid()) { + block = block.next(); + const auto data = dynamic_cast<TextBlockUserData*>(block.userData()); + if (!data) + continue; + for (auto it = data->foldingRegions.constBegin(); it != data->foldingRegions.constEnd(); ++it) { + if ((*it).id() != region.id()) + continue; + if ((*it).type() == FoldingRegion::End) + --depth; + else if ((*it).type() == FoldingRegion::Begin) + ++depth; + if (depth == 0) + return block; + } + } + + return QTextBlock(); +} + +void SyntaxHighlighter::highlightBlock(const QString& text) +{ + Q_D(SyntaxHighlighter); + + State state; + if (currentBlock().position() > 0) { + const auto prevBlock = currentBlock().previous(); + const auto prevData = dynamic_cast<TextBlockUserData*>(prevBlock.userData()); + if (prevData) + state = prevData->state; + } + d->foldingRegions.clear(); + state = highlightLine(text, state); + + auto data = dynamic_cast<TextBlockUserData*>(currentBlockUserData()); + if (!data) { // first time we highlight this + data = new TextBlockUserData; + data->state = state; + data->foldingRegions = d->foldingRegions; + setCurrentBlockUserData(data); + return; + } + + if (data->state == state && data->foldingRegions == d->foldingRegions) // we ended up in the same state, so we are done here + return; + data->state = state; + data->foldingRegions = d->foldingRegions; + + const auto nextBlock = currentBlock().next(); + if (nextBlock.isValid()) + QMetaObject::invokeMethod(this, "rehighlightBlock", Qt::QueuedConnection, Q_ARG(QTextBlock, nextBlock)); +} + +void SyntaxHighlighter::applyFormat(int offset, int length, const KSyntaxHighlighting::Format& format) +{ + if (format.isDefaultTextStyle(theme()) || length == 0) + return; + + QTextCharFormat tf; + if (format.hasTextColor(theme())) + tf.setForeground(format.textColor(theme())); + if (format.hasBackgroundColor(theme())) + tf.setBackground(format.backgroundColor(theme())); + + if (format.isBold(theme())) + tf.setFontWeight(QFont::Bold); + if (format.isItalic(theme())) + tf.setFontItalic(true); + if (format.isUnderline(theme())) + tf.setFontUnderline(true); + if (format.isStrikeThrough(theme())) + tf.setFontStrikeOut(true); + + QSyntaxHighlighter::setFormat(offset, length, tf); +} + +void SyntaxHighlighter::applyFolding(int offset, int length, FoldingRegion region) +{ + Q_UNUSED(offset); + Q_UNUSED(length); + Q_D(SyntaxHighlighter); + + if (region.type() == FoldingRegion::Begin) + d->foldingRegions.push_back(region); + + if (region.type() == FoldingRegion::End) { + for (int i = d->foldingRegions.size() - 1; i >= 0; --i) { + if (d->foldingRegions.at(i).id() != region.id() || d->foldingRegions.at(i).type() != FoldingRegion::Begin) + continue; + d->foldingRegions.remove(i); + return; + } + d->foldingRegions.push_back(region); + } +} diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.h b/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.h new file mode 100644 index 0000000000..f5d2a5e219 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.h @@ -0,0 +1,85 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_QSYNTAXHIGHLIGHTER_H +#define KSYNTAXHIGHLIGHTING_QSYNTAXHIGHLIGHTER_H + +#include "ksyntaxhighlighting_export.h" + +#include "abstracthighlighter.h" + +#include <QSyntaxHighlighter> + +namespace KSyntaxHighlighting { + +class SyntaxHighlighterPrivate; + +/** A QSyntaxHighlighter implementation for use with QTextDocument. + * This supports partial re-highlighting during editing and + * tracks syntax-based code folding regions. + * + * @since 5.28 + */ +class KSYNTAXHIGHLIGHTING_EXPORT SyntaxHighlighter : public QSyntaxHighlighter, public AbstractHighlighter +{ + Q_OBJECT +public: + explicit SyntaxHighlighter(QObject *parent = nullptr); + explicit SyntaxHighlighter(QTextDocument *document); + ~SyntaxHighlighter() override; + + void setDefinition(const Definition &def) override; + + /** Returns whether there is a folding region beginning at @p startBlock. + * This only considers syntax-based folding regions, + * not indention-based ones as e.g. found in Python. + * + * @see findFoldingRegionEnd + */ + bool startsFoldingRegion(const QTextBlock &startBlock) const; + + /** Finds the end of the folding region starting at @p startBlock. + * If multiple folding regions begin at @p startBlock, the end of + * the last/innermost one is returned. + * This returns an invalid block if no folding region end is found, + * which typically indicates an unterminated region and thus folding + * until the document end. + * This method performs a sequential search starting at @p startBlock + * for the matching folding region end, which is a potentially expensive + * operation. + * + * @see startsFoldingRegion + */ + QTextBlock findFoldingRegionEnd(const QTextBlock &startBlock) const; + +protected: + void highlightBlock(const QString & text) override; + void applyFormat(int offset, int length, const Format &format) override; + void applyFolding(int offset, int length, FoldingRegion region) override; + +private: + Q_DECLARE_PRIVATE_D(AbstractHighlighter::d_ptr, SyntaxHighlighter) +}; +} + +#endif // KSYNTAXHIGHLIGHTING_QSYNTAXHIGHLIGHTER_H diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/textstyledata_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/textstyledata_p.h new file mode 100644 index 0000000000..40c5ef679e --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/textstyledata_p.h @@ -0,0 +1,63 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_TEXTSTYLEDATA_P_H +#define KSYNTAXHIGHLIGHTING_TEXTSTYLEDATA_P_H + +#include <QColor> + +namespace KSyntaxHighlighting { + +class TextStyleData +{ +public: + // Constructor initializing all data. + TextStyleData() + : bold(false) + , italic(false) + , underline(false) + , strikeThrough(false) + , hasBold(false) + , hasItalic(false) + , hasUnderline(false) + , hasStrikeThrough(false) + {} + + QRgb textColor = 0x0; + QRgb backgroundColor = 0x0; + QRgb selectedTextColor = 0x0; + QRgb selectedBackgroundColor = 0x0; + bool bold :1; + bool italic :1; + bool underline :1; + bool strikeThrough :1; + + bool hasBold :1; + bool hasItalic :1; + bool hasUnderline :1; + bool hasStrikeThrough :1; +}; + +} + +#endif diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/theme.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/theme.cpp new file mode 100644 index 0000000000..57f62ef6ab --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/theme.cpp @@ -0,0 +1,124 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "theme.h" +#include "themedata_p.h" + +#include <QCoreApplication> + +using namespace KSyntaxHighlighting; + +Theme::Theme() +{ +} + +Theme::Theme(const Theme ©) +{ + m_data = copy.m_data; +} + +Theme::Theme(ThemeData* data) + : m_data(data) +{ +} + +Theme::~Theme() +{ +} + +Theme &Theme::operator=(const Theme &other) +{ + m_data = other.m_data; + return *this; +} + +bool Theme::isValid() const +{ + return m_data.data(); +} + +QString Theme::name() const +{ + return m_data ? m_data->name() : QString(); +} + +QString Theme::translatedName() const +{ + return m_data ? QCoreApplication::instance()->translate("Theme", m_data->name().toUtf8().constData()) + : QString(); +} + +bool Theme::isReadOnly() const +{ + return m_data ? m_data->isReadOnly() : false; +} + +QString Theme::filePath() const +{ + return m_data ? m_data->filePath() : QString(); +} + +QRgb Theme::textColor(TextStyle style) const +{ + return m_data ? m_data->textColor(style) : 0; +} + +QRgb Theme::selectedTextColor(TextStyle style) const +{ + return m_data ? m_data->selectedTextColor(style) : 0; +} + +QRgb Theme::backgroundColor(TextStyle style) const +{ + return m_data ? m_data->backgroundColor(style) : 0; +} + +QRgb Theme::selectedBackgroundColor(TextStyle style) const +{ + return m_data ? m_data->selectedBackgroundColor(style) : 0; +} + +bool Theme::isBold(TextStyle style) const +{ + return m_data ? m_data->isBold(style) : false; +} + +bool Theme::isItalic(TextStyle style) const +{ + return m_data ? m_data->isItalic(style) : false; +} + +bool Theme::isUnderline(TextStyle style) const +{ + return m_data ? m_data->isUnderline(style) : false; +} + +bool Theme::isStrikeThrough(TextStyle style) const +{ + return m_data ? m_data->isStrikeThrough(style) : false; +} + +QRgb Theme::editorColor(EditorColorRole role) const +{ + return m_data ? m_data->editorColor(role) : 0; +} diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/theme.h b/src/libs/3rdparty/syntax-highlighting/src/lib/theme.h new file mode 100644 index 0000000000..adb8431f6a --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/theme.h @@ -0,0 +1,378 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_THEME_H +#define KSYNTAXHIGHLIGHTING_THEME_H + +#include "ksyntaxhighlighting_export.h" + +#include <QColor> +#include <QExplicitlySharedDataPointer> +#include <qobjectdefs.h> +#include <QTypeInfo> + +namespace KSyntaxHighlighting { + +class ThemeData; +class RepositoryPrivate; + +/** + * Color theme definition used for highlighting. + * + * @section theme_intro Introduction + * + * The Theme provides a full color theme for painting the highlighted text. + * One Theme is defined either as a *.theme file on disk, or as a file compiled + * into the SyntaxHighlighting library by using Qt's resource system. Each + * Theme has a unique name(), including a translatedName() if put into the UI. + * Themes shipped by default are typically read-only, see isReadOnly(). + * + * A Theme defines two sets of colors: + * - Text colors, including foreground and background colors, colors for + * selected text, and properties such as bold and italic. These colors are + * used e.g. by the SyntaxHighlighter. + * - Editor colors, including a background color for the entire editor widget, + * the line number color, code folding colors, etc. + * + * @section theme_text_colors Text Colors and the Class Format + * + * The text colors are used for syntax highlighting. + * // TODO: elaborate more and explain relation to Format class + * + * @section theme_editor_colors Editor Colors + * + * If you want to use the SyntaxHighlighting framework to write your own text + * editor, you also need to paint the background of the editing widget. In + * addition, the editor may support showing line numbers, a folding bar, a + * highlight for the current text line, and similar features. All these colors + * are defined in terms of the "editor colors" and accessible by calling + * editorColor() with the desired enum EditorColorRole. + * + * @section theme_access Accessing a Theme + * + * All available Theme%s are accessed through the Repository. These themes are + * typically valid themes. If you create a Theme on your own, isValid() will + * return @e false, and all colors provided by this Theme are in fact invalid + * and therefore unusable. + * + * @see Format + * @since 5.28 + */ +class KSYNTAXHIGHLIGHTING_EXPORT Theme +{ + Q_GADGET +public: + + // TODO KF6: + // - make TextStyle an enum class + // - move out of Theme into KSyntaxHighlighting + // - do the same for EditorColorRole + + /** + * Default styles that can be referenced from syntax definition XML files. + * Make sure to choose readable colors with good contrast especially in + * combination with the EditorColorRole%s. + */ + enum TextStyle { + //! Default text style for normal text and source code without + //! special highlighting. + Normal = 0, + //! Text style for language keywords. + Keyword, + //! Text style for function definitions and function calls. + Function, + //! Text style for variables, if applicable. For instance, variables in + //! PHP typically start with a '$', so all identifiers following the + //! pattern $foo are highlighted as variable. + Variable, + //! Text style for control flow highlighting, such as @e if, @e then, + //! @e else, @e return, or @e continue. + ControlFlow, + //! Text style for operators such as +, -, *, / and :: etc. + Operator, + //! Text style for built-in language classes and functions. + BuiltIn, + //! Text style for well-known extensions, such as Qt or boost. + Extension, + //! Text style for preprocessor statements. + Preprocessor, + //! Text style for attributes of functions or objects, e.g. \@override + //! in Java, or __declspec(...) and __attribute__((...)) in C++. + Attribute, + //! Text style for single characters such as 'a'. + Char, + //! Text style for escaped characters in strings, such as "hello\n". + SpecialChar, + //! Text style for strings, for instance "hello world". + String, + //! Text style for verbatim strings such as HERE docs. + VerbatimString, + //! Text style for special strings such as regular expressions in + //! ECMAScript or the LaTeX math mode. + SpecialString, + //! Text style for includes, imports, modules, or LaTeX packages. + Import, + //! Text style for data types such as int, char, float etc. + DataType, + //! Text style for decimal values. + DecVal, + //! Text style for numbers with base other than 10. + BaseN, + //! Text style for floating point numbers. + Float, + //! Text style for language constants, e.g. True, False, None in Python + //! or nullptr in C/C++. + Constant, + //! Text style for normal comments. + Comment, + //! Text style for comments that reflect API documentation, such as + //! doxygen /** */ comments. + Documentation, + //! Text style for annotations in comments, such as \@param in Doxygen + //! or JavaDoc. + Annotation, + //! Text style that refers to variables in a comment, such as after + //! \@param \<identifier\> in Doxygen or JavaDoc. + CommentVar, + //! Text style for region markers, typically defined by BEGIN/END. + RegionMarker, + //! Text style for information, such as the keyword \@note in Doxygen. + Information, + //! Text style for warnings, such as the keyword \@warning in Doxygen. + Warning, + //! Text style for comment specials such as TODO and WARNING in + //! comments. + Alert, + //! Text style indicating wrong syntax. + Error, + //! Text style for attributes that do not match any of the other default + //! styles. + Others + }; + Q_ENUM(TextStyle) + + /** + * Editor color roles, used to paint line numbers, editor background etc. + * The colors typically should have good contrast with the colors used + * in the TextStyle%s. + */ + enum EditorColorRole { + //! Background color for the editing area. + BackgroundColor = 0, + //! Background color for selected text. + TextSelection, + //! Background color for the line of the current text cursor. + CurrentLine, + //! Background color for matching text while searching. + SearchHighlight, + //! Background color for replaced text for a search & replace action. + ReplaceHighlight, + //! Background color for matching bracket pairs (including quotes) + BracketMatching, + //! Foreground color for visualizing tabs and trailing spaces. + TabMarker, + //! Color used to underline spell check errors. + SpellChecking, + //! Color used to draw vertical indentation levels, typically a line. + IndentationLine, + //! Background color for the icon border. + IconBorder, + //! Background colors for code folding regions in the text area, as well + //! as code folding indicators in the code folding border. + CodeFolding, + //! Foreground color for drawing the line numbers. This should have a + //! good contrast with the IconBorder background color. + LineNumbers, + //! Foreground color for drawing the current line number. This should + //! have a good contrast with the IconBorder background color. + CurrentLineNumber, + //! Color used in the icon border to indicate dynamically wrapped lines. + //! This color should have a good contrast with the IconBorder + //! background color. + WordWrapMarker, + //! Color used to draw a vertical line for marking changed lines. + ModifiedLines, + //! Color used to draw a vertical line for marking saved lines. + SavedLines, + //! Line color used to draw separator lines, e.g. at column 80 in the + //! text editor area. + Separator, + //! Background color for bookmarks. + MarkBookmark, + //! Background color for active breakpoints. + MarkBreakpointActive, + //! Background color for a reached breakpoint. + MarkBreakpointReached, + //! Background color for inactive (disabled) breakpoints. + MarkBreakpointDisabled, + //! Background color for marking the current execution position. + MarkExecution, + //! Background color for general warning marks. + MarkWarning, + //! Background color for general error marks. + MarkError, + //! Background color for text templates (snippets). + TemplateBackground, + //! Background color for all editable placeholders in text templates. + TemplatePlaceholder, + //! Background color for the currently active placeholder in text + //! templates. + TemplateFocusedPlaceholder, + //! Background color for read-only placeholders in text templates. + TemplateReadOnlyPlaceholder + }; + Q_ENUM(EditorColorRole) + + /** + * Default constructor, creating an invalid Theme, see isValid(). + */ + Theme(); + + /** + * Copy constructor, sharing the Theme data with @p copy. + */ + Theme(const Theme ©); + + /** + * Destructor. + */ + ~Theme(); + + /** + * Assignment operator, sharing the Theme data with @p other. + */ + Theme &operator=(const Theme &other); + + /** + * Returns @c true if this is a valid Theme. + * If the theme is invalid, none of the returned colors are well-defined. + */ + bool isValid() const; + + /** + * Returns the unique name of this Theme. + * @see translatedName() + */ + QString name() const; + + /** + * Returns the translated name of this Theme. The translated name can be + * used in the user interface. + */ + QString translatedName() const; + + /** + * Returns @c true if this Theme is read-only. + * + * A Theme is read-only, if the filePath() points to a non-writable file. + * This is typically the case for Themes that are compiled into the executable + * as resource file, as well as for theme files that are installed in read-only + * system locations (e.g. /usr/share/). + */ + bool isReadOnly() const; + + /** + * Returns the full path and file name to this Theme. + * Themes from the Qt resource return the Qt resource path. + * Themes from disk return the local path. + * + * If the theme is invalid (isValid()), an empty string is returned. + */ + QString filePath() const; + + /** + * Returns the text color to be used for @p style. + * @c 0 is returned for styles that do not specify a text color, + * use the default text color in that case. + */ + QRgb textColor(TextStyle style) const; + + /** + * Returns the selected text color to be used for @p style. + * @c 0 is returned for styles that do not specify a selected text color, + * use the default textColor() in that case. + */ + QRgb selectedTextColor(TextStyle style) const; + + /** + * Returns the background color to be used for @p style. + * @c 0 is returned for styles that do not specify a background color, + * use the default background color in that case. + */ + QRgb backgroundColor(TextStyle style) const; + + /** + * Returns the background color to be used for selected text for @p style. + * @c 0 is returned for styles that do not specify a background color, + * use the default backgroundColor() in that case. + */ + QRgb selectedBackgroundColor(TextStyle style) const; + + /** + * Returns whether the given style should be shown in bold. + */ + bool isBold(TextStyle style) const; + + /** + * Returns whether the given style should be shown in italic. + */ + bool isItalic(TextStyle style) const; + + /** + * Returns whether the given style should be shown underlined. + */ + bool isUnderline(TextStyle style) const; + + /** + * Returns whether the given style should be shown struck through. + */ + bool isStrikeThrough(TextStyle style) const; + +public: + /** + * Returns the editor color for the requested @p role. + */ + QRgb editorColor(EditorColorRole role) const; + +private: + /** + * Constructor taking a shared ThemeData instance. + */ + explicit Theme(ThemeData* data); + friend class RepositoryPrivate; + friend class ThemeData; + +private: + /** + * Shared data holder. + */ + QExplicitlySharedDataPointer<ThemeData> m_data; +}; + +} + +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(KSyntaxHighlighting::Theme, Q_MOVABLE_TYPE); +QT_END_NAMESPACE + +#endif // KSYNTAXHIGHLIGHTING_THEME_H diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/themedata.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/themedata.cpp new file mode 100644 index 0000000000..eac9a92264 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/themedata.cpp @@ -0,0 +1,255 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + Copyright (C) 2016 Dominik Haumann <dhaumann@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "themedata_p.h" +#include "ksyntaxhighlighting_logging.h" + +#include <QFile> +#include <QFileInfo> +#include <QJsonDocument> +#include <QJsonObject> +#include <QJsonValue> +#include <QMetaEnum> + +#include <QDebug> + +using namespace KSyntaxHighlighting; + +ThemeData* ThemeData::get(const Theme &theme) +{ + return theme.m_data.data(); +} + +ThemeData::ThemeData() +{ + memset(m_editorColors, 0, sizeof(m_editorColors)); +} + +/** + * Convert QJsonValue @p val into a color, if possible. Valid colors are only + * in hex format: #rrggbb. On error, returns 0x00000000. + */ +static inline QRgb readColor(const QJsonValue &val) +{ + const QRgb unsetColor = 0; + if (!val.isString()) { + return unsetColor; + } + const QString str = val.toString(); + if (str.isEmpty() || str[0] != QLatin1Char('#')) { + return unsetColor; + } + const QColor color(str); + return color.isValid() ? color.rgb() : unsetColor; +} + +static inline TextStyleData readThemeData(const QJsonObject &obj) +{ + TextStyleData td; + + td.textColor = readColor(obj.value(QLatin1String("text-color"))); + td.backgroundColor = readColor(obj.value(QLatin1String("background-color"))); + td.selectedTextColor = readColor(obj.value(QLatin1String("selected-text-color"))); + td.selectedBackgroundColor = readColor(obj.value(QLatin1String("selected-background-color"))); + + auto val = obj.value(QLatin1String("bold")); + if (val.isBool()) { + td.bold = val.toBool(); + td.hasBold = true; + } + val = obj.value(QLatin1String("italic")); + if (val.isBool()) { + td.italic = val.toBool(); + td.hasItalic = true; + } + val = obj.value(QLatin1String("underline")); + if (val.isBool()) { + td.underline = val.toBool(); + td.hasUnderline = true; + } + val = obj.value(QLatin1String("strike-through")); + if (val.isBool()) { + td.strikeThrough = val.toBool(); + td.hasStrikeThrough = true; + } + + return td; +} + +bool ThemeData::load(const QString &filePath) +{ + QFile loadFile(filePath); + if (!loadFile.open(QIODevice::ReadOnly)) { + return false; + } + const QByteArray jsonData = loadFile.readAll(); + + QJsonParseError parseError; + QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError); + if (parseError.error != QJsonParseError::NoError) { + qCWarning(Log) << "Failed to parse theme file" << filePath << ":" << parseError.errorString(); + return false; + } + + m_filePath = filePath; + + QJsonObject obj = jsonDoc.object(); + + // read metadata + const QJsonObject metadata = obj.value(QLatin1String("metadata")).toObject(); + m_name = metadata.value(QLatin1String("name")).toString(); + m_revision = metadata.value(QLatin1String("revision")).toInt(); + + // read text styles + static const auto idx = Theme::staticMetaObject.indexOfEnumerator("TextStyle"); + Q_ASSERT(idx >= 0); + const auto metaEnum = Theme::staticMetaObject.enumerator(idx); + const QJsonObject textStyles = obj.value(QLatin1String("text-styles")).toObject(); + for (int i = 0; i < metaEnum.keyCount(); ++i) { + Q_ASSERT(i == metaEnum.value(i)); + m_textStyles[i] = readThemeData(textStyles.value(QLatin1String(metaEnum.key(i))).toObject()); + } + + // read editor area colors + const QJsonObject editorColors = obj.value(QLatin1String("editor-colors")).toObject(); + m_editorColors[Theme::BackgroundColor] = readColor(editorColors.value(QLatin1String("background-color"))); + m_editorColors[Theme::TextSelection] = readColor(editorColors.value(QLatin1String("selection"))); + m_editorColors[Theme::CurrentLine] = readColor(editorColors.value(QLatin1String("current-line"))); + m_editorColors[Theme::SearchHighlight] = readColor(editorColors.value(QLatin1String("search-highlight"))); + m_editorColors[Theme::ReplaceHighlight] = readColor(editorColors.value(QLatin1String("replace-highlight"))); + m_editorColors[Theme::BracketMatching] = readColor(editorColors.value(QLatin1String("bracket-matching"))); + m_editorColors[Theme::TabMarker] = readColor(editorColors.value(QLatin1String("tab-marker"))); + m_editorColors[Theme::SpellChecking] = readColor(editorColors.value(QLatin1String("spell-checking"))); + m_editorColors[Theme::IndentationLine] = readColor(editorColors.value(QLatin1String("indentation-line"))); + m_editorColors[Theme::IconBorder] = readColor(editorColors.value(QLatin1String("icon-border"))); + m_editorColors[Theme::CodeFolding] = readColor(editorColors.value(QLatin1String("code-folding"))); + m_editorColors[Theme::LineNumbers] = readColor(editorColors.value(QLatin1String("line-numbers"))); + m_editorColors[Theme::CurrentLineNumber] = readColor(editorColors.value(QLatin1String("current-line-number"))); + m_editorColors[Theme::WordWrapMarker] = readColor(editorColors.value(QLatin1String("word-wrap-marker"))); + m_editorColors[Theme::ModifiedLines] = readColor(editorColors.value(QLatin1String("modified-lines"))); + m_editorColors[Theme::SavedLines] = readColor(editorColors.value(QLatin1String("saved-lines"))); + m_editorColors[Theme::Separator] = readColor(editorColors.value(QLatin1String("separator"))); + m_editorColors[Theme::MarkBookmark] = readColor(editorColors.value(QLatin1String("mark-bookmark"))); + m_editorColors[Theme::MarkBreakpointActive] = readColor(editorColors.value(QLatin1String("mark-breakpoint-active"))); + m_editorColors[Theme::MarkBreakpointReached] = readColor(editorColors.value(QLatin1String("mark-breakpoint-reached"))); + m_editorColors[Theme::MarkBreakpointDisabled] = readColor(editorColors.value(QLatin1String("mark-breakpoint-disabled"))); + m_editorColors[Theme::MarkExecution] = readColor(editorColors.value(QLatin1String("mark-execution"))); + m_editorColors[Theme::MarkWarning] = readColor(editorColors.value(QLatin1String("mark-warning"))); + m_editorColors[Theme::MarkError] = readColor(editorColors.value(QLatin1String("mark-error"))); + m_editorColors[Theme::TemplateBackground] = readColor(editorColors.value(QLatin1String("template-background"))); + m_editorColors[Theme::TemplatePlaceholder] = readColor(editorColors.value(QLatin1String("template-placeholder"))); + m_editorColors[Theme::TemplateFocusedPlaceholder] = readColor(editorColors.value(QLatin1String("template-focused-placeholder"))); + m_editorColors[Theme::TemplateReadOnlyPlaceholder] = readColor(editorColors.value(QLatin1String("template-read-only-placeholder"))); + + // read per-definition style overrides + const auto customStyles = obj.value(QLatin1String("custom-styles")).toObject(); + for (auto it = customStyles.begin(); it != customStyles.end(); ++it) { + const auto obj = it.value().toObject(); + QHash<QString, TextStyleData> overrideStyle; + for (auto it2 = obj.begin(); it2 != obj.end(); ++it2) + overrideStyle.insert(it2.key(), readThemeData(it2.value().toObject())); + m_textStyleOverrides.insert(it.key(), overrideStyle); + } + + return true; +} + +QString ThemeData::name() const +{ + return m_name; +} + +int ThemeData::revision() const +{ + return m_revision; +} + +bool ThemeData::isReadOnly() const +{ + return !QFileInfo(m_filePath).isWritable(); +} + +QString ThemeData::filePath() const +{ + return m_filePath; +} + +QRgb ThemeData::textColor(Theme::TextStyle style) const +{ + Q_ASSERT(static_cast<int>(style) >= 0 && static_cast<int>(style) <= static_cast<int>(Theme::Others)); + return m_textStyles[style].textColor; +} + +QRgb ThemeData::selectedTextColor(Theme::TextStyle style) const +{ + Q_ASSERT(static_cast<int>(style) >= 0 && static_cast<int>(style) <= static_cast<int>(Theme::Others)); + return m_textStyles[style].selectedTextColor; +} + +QRgb ThemeData::backgroundColor(Theme::TextStyle style) const +{ + Q_ASSERT(static_cast<int>(style) >= 0 && static_cast<int>(style) <= static_cast<int>(Theme::Others)); + return m_textStyles[style].backgroundColor; +} + +QRgb ThemeData::selectedBackgroundColor(Theme::TextStyle style) const +{ + Q_ASSERT(static_cast<int>(style) >= 0 && static_cast<int>(style) <= static_cast<int>(Theme::Others)); + return m_textStyles[style].selectedBackgroundColor; +} + +bool ThemeData::isBold(Theme::TextStyle style) const +{ + Q_ASSERT(static_cast<int>(style) >= 0 && static_cast<int>(style) <= static_cast<int>(Theme::Others)); + return m_textStyles[style].bold; +} + +bool ThemeData::isItalic(Theme::TextStyle style) const +{ + Q_ASSERT(static_cast<int>(style) >= 0 && static_cast<int>(style) <= static_cast<int>(Theme::Others)); + return m_textStyles[style].italic; +} + +bool ThemeData::isUnderline(Theme::TextStyle style) const +{ + Q_ASSERT(static_cast<int>(style) >= 0 && static_cast<int>(style) <= static_cast<int>(Theme::Others)); + return m_textStyles[style].underline; +} + +bool ThemeData::isStrikeThrough(Theme::TextStyle style) const +{ + Q_ASSERT(static_cast<int>(style) >= 0 && static_cast<int>(style) <= static_cast<int>(Theme::Others)); + return m_textStyles[style].strikeThrough; +} + +QRgb ThemeData::editorColor(Theme::EditorColorRole role) const +{ + Q_ASSERT(static_cast<int>(role) >= 0 && static_cast<int>(role) <= static_cast<int>(Theme::TemplateReadOnlyPlaceholder)); + return m_editorColors[role]; +} + +TextStyleData ThemeData::textStyleOverride(const QString& definitionName, const QString& attributeName) const +{ + return m_textStyleOverrides.value(definitionName).value(attributeName); +} diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/themedata_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/themedata_p.h new file mode 100644 index 0000000000..3b5f4637a9 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/themedata_p.h @@ -0,0 +1,170 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + Copyright (C) 2016 Dominik Haumann <dhaumann@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_THEMEDATA_P_H +#define KSYNTAXHIGHLIGHTING_THEMEDATA_P_H + +#include "theme.h" +#include "textstyledata_p.h" + +#include <QHash> +#include <QSharedData> + +namespace KSyntaxHighlighting { + +/** + * Data container for a Theme. + */ +class ThemeData : public QSharedData +{ +public: + static ThemeData* get(const Theme &theme); + + /** + * Default constructor, creating an uninitialized ThemeData instance. + */ + ThemeData(); + + /** + * Load the Theme data from the file @p filePath. + * Note, that @p filePath either is a local file, or a qt resource location. + */ + bool load(const QString &filePath); + + /** + * Returns the unique name of this Theme. + */ + QString name() const; + + /** + * Returns the revision of this Theme. + * The revision in a .theme file should be increased with every change. + */ + int revision() const; + + /** + * Returns @c true if this Theme is read-only. + * Typically, themes that are shipped by default are read-only. + */ + bool isReadOnly() const; + + /** + * Returns the full path and filename to this Theme. + * Themes from the Qt resource return the Qt resource path. + * Themes from disk return the local path. + * + * If the theme is invalid (isValid()), an empty string is returned. + */ + QString filePath() const; + + /** + * Returns the text color to be used for @p style. + * @c 0 is returned for styles that do not specify a text color, + * use the default text color in that case. + */ + QRgb textColor(Theme::TextStyle style) const; + + /** + * Returns the text color for selected to be used for @p style. + * @c 0 is returned for styles that do not specify a selected text color, + * use the textColor() in that case. + */ + QRgb selectedTextColor(Theme::TextStyle style) const; + + /** + * Returns the background color to be used for @p style. + * @c 0 is returned for styles that do not specify a background color, + * use the default background color in that case. + */ + QRgb backgroundColor(Theme::TextStyle style) const; + + /** + * Returns the background color for selected text to be used for @p style. + * @c 0 is returned for styles that do not specify a selected background + * color, use the default backgroundColor() in that case. + */ + QRgb selectedBackgroundColor(Theme::TextStyle style) const; + + /** + * Returns whether the given style should be shown in bold. + */ + bool isBold(Theme::TextStyle style) const; + + /** + * Returns whether the given style should be shown in italic. + */ + bool isItalic(Theme::TextStyle style) const; + + /** + * Returns whether the given style should be shown underlined. + */ + bool isUnderline(Theme::TextStyle style) const; + + /** + * Returns whether the given style should be shown struck through. + */ + bool isStrikeThrough(Theme::TextStyle style) const; + +public: + /** + * Returns the editor color for the requested @p role. + */ + QRgb editorColor(Theme::EditorColorRole role) const; + + /** + * Returns the TextStyle override of a specific "itemData" with attributeName + * in the syntax definition called definitionName. + * + * If no override exists, a valid TextStyleData with the respective default + * TextStyle will be used, so the returned value is always valid. + */ + TextStyleData textStyleOverride(const QString &definitionName, const QString &attributeName) const; + +private: + int m_revision = 0; + QString m_name; + + //! Path to the file where the theme came from. + //! This is either a resource location (":/themes/Default.theme"), or a file + //! on disk (in a read-only or a writeable location). + QString m_filePath; + + //! TextStyles + TextStyleData m_textStyles[Theme::Others + 1]; + + //! style overrides for individual itemData entries + //! definition name -> attribute name -> style + QHash<QString, QHash<QString, TextStyleData> > m_textStyleOverrides; + + //! Editor area colors + QRgb m_editorColors[Theme::TemplateReadOnlyPlaceholder + 1]; +}; + +} + +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(KSyntaxHighlighting::TextStyleData, Q_MOVABLE_TYPE); +QT_END_NAMESPACE + +#endif // KSYNTAXHIGHLIGHTING_THEMEDATA_P_H diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.cpp new file mode 100644 index 0000000000..167295a930 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.cpp @@ -0,0 +1,83 @@ +/* + Copyright (C) 2007 Sebastian Pipping <webmaster@hartwork.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "wildcardmatcher_p.h" + +using namespace KSyntaxHighlighting; + +#include <QString> +#include <QChar> + +static bool exactMatch(const QString &candidate, const QString &wildcard, int candidatePosFromRight, + int wildcardPosFromRight, bool caseSensitive = true) +{ + for (; wildcardPosFromRight >= 0; wildcardPosFromRight--) { + const auto ch = wildcard.at(wildcardPosFromRight).unicode(); + switch (ch) { + case L'*': + if (candidatePosFromRight == -1) { + break; + } + + if (wildcardPosFromRight == 0) { + return true; + } + + // Eat all we can and go back as far as we have to + for (int j = -1; j <= candidatePosFromRight; j++) { + if (exactMatch(candidate, wildcard, j, wildcardPosFromRight - 1)) { + return true; + } + } + return false; + + case L'?': + if (candidatePosFromRight == -1) { + return false; + } + + candidatePosFromRight--; + break; + + default: + if (candidatePosFromRight == -1) { + return false; + } + + const auto candidateCh = candidate.at(candidatePosFromRight).unicode(); + const auto match = caseSensitive ? (candidateCh == ch) : (QChar::toLower(candidateCh) == QChar::toLower(ch)); + if (match) { + candidatePosFromRight--; + } else { + return false; + } + } + } + return true; +} + +bool WildcardMatcher::exactMatch(const QString &candidate, const QString &wildcard, + bool caseSensitive) +{ + return ::exactMatch(candidate, wildcard, candidate.length() - 1, wildcard.length() - 1, caseSensitive); +} diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher_p.h new file mode 100644 index 0000000000..016b10fe66 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher_p.h @@ -0,0 +1,51 @@ +/* + Copyright (C) 2007 Sebastian Pipping <webmaster@hartwork.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_WILDCARDMATCHER_P_H +#define KSYNTAXHIGHLIGHTING_WILDCARDMATCHER_P_H + +#include <QtGlobal> + +QT_BEGIN_NAMESPACE +class QString; +QT_END_NAMESPACE + +namespace KSyntaxHighlighting { + +namespace WildcardMatcher +{ + /** + * Matches a string against a given wildcard. + * The wildcard supports '*' (".*" in regex) and '?' ("." in regex), not more. + * + * @param candidate Text to match + * @param wildcard Wildcard to use + * @param caseSensitive Case-sensitivity flag + * @return True for an exact match, false otherwise + */ + bool exactMatch(const QString &candidate, const QString &wildcard, bool caseSensitive = true); +} + +} + +#endif // KSYNTAXHIGHLIGHTING_WILDCARDMATCHER_P_H diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/xml_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/xml_p.h new file mode 100644 index 0000000000..5f1f066dfd --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/xml_p.h @@ -0,0 +1,42 @@ +/* + Copyright (C) 2016 Volker Krause <vkrause@kde.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef KSYNTAXHIGHLIGHTING_XML_P_H +#define KSYNTAXHIGHLIGHTING_XML_P_H + +#include <QString> + +namespace KSyntaxHighlighting { +/** Utilities for XML parsing. */ +namespace Xml { + +/** Parse a xs:boolean attribute. */ +inline bool attrToBool(const QStringRef &str) +{ + return str == QLatin1String("1") || str.compare(QLatin1String("true"), Qt::CaseInsensitive) == 0; +} + +} +} + +#endif diff --git a/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.pro b/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.pro new file mode 100644 index 0000000000..38127e1cfe --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.pro @@ -0,0 +1,55 @@ +include(../../../qtcreatorlibrary.pri) +include(autogenerated/autogenerated.pri) + +QT += network + +DEFINES += KSYNTAXHIGHLIGHTING_LIBRARY + +RESOURCES += \ + data/themes/theme-data.qrc + +HEADERS += \ + src/lib/abstracthighlighter.h \ + src/lib/abstracthighlighter_p.h \ + src/lib/context_p.h \ + src/lib/contextswitch_p.h \ + src/lib/definition.h \ + src/lib/definition_p.h \ + src/lib/definitiondownloader.h \ + src/lib/definitionref_p.h \ + src/lib/foldingregion.h \ + src/lib/format.h \ + src/lib/format_p.h \ + src/lib/htmlhighlighter.h \ + src/lib/keywordlist_p.h \ + src/lib/ksyntaxhighlighting_export.h \ + src/lib/matchresult_p.h \ + src/lib/repository.h \ + src/lib/repository_p.h \ + src/lib/rule_p.h \ + src/lib/state.h \ + src/lib/state_p.h \ + src/lib/syntaxhighlighter.h \ + src/lib/textstyledata_p.h \ + src/lib/theme.h \ + src/lib/themedata_p.h \ + src/lib/wildcardmatcher_p.h \ + src/lib/xml_p.h \ + +SOURCES += \ + src/lib/abstracthighlighter.cpp \ + src/lib/context.cpp \ + src/lib/contextswitch.cpp \ + src/lib/definition.cpp \ + src/lib/definitiondownloader.cpp \ + src/lib/foldingregion.cpp \ + src/lib/format.cpp \ + src/lib/htmlhighlighter.cpp \ + src/lib/keywordlist.cpp \ + src/lib/repository.cpp \ + src/lib/rule.cpp \ + src/lib/state.cpp \ + src/lib/syntaxhighlighter.cpp \ + src/lib/theme.cpp \ + src/lib/themedata.cpp \ + src/lib/wildcardmatcher.cpp \ diff --git a/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.qbs b/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.qbs new file mode 100644 index 0000000000..248ebe0fd4 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.qbs @@ -0,0 +1,88 @@ +import qbs 1.0 +import qbs.File +import qbs.FileInfo +import qbs.Environment + +Project { + QtcDevHeaders { + productName: "syntax-highlighting (3rd party)" + baseDir: sourceDirectory + "/src/lib" + } + QtcDevHeaders { + productName: "syntax-highlighting autogenerated (3rd party)" + baseDir: sourceDirectory + "/autogenerated/src/lib" + Group { + prefix: baseDir + '/' + files: [ + "AbstractHighlighter", + "Definition", + "FoldingRegion", + "Format", + "Repository", + "State", + "SyntaxHighlighter", + "Theme" + ] + qbs.install: true + qbs.installDir: qtc.ide_include_path + '/' + FileInfo.fileName(product.sourceDirectory) + qbs.installSourceBase: baseDir + } + } + + QtcLibrary { + name: "KSyntaxHighlighting" + + cpp.defines: base.concat("KSYNTAXHIGHLIGHTING_LIBRARY") + cpp.includePaths: [ + product.sourceDirectory + "/src/lib/", + product.sourceDirectory + "/autogenerated/src/lib/", + product.sourceDirectory + "/autogenerated/" + ] + + Depends { name: "Qt.gui" } + Depends { name: "Qt.network" } + + Group { + name: "lib" + prefix: "src/lib/" + files: [ + "*.h", + "*.cpp" + ] + } + + Group { + name: "KSyntaxHighlighting data" + qbs.install: true + qbs.installDir: qtc.ide_data_path + "/generic-highlighter/" + qbs.installSourceBase: project.ide_source_tree + "/src/libs/3rdparty/syntax-highlighting/data/" + prefix: project.ide_source_tree + "/src/libs/3rdparty/syntax-highlighting/data/" + files: [ + "syntax/**/*" + ] + } + + Group { + name: "autogenerated lib" + prefix: "autogenerated/src/lib/" + files: [ + "*.h", + "*.cpp" + ] + } + + Group { + name: "theme data" + prefix: "data/themes/" + files: [ "theme-data.qrc" ] + } + + Export { + Depends { name: "cpp" } + cpp.includePaths: [ + product.sourceDirectory + "/src/lib/", + product.sourceDirectory + "/autogenerated/src/lib/", + ] + } + } +} diff --git a/src/libs/3rdparty/syntax-highlighting/syntax-highlighting_dependencies.pri b/src/libs/3rdparty/syntax-highlighting/syntax-highlighting_dependencies.pri new file mode 100644 index 0000000000..f2fd3e61b2 --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/syntax-highlighting_dependencies.pri @@ -0,0 +1,3 @@ +QTC_LIB_NAME = KSyntaxHighlighting +INCLUDEPATH *= $$PWD/src/lib +INCLUDEPATH *= $$PWD/autogenerated/src/lib diff --git a/src/libs/libs.pro b/src/libs/libs.pro index d998316fba..1ffb3bc9a4 100644 --- a/src/libs/libs.pro +++ b/src/libs/libs.pro @@ -31,7 +31,9 @@ for(l, SUBDIRS) { } SUBDIRS += \ - utils/process_stub.pro + utils/process_stub.pro \ + 3rdparty/syntax-highlighting \ + 3rdparty/syntax-highlighting/data win32:SUBDIRS += utils/process_ctrlc_stub.pro diff --git a/src/libs/libs.qbs b/src/libs/libs.qbs index 5db1dee72b..1c4275f6f1 100644 --- a/src/libs/libs.qbs +++ b/src/libs/libs.qbs @@ -21,5 +21,6 @@ Project { "utils/process_stub.qbs", "utils/process_ctrlc_stub.qbs", "utils/utils.qbs", + "3rdparty/syntax-highlighting/syntax-highlighting.qbs", ].concat(project.additionalLibs) } diff --git a/src/plugins/cmakeprojectmanager/cmakeeditor.cpp b/src/plugins/cmakeprojectmanager/cmakeeditor.cpp index c5c0fe5b74..6342535361 100644 --- a/src/plugins/cmakeprojectmanager/cmakeeditor.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeeditor.cpp @@ -41,7 +41,6 @@ #include <projectexplorer/projectexplorer.h> #include <projectexplorer/session.h> -#include <texteditor/highlighterutils.h> #include <texteditor/texteditoractionhandler.h> #include <texteditor/texteditorconstants.h> diff --git a/src/plugins/texteditor/codeassist/codeassistant.cpp b/src/plugins/texteditor/codeassist/codeassistant.cpp index 1290199a54..b531f44c80 100644 --- a/src/plugins/texteditor/codeassist/codeassistant.cpp +++ b/src/plugins/texteditor/codeassist/codeassistant.cpp @@ -26,7 +26,6 @@ #include "codeassistant.h" #include "completionassistprovider.h" #include "iassistprocessor.h" -#include "textdocument.h" #include "iassistproposal.h" #include "iassistproposalmodel.h" #include "iassistproposalwidget.h" @@ -35,6 +34,7 @@ #include "runner.h" #include "textdocumentmanipulator.h" +#include <texteditor/textdocument.h> #include <texteditor/texteditor.h> #include <texteditor/texteditorsettings.h> #include <texteditor/completionsettings.h> diff --git a/src/plugins/texteditor/generichighlighter/context.cpp b/src/plugins/texteditor/generichighlighter/context.cpp deleted file mode 100644 index 59681af6ec..0000000000 --- a/src/plugins/texteditor/generichighlighter/context.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "context.h" -#include "rule.h" -#include "reuse.h" -#include "dynamicrule.h" -#include "highlightdefinition.h" - -using namespace TextEditor; -using namespace Internal; - -Context::Context() : m_fallthrough(false), m_dynamic(false) -{} - -Context::Context(const Context &context) : - m_id(context.m_id), m_name(context.m_name), m_lineBeginContext(context.m_lineBeginContext), - m_lineEndContext(context.m_lineEndContext), m_lineEmptyContext(context.m_lineEmptyContext), - m_fallthroughContext(context.m_fallthroughContext), - m_itemData(context.m_itemData), m_fallthrough(context.m_fallthrough), - m_dynamic(context.m_dynamic), m_instructions(context.m_instructions), - m_definition(context.m_definition) -{ - // Rules need to be deeply copied because of dynamic contexts. - foreach (const QSharedPointer<Rule> &rule, context.m_rules) - m_rules.append(QSharedPointer<Rule>(rule->clone())); -} - -const Context &Context::operator=(Context copy) -{ - swap(copy); - return *this; -} - -Context::~Context() = default; - -void Context::swap(Context &context) -{ - qSwap(m_id, context.m_id); - qSwap(m_name, context.m_name); - qSwap(m_lineBeginContext, context.m_lineBeginContext); - qSwap(m_lineEndContext, context.m_lineEndContext); - qSwap(m_lineEmptyContext, context.m_lineEmptyContext); - qSwap(m_fallthroughContext, context.m_fallthroughContext); - qSwap(m_itemData, context.m_itemData); - qSwap(m_fallthrough, context.m_fallthrough); - qSwap(m_dynamic, context.m_dynamic); - qSwap(m_rules, context.m_rules); - qSwap(m_instructions, context.m_instructions); - qSwap(m_definition, context.m_definition); -} - -void Context::configureId(const int unique) -{ m_id.append(QString::number(unique)); } - -const QString &Context::id() const -{ return m_id; } - -void Context::setName(const QString &name) -{ - m_name = name; - m_id = name; -} - -const QString &Context::name() const -{ return m_name; } - -void Context::setLineBeginContext(const QString &context) -{ m_lineBeginContext = context; } - -const QString &Context::lineBeginContext() const -{ return m_lineBeginContext; } - -void Context::setLineEndContext(const QString &context) -{ m_lineEndContext = context; } - -const QString &Context::lineEndContext() const -{ return m_lineEndContext; } - -void Context::setLineEmptyContext(const QString &context) -{ m_lineEmptyContext = context; } - -const QString &Context::lineEmptyContext() const -{ return m_lineEmptyContext; } - -void Context::setFallthroughContext(const QString &context) -{ m_fallthroughContext = context; } - -const QString &Context::fallthroughContext() const -{ return m_fallthroughContext; } - -void Context::setItemData(const QString &itemData) -{ m_itemData = itemData; } - -const QString &Context::itemData() const -{ return m_itemData; } - -void Context::setFallthrough(const QString &fallthrough) -{ m_fallthrough = toBool(fallthrough); } - -bool Context::isFallthrough() const -{ return m_fallthrough; } - -void Context::setDynamic(const QString &dynamic) -{ m_dynamic = toBool(dynamic); } - -bool Context::isDynamic() const -{ return m_dynamic; } - -void Context::updateDynamicRules(const QStringList &captures) const -{ - Internal::updateDynamicRules(m_rules, captures); -} - -void Context::addRule(const QSharedPointer<Rule> &rule) -{ m_rules.append(rule); } - -void Context::addRule(const QSharedPointer<Rule> &rule, int index) -{ m_rules.insert(index, rule); } - -const QList<QSharedPointer<Rule> > & Context::rules() const -{ return m_rules; } - -void Context::addIncludeRulesInstruction(const IncludeRulesInstruction &instruction) -{ m_instructions.append(instruction); } - -const QList<IncludeRulesInstruction> &Context::includeRulesInstructions() const -{ return m_instructions; } - -void Context::clearIncludeRulesInstructions() -{ m_instructions.clear(); } - -void Context::setDefinition(const QSharedPointer<HighlightDefinition> &definition) -{ m_definition = definition; } - -const QSharedPointer<HighlightDefinition> &Context::definition() const -{ return m_definition; } diff --git a/src/plugins/texteditor/generichighlighter/context.h b/src/plugins/texteditor/generichighlighter/context.h deleted file mode 100644 index c2358f2d04..0000000000 --- a/src/plugins/texteditor/generichighlighter/context.h +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include "includerulesinstruction.h" - -#include <QString> -#include <QList> -#include <QSharedPointer> - -namespace TextEditor { -namespace Internal { - -class Rule; -class HighlightDefinition; - -class Context -{ -public: - Context(); - Context(const Context &context); - const Context &operator=(Context copy); - ~Context(); - - void configureId(const int unique); - const QString &id() const; - - void setName(const QString &name); - const QString &name() const; - - void setLineBeginContext(const QString &context); - const QString &lineBeginContext() const; - - void setLineEndContext(const QString &context); - const QString &lineEndContext() const; - - void setLineEmptyContext(const QString &context); - const QString &lineEmptyContext() const; - - void setFallthroughContext(const QString &context); - const QString &fallthroughContext() const; - - void setItemData(const QString &itemData); - const QString &itemData() const; - - void setFallthrough(const QString &fallthrough); - bool isFallthrough() const; - - void setDynamic(const QString &dynamic); - bool isDynamic() const; - void updateDynamicRules(const QStringList &captures) const; - - void addRule(const QSharedPointer<Rule> &rule); - void addRule(const QSharedPointer<Rule> &rule, int index); - const QList<QSharedPointer<Rule> > &rules() const; - - void addIncludeRulesInstruction(const IncludeRulesInstruction &instruction); - const QList<IncludeRulesInstruction> &includeRulesInstructions() const; - void clearIncludeRulesInstructions(); - - void setDefinition(const QSharedPointer<HighlightDefinition> &definition); - const QSharedPointer<HighlightDefinition> &definition() const; - - void swap(Context &context); - -private: - QString m_id; - QString m_name; - QString m_lineBeginContext; - QString m_lineEndContext; - QString m_lineEmptyContext; - QString m_fallthroughContext; - QString m_itemData; - bool m_fallthrough; - bool m_dynamic; - - QList<QSharedPointer<Rule> > m_rules; - QList<IncludeRulesInstruction> m_instructions; - - QSharedPointer<HighlightDefinition> m_definition; -}; - -} // namespace Internal -} // namespace TextEditor diff --git a/src/plugins/texteditor/generichighlighter/definitiondownloader.cpp b/src/plugins/texteditor/generichighlighter/definitiondownloader.cpp deleted file mode 100644 index 680d811148..0000000000 --- a/src/plugins/texteditor/generichighlighter/definitiondownloader.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "definitiondownloader.h" - -#include <utils/fileutils.h> - -#include <QLatin1Char> -#include <QEventLoop> -#include <QScopedPointer> -#include <QNetworkRequest> -#include <QNetworkReply> -#include <QRegExp> - -#include <utils/networkaccessmanager.h> - -namespace TextEditor { -namespace Internal { - -static QNetworkReply *getData(QNetworkAccessManager *manager, const QUrl &url) -{ - QNetworkRequest request(url); - QNetworkReply *reply = manager->get(request); - - QEventLoop eventLoop; - QObject::connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit); - eventLoop.exec(); - - return reply; -} - -DefinitionDownloader::DefinitionDownloader(const QUrl &url, const QString &localPath) : - m_url(url), m_localPath(localPath), m_status(Unknown) -{} - -void DefinitionDownloader::run() -{ - Utils::NetworkAccessManager manager; - - int currentAttempt = 0; - const int maxAttempts = 5; - while (currentAttempt < maxAttempts) { - QScopedPointer<QNetworkReply> reply(getData(&manager, m_url)); - if (reply->error() != QNetworkReply::NoError) { - m_status = NetworkError; - return; - } - - ++currentAttempt; - QVariant variant = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); - if (variant.isValid() && currentAttempt < maxAttempts) { - m_url = variant.toUrl(); - } else if (!variant.isValid()) { - saveData(reply.data()); - return; - } - } -} - -void DefinitionDownloader::saveData(QNetworkReply *reply) -{ - const QString &urlPath = m_url.path(); - const QString &fileName = - urlPath.right(urlPath.length() - urlPath.lastIndexOf(QLatin1Char('/')) - 1); - Utils::FileSaver saver(m_localPath + fileName, QIODevice::Text); - const QByteArray data = reply->readAll(); - saver.write(data); - m_status = saver.finalize() ? Ok: WriteError; - QString content = QString::fromUtf8(data); - QRegExp reference(QLatin1String("context\\s*=\\s*\"[^\"]*##([^\"]+)\"")); - int index = -1; - forever { - index = reference.indexIn(content, index + 1); - if (index == -1) - break; - emit foundReferencedDefinition(reference.cap(1)); - } -} - -DefinitionDownloader::Status DefinitionDownloader::status() const -{ return m_status; } - -} // namespace Internal -} // namespace TextEditor diff --git a/src/plugins/texteditor/generichighlighter/definitiondownloader.h b/src/plugins/texteditor/generichighlighter/definitiondownloader.h deleted file mode 100644 index 95ab812114..0000000000 --- a/src/plugins/texteditor/generichighlighter/definitiondownloader.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include <QObject> -#include <QString> -#include <QUrl> - -QT_BEGIN_NAMESPACE -class QNetworkReply; -QT_END_NAMESPACE - -namespace TextEditor { -namespace Internal { - -class DefinitionDownloader : public QObject -{ - Q_OBJECT -public: - DefinitionDownloader(const QUrl &url, const QString &localPath); - - enum Status { - NetworkError, - WriteError, - Ok, - Unknown - }; - - void run(); - Status status() const; - -signals: - void foundReferencedDefinition(const QString &name); - -private: - void saveData(QNetworkReply *reply); - - QUrl m_url; - QString m_localPath; - Status m_status; -}; - -} // namespace Internal -} // namespace TextEditor diff --git a/src/plugins/texteditor/generichighlighter/dynamicrule.cpp b/src/plugins/texteditor/generichighlighter/dynamicrule.cpp deleted file mode 100644 index abb4b73faa..0000000000 --- a/src/plugins/texteditor/generichighlighter/dynamicrule.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "dynamicrule.h" -#include "reuse.h" - -using namespace TextEditor; -using namespace Internal; - -DynamicRule::DynamicRule() : m_active(false) -{} - -DynamicRule::~DynamicRule() = default; - -void DynamicRule::setActive(const QString &active) -{ m_active = toBool(active); } - -bool DynamicRule::isActive() const -{ return m_active; } - -void DynamicRule::replaceExpressions(const QStringList &captures) -{ - doReplaceExpressions(captures); - updateDynamicRules(children(), captures); -} - -namespace TextEditor { -namespace Internal { - -void updateDynamicRules(const QList<QSharedPointer<Rule> > &rules, const QStringList &captures) -{ - foreach (QSharedPointer<Rule> rule, rules) { - auto dynamicRule = dynamic_cast<DynamicRule *>(rule.data()); - if (dynamicRule && dynamicRule->isActive()) - dynamicRule->replaceExpressions(captures); - } -} - -} // namespace Internal -} // namespace TextEditor diff --git a/src/plugins/texteditor/generichighlighter/dynamicrule.h b/src/plugins/texteditor/generichighlighter/dynamicrule.h deleted file mode 100644 index 2c3d46bd8d..0000000000 --- a/src/plugins/texteditor/generichighlighter/dynamicrule.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include "rule.h" - -QT_BEGIN_NAMESPACE -class QStringList; -QT_END_NAMESPACE - -namespace TextEditor { -namespace Internal { - -class DynamicRule : public Rule -{ -public: - DynamicRule(); - ~DynamicRule() override; - - void setActive(const QString &active); - bool isActive() const; - - virtual void replaceExpressions(const QStringList &captures); - -private: - virtual void doReplaceExpressions(const QStringList &captures) = 0; - - bool m_active; -}; - -void updateDynamicRules(const QList<QSharedPointer<Rule> > &rules, const QStringList &captures); - -} // namespace Internal -} // namespace TextEditor diff --git a/src/plugins/texteditor/generichighlighter/highlightdefinition.cpp b/src/plugins/texteditor/generichighlighter/highlightdefinition.cpp deleted file mode 100644 index 66e3cb2712..0000000000 --- a/src/plugins/texteditor/generichighlighter/highlightdefinition.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "highlightdefinition.h" -#include "highlighterexception.h" -#include "context.h" -#include "keywordlist.h" -#include "itemdata.h" -#include "reuse.h" - -#include <QCoreApplication> -#include <QString> - -using namespace TextEditor; -using namespace Internal; - -namespace { - -template <class Element, class Container> -QSharedPointer<Element> createHelper(const QString &name, Container &container) -{ - if (name.isEmpty()) { - throw HighlighterException( - QCoreApplication::translate("GenericHighlighter", "Element name is empty.")); - } - - if (container.contains(name)) { - throw HighlighterException( - QCoreApplication::translate("GenericHighlighter", - "Duplicate element name \"%1\".").arg(name)); - } - - return container.insert(name, QSharedPointer<Element>(new Element)).value(); -} - -template <class Element, class Container> -QSharedPointer<Element> -findHelper(const QString &name, const Container &container) -{ - typename Container::const_iterator it = container.find(name); - if (it == container.end()) { - throw HighlighterException( - QCoreApplication::translate("GenericHighlighter", - "Name \"%1\" not found.").arg(name)); - } - - return it.value(); -} - -} // anon namespace - -HighlightDefinition::HighlightDefinition() : - m_keywordCaseSensitivity(Qt::CaseSensitive), - m_singleLineCommentAfterWhiteSpaces(false), - m_indentationBasedFolding(false) -{ - const QString s(QLatin1String(".():!+,-<=>%&/;?[]^{|}~\\*, \t")); - for (auto &c : s) - m_delimiters.insert(c); -} - -HighlightDefinition::~HighlightDefinition() = default; - -bool HighlightDefinition::isValid() const -{ - return !m_initialContext.isEmpty(); -} - -QSharedPointer<KeywordList> HighlightDefinition::createKeywordList(const QString &list) -{ - return createHelper<KeywordList>(list, m_lists); -} - -QSharedPointer<KeywordList> HighlightDefinition::keywordList(const QString &list) -{ - return findHelper<KeywordList>(list, m_lists); -} - -QSharedPointer<Context> HighlightDefinition::createContext(const QString &context, bool initial) -{ - if (initial) - m_initialContext = context; - - QSharedPointer<Context> newContext = createHelper<Context>(context, m_contexts); - newContext->setName(context); - return newContext; -} - -QSharedPointer<Context> HighlightDefinition::initialContext() const -{ - return findHelper<Context>(m_initialContext, m_contexts); -} - -QSharedPointer<Context> HighlightDefinition::context(const QString &context) const -{ - return findHelper<Context>(context, m_contexts); -} - -const QHash<QString, QSharedPointer<Context> > &HighlightDefinition::contexts() const -{ - return m_contexts; -} - -QSharedPointer<ItemData> HighlightDefinition::createItemData(const QString &itemData) -{ - return createHelper<ItemData>(itemData, m_itemsData); -} - -QSharedPointer<ItemData> HighlightDefinition::itemData(const QString &itemData) const -{ - return findHelper<ItemData>(itemData, m_itemsData); -} - -void HighlightDefinition::setSingleLineComment(const QString &start) -{ m_singleLineComment = start; } - -const QString &HighlightDefinition::singleLineComment() const -{ return m_singleLineComment; } - -void HighlightDefinition::setCommentAfterWhitespaces(const QString &after) -{ - if (after == QLatin1String("afterwhitespace")) - m_singleLineCommentAfterWhiteSpaces = true; -} - -bool HighlightDefinition::isCommentAfterWhiteSpaces() const -{ return m_singleLineCommentAfterWhiteSpaces; } - -void HighlightDefinition::setMultiLineCommentStart(const QString &start) -{ m_multiLineCommentStart = start; } - -const QString &HighlightDefinition::multiLineCommentStart() const -{ return m_multiLineCommentStart; } - -void HighlightDefinition::setMultiLineCommentEnd(const QString &end) -{ m_multiLineCommentEnd = end; } - -const QString &HighlightDefinition::multiLineCommentEnd() const -{ return m_multiLineCommentEnd; } - -void HighlightDefinition::setMultiLineCommentRegion(const QString ®ion) -{ m_multiLineCommentRegion = region; } - -const QString &HighlightDefinition::multiLineCommentRegion() const -{ return m_multiLineCommentRegion; } - -void HighlightDefinition::removeDelimiters(const QString &characters) -{ - for (QChar character : characters) - m_delimiters.remove(character); -} - -void HighlightDefinition::addDelimiters(const QString &characters) -{ - for (QChar character : characters) { - if (!m_delimiters.contains(character)) - m_delimiters.insert(character); - } -} - -bool HighlightDefinition::isDelimiter(const QChar &character) const -{ - if (m_delimiters.contains(character)) - return true; - return false; -} - -void HighlightDefinition::setKeywordsSensitive(const QString &sensitivity) -{ - if (!sensitivity.isEmpty()) - m_keywordCaseSensitivity = toCaseSensitivity(toBool(sensitivity)); -} - -Qt::CaseSensitivity HighlightDefinition::keywordsSensitive() const -{ return m_keywordCaseSensitivity; } - -void HighlightDefinition::setIndentationBasedFolding(const QString &indentationBasedFolding) -{ m_indentationBasedFolding = toBool(indentationBasedFolding); } - -bool HighlightDefinition::isIndentationBasedFolding() const -{ return m_indentationBasedFolding; } diff --git a/src/plugins/texteditor/generichighlighter/highlightdefinition.h b/src/plugins/texteditor/generichighlighter/highlightdefinition.h deleted file mode 100644 index f39373df18..0000000000 --- a/src/plugins/texteditor/generichighlighter/highlightdefinition.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include <QString> -#include <QHash> -#include <QSet> -#include <QSharedPointer> - -namespace TextEditor { -namespace Internal { - -class KeywordList; -class Context; -class ItemData; - -class HighlightDefinition -{ -public: - HighlightDefinition(); - ~HighlightDefinition(); - - bool isValid() const; - - QSharedPointer<KeywordList> createKeywordList(const QString &list); - QSharedPointer<KeywordList> keywordList(const QString &list); - - QSharedPointer<Context> createContext(const QString &context, bool initial); - QSharedPointer<Context> initialContext() const; - QSharedPointer<Context> context(const QString &context) const; - const QHash<QString, QSharedPointer<Context> > &contexts() const; - - QSharedPointer<ItemData> createItemData(const QString &itemData); - QSharedPointer<ItemData> itemData(const QString &itemData) const; - - void setKeywordsSensitive(const QString &sensitivity); - Qt::CaseSensitivity keywordsSensitive() const; - - void addDelimiters(const QString &characters); - void removeDelimiters(const QString &characters); - bool isDelimiter(const QChar &character) const; - - void setSingleLineComment(const QString &start); - const QString &singleLineComment() const; - - void setCommentAfterWhitespaces(const QString &after); - bool isCommentAfterWhiteSpaces() const; - - void setMultiLineCommentStart(const QString &start); - const QString &multiLineCommentStart() const; - - void setMultiLineCommentEnd(const QString &end); - const QString &multiLineCommentEnd() const; - - void setMultiLineCommentRegion(const QString ®ion); - const QString &multiLineCommentRegion() const; - - void setIndentationBasedFolding(const QString &indentationBasedFolding); - bool isIndentationBasedFolding() const; - -private: - Q_DISABLE_COPY(HighlightDefinition) - - QHash<QString, QSharedPointer<KeywordList> > m_lists; - QHash<QString, QSharedPointer<Context> > m_contexts; - QHash<QString, QSharedPointer<ItemData> > m_itemsData; - - QString m_initialContext; - - QString m_singleLineComment; - - QString m_multiLineCommentStart; - QString m_multiLineCommentEnd; - QString m_multiLineCommentRegion; - - Qt::CaseSensitivity m_keywordCaseSensitivity; - - bool m_singleLineCommentAfterWhiteSpaces; - bool m_indentationBasedFolding; - - QSet<QChar> m_delimiters; -}; - -} // namespace Internal -} // namespace TextEditor diff --git a/src/plugins/texteditor/generichighlighter/highlightdefinitionhandler.cpp b/src/plugins/texteditor/generichighlighter/highlightdefinitionhandler.cpp deleted file mode 100644 index 56b1626414..0000000000 --- a/src/plugins/texteditor/generichighlighter/highlightdefinitionhandler.cpp +++ /dev/null @@ -1,502 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "highlightdefinitionhandler.h" -#include "highlightdefinition.h" -#include "highlighterexception.h" -#include "specificrules.h" -#include "itemdata.h" -#include "keywordlist.h" -#include "context.h" -#include "manager.h" - -#include <coreplugin/messagemanager.h> - -#include <QCoreApplication> -#include <QLatin1String> - -using namespace TextEditor; -using namespace Internal; - -namespace { - static const QLatin1String kName("name"); - static const QLatin1String kList("list"); - static const QLatin1String kItem("item"); - static const QLatin1String kContext("context"); - static const QLatin1String kAttribute("attribute"); - static const QLatin1String kDynamic("dynamic"); - static const QLatin1String kFallthrough("fallthrough"); - static const QLatin1String kLineEndContext("lineEndContext"); - static const QLatin1String kLineEmptyContext("lineEmptyContext"); - static const QLatin1String kLineBeginContext("lineBeginContext"); - static const QLatin1String kFallthroughContext("fallthroughContext"); - static const QLatin1String kBeginRegion("beginRegion"); - static const QLatin1String kEndRegion("endRegion"); - static const QLatin1String kLookAhead("lookAhead"); - static const QLatin1String kFirstNonSpace("firstNonSpace"); - static const QLatin1String kColumn("column"); - static const QLatin1String kItemData("itemData"); - static const QLatin1String kDefStyleNum("defStyleNum"); - static const QLatin1String kColor("color"); - static const QLatin1String kSelColor("selColor"); - static const QLatin1String kItalic("italic"); - static const QLatin1String kBold("bold"); - static const QLatin1String kUnderline("underline"); - static const QLatin1String kStrikeout("strikeout"); - static const QLatin1String kChar("char"); - static const QLatin1String kChar1("char1"); - static const QLatin1String kString("String"); - static const QLatin1String kInsensitive("insensitive"); - static const QLatin1String kMinimal("minimal"); - static const QLatin1String kKeywords("keywords"); - static const QLatin1String kCaseSensitive("casesensitive"); - static const QLatin1String kWeakDeliminator("weakDeliminator"); - static const QLatin1String kAdditionalDeliminator("additionalDeliminator"); - static const QLatin1String kComment("comment"); - static const QLatin1String kPosition("position"); - static const QLatin1String kSingleLine("singleline"); - static const QLatin1String kMultiLine("multiline"); - static const QLatin1String kStart("start"); - static const QLatin1String kEnd("end"); - static const QLatin1String kRegion("region"); - static const QLatin1String kDetectChar("DetectChar"); - static const QLatin1String kDetect2Chars("Detect2Chars"); - static const QLatin1String kAnyChar("AnyChar"); - static const QLatin1String kStringDetect("StringDetect"); - static const QLatin1String kWordDetect("WordDetect"); - static const QLatin1String kRegExpr("RegExpr"); - static const QLatin1String kKeyword("keyword"); - static const QLatin1String kInt("Int"); - static const QLatin1String kFloat("Float"); - static const QLatin1String kHlCOct("HlCOct"); - static const QLatin1String kHlCHex("HlCHex"); - static const QLatin1String kHlCStringChar("HlCStringChar"); - static const QLatin1String kHlCChar("HlCChar"); - static const QLatin1String kRangeDetect("RangeDetect"); - static const QLatin1String kLineContinue("LineContinue"); - static const QLatin1String kIncludeRules("IncludeRules"); - static const QLatin1String kDetectSpaces("DetectSpaces"); - static const QLatin1String kDetectIdentifier("DetectIdentifier"); - static const QLatin1String kIncludeAttrib("includeAttrib"); - static const QLatin1String kFolding("folding"); - static const QLatin1String kIndentationSensitive("indentationsensitive"); - static const QLatin1String kHash("#"); - static const QLatin1String kDoubleHash("##"); -} - -HighlightDefinitionHandler:: -HighlightDefinitionHandler(const QSharedPointer<HighlightDefinition> &definition) : - m_definition(definition), - m_processingKeyword(false), - m_initialContext(true) -{} - -HighlightDefinitionHandler::~HighlightDefinitionHandler() = default; - -bool HighlightDefinitionHandler::startDocument() -{ - return true; -} - -bool HighlightDefinitionHandler::endDocument() -{ - processIncludeRules(); - return true; -} - -bool HighlightDefinitionHandler::startElement(const QString &, - const QString &, - const QString &qName, - const QXmlAttributes &atts) -{ - if (qName == kList) - listElementStarted(atts); - else if (qName == kItem) - itemElementStarted(); - else if (qName == kContext) - contextElementStarted(atts); - else if (qName == kItemData) - itemDataElementStarted(atts); - else if (qName == kComment) - commentElementStarted(atts); - else if (qName == kKeywords) - keywordsElementStarted(atts); - else if (qName == kFolding) - foldingElementStarted(atts); - else if (qName == kDetectChar) - detectCharStarted(atts); - else if (qName == kDetect2Chars) - detect2CharsStarted(atts); - else if (qName == kAnyChar) - anyCharStarted(atts); - else if (qName == kStringDetect) - stringDetectedStarted(atts); - else if (qName == kWordDetect) - wordDetectStarted(atts); - else if (qName == kRegExpr) - regExprStarted(atts); - else if (qName == kKeyword) - keywordStarted(atts); - else if (qName == kInt) - intStarted(atts); - else if (qName == kFloat) - floatStarted(atts); - else if (qName == kHlCOct) - hlCOctStarted(atts); - else if (qName == kHlCHex) - hlCHexStarted(atts); - else if (qName == kHlCStringChar) - hlCStringCharStarted(atts); - else if (qName == kHlCChar) - hlCCharStarted(atts); - else if (qName == kRangeDetect) - rangeDetectStarted(atts); - else if (qName == kLineContinue) - lineContinue(atts); - else if (qName == kIncludeRules) - includeRulesStarted(atts); - else if (qName == kDetectSpaces) - detectSpacesStarted(atts); - else if (qName == kDetectIdentifier) - detectIdentifier(atts); - - return true; -} - -bool HighlightDefinitionHandler::endElement(const QString &, const QString &, const QString &qName) -{ - if (qName == kItem) { - m_currentList->addKeyword(m_currentKeyword.trimmed()); - m_processingKeyword = false; - } else if (qName == kDetectChar || qName == kDetect2Chars || qName == kAnyChar || - qName == kStringDetect || qName == kWordDetect || qName == kRegExpr || - qName == kKeyword || qName == kInt || - qName == kFloat || qName == kHlCOct || qName == kHlCHex || qName == kHlCStringChar || - qName == kHlCChar || qName == kRangeDetect || qName == kLineContinue || - qName == kDetectSpaces || qName == kDetectIdentifier) { - m_currentRule.pop(); - } - - return true; -} - -bool HighlightDefinitionHandler::characters(const QString& ch) -{ - // Character data of an element may be reported in more than one chunk. - if (m_processingKeyword) - m_currentKeyword.append(ch); - - return true; -} - -void HighlightDefinitionHandler::listElementStarted(const QXmlAttributes &atts) -{ - m_currentList = m_definition->createKeywordList(atts.value(kName)); -} - -void HighlightDefinitionHandler::itemElementStarted() -{ - m_currentKeyword.clear(); - m_processingKeyword = true; -} - -void HighlightDefinitionHandler::contextElementStarted(const QXmlAttributes &atts) -{ - m_currentContext = m_definition->createContext(atts.value(kName), m_initialContext); - m_currentContext->setDefinition(m_definition); - m_currentContext->setItemData(atts.value(kAttribute)); - m_currentContext->setDynamic(atts.value(kDynamic)); - m_currentContext->setFallthrough(atts.value(kFallthrough)); - m_currentContext->setFallthroughContext(atts.value(kFallthroughContext)); - m_currentContext->setLineBeginContext(atts.value(kLineBeginContext)); - m_currentContext->setLineEndContext(atts.value(kLineEndContext)); - m_currentContext->setLineEmptyContext(atts.value(kLineEmptyContext)); - - m_initialContext = false; -} - -void HighlightDefinitionHandler::ruleElementStarted(const QXmlAttributes &atts, - const QSharedPointer<Rule> &rule) -{ - const QString context = atts.value(kContext); - // The definition of a rule is not necessarily the same of its enclosing context because of - // externally included rules. - rule->setDefinition(m_definition); - rule->setItemData(atts.value(kAttribute)); - rule->setContext(context); - rule->setBeginRegion(atts.value(kBeginRegion)); - rule->setEndRegion(atts.value(kEndRegion)); - rule->setLookAhead(atts.value(kLookAhead)); - rule->setFirstNonSpace(atts.value(kFirstNonSpace)); - rule->setColumn(atts.value(kColumn)); - - if (context.contains(kDoubleHash)) { - IncludeRulesInstruction includeInstruction(context, m_currentContext->rules().size(), QString()); - m_currentContext->addIncludeRulesInstruction(includeInstruction); - } - if (m_currentRule.isEmpty()) - m_currentContext->addRule(rule); - else - m_currentRule.top()->addChild(rule); - - m_currentRule.push(rule); -} - -void HighlightDefinitionHandler::itemDataElementStarted(const QXmlAttributes &atts) const -{ - QSharedPointer<ItemData> itemData = m_definition->createItemData(atts.value(kName)); - itemData->setStyle(atts.value(kDefStyleNum)); - itemData->setColor(atts.value(kColor)); - itemData->setSelectionColor(atts.value(kSelColor)); - itemData->setItalic(atts.value(kItalic)); - itemData->setBold(atts.value(kBold)); - itemData->setUnderlined(atts.value(kUnderline)); - itemData->setStrikeOut(atts.value(kStrikeout)); -} - -void HighlightDefinitionHandler::commentElementStarted(const QXmlAttributes &atts) const -{ - const QString &commentType = atts.value(kName); - if (commentType.compare(kSingleLine, Qt::CaseInsensitive) == 0) { - m_definition->setSingleLineComment(atts.value(kStart)); - m_definition->setCommentAfterWhitespaces(atts.value(kPosition)); - } else if (commentType.compare(kMultiLine, Qt::CaseInsensitive) == 0) { - m_definition->setMultiLineCommentStart(atts.value(kStart)); - m_definition->setMultiLineCommentEnd(atts.value(kEnd)); - m_definition->setMultiLineCommentRegion(atts.value(kRegion)); - } -} - -void HighlightDefinitionHandler::keywordsElementStarted(const QXmlAttributes &atts) const -{ - // Global case sensitivity appears last in the document (required by dtd) and is set here. - m_definition->setKeywordsSensitive(atts.value(kCaseSensitive)); - m_definition->removeDelimiters(atts.value(kWeakDeliminator)); - m_definition->addDelimiters(atts.value(kAdditionalDeliminator)); - //@todo: wordWrapDelimiters? -} - -void HighlightDefinitionHandler::foldingElementStarted(const QXmlAttributes &atts) const -{ - m_definition->setIndentationBasedFolding(atts.value(kIndentationSensitive)); -} - -void HighlightDefinitionHandler::detectCharStarted(const QXmlAttributes &atts) -{ - auto rule = new DetectCharRule; - rule->setChar(atts.value(kChar)); - rule->setActive(atts.value(kDynamic)); - ruleElementStarted(atts, QSharedPointer<Rule>(rule)); -} - -void HighlightDefinitionHandler::detect2CharsStarted(const QXmlAttributes &atts) -{ - auto rule = new Detect2CharsRule; - rule->setChar(atts.value(kChar)); - rule->setChar1(atts.value(kChar1)); - rule->setActive(atts.value(kDynamic)); - ruleElementStarted(atts, QSharedPointer<Rule>(rule)); -} - -void HighlightDefinitionHandler::anyCharStarted(const QXmlAttributes &atts) -{ - auto rule = new AnyCharRule; - rule->setCharacterSet(atts.value(kString)); - ruleElementStarted(atts, QSharedPointer<Rule>(rule)); -} - -void HighlightDefinitionHandler::stringDetectedStarted(const QXmlAttributes &atts) -{ - auto rule = new StringDetectRule; - rule->setString(atts.value(kString)); - rule->setInsensitive(atts.value(kInsensitive)); - rule->setActive(atts.value(kDynamic)); - ruleElementStarted(atts, QSharedPointer<Rule>(rule)); -} - -void HighlightDefinitionHandler::wordDetectStarted(const QXmlAttributes &atts) -{ - auto rule = new WordDetectRule; - rule->setString(atts.value(kString)); - rule->setInsensitive(atts.value(kInsensitive)); - rule->setActive(atts.value(kDynamic)); - ruleElementStarted(atts, QSharedPointer<Rule>(rule)); -} - -void HighlightDefinitionHandler::regExprStarted(const QXmlAttributes &atts) -{ - auto rule = new RegExprRule; - rule->setPattern(atts.value(kString)); - rule->setMinimal(atts.value(kMinimal)); - rule->setInsensitive(atts.value(kInsensitive)); - rule->setActive(atts.value(kDynamic)); - ruleElementStarted(atts, QSharedPointer<Rule>(rule)); -} - -void HighlightDefinitionHandler::keywordStarted(const QXmlAttributes &atts) -{ - auto rule = new KeywordRule(m_definition); - try { - rule->setList(atts.value(kString)); - } catch (const HighlighterException &e) { - // Handle broken files. makefile.xml references an invalid list. - Core::MessageManager::write( - QCoreApplication::translate("GenericHighlighter", - "Generic highlighter warning: %1") - .arg(e.message())); - } - rule->setInsensitive(atts.value(kInsensitive)); - ruleElementStarted(atts, QSharedPointer<Rule>(rule)); -} - -void HighlightDefinitionHandler::intStarted(const QXmlAttributes &atts) -{ - ruleElementStarted(atts, QSharedPointer<Rule>(new IntRule)); -} - -void HighlightDefinitionHandler::floatStarted(const QXmlAttributes &atts) -{ - ruleElementStarted(atts, QSharedPointer<Rule>(new FloatRule)); -} - -void HighlightDefinitionHandler::hlCOctStarted(const QXmlAttributes &atts) -{ - ruleElementStarted(atts, QSharedPointer<Rule>(new HlCOctRule)); -} - -void HighlightDefinitionHandler::hlCHexStarted(const QXmlAttributes &atts) -{ - ruleElementStarted(atts, QSharedPointer<Rule>(new HlCHexRule)); -} - -void HighlightDefinitionHandler::hlCStringCharStarted(const QXmlAttributes &atts) -{ - ruleElementStarted(atts, QSharedPointer<Rule>(new HlCStringCharRule)); -} - -void HighlightDefinitionHandler::hlCCharStarted(const QXmlAttributes &atts) -{ - ruleElementStarted(atts, QSharedPointer<Rule>(new HlCCharRule)); -} - -void HighlightDefinitionHandler::rangeDetectStarted(const QXmlAttributes &atts) -{ - auto rule = new RangeDetectRule; - rule->setChar(atts.value(kChar)); - rule->setChar1(atts.value(kChar1)); - ruleElementStarted(atts, QSharedPointer<Rule>(rule)); -} - -void HighlightDefinitionHandler::lineContinue(const QXmlAttributes &atts) -{ - ruleElementStarted(atts, QSharedPointer<Rule>(new LineContinueRule)); -} - -void HighlightDefinitionHandler::includeRulesStarted(const QXmlAttributes &atts) -{ - // Include rules are treated as instructions for latter processing. - IncludeRulesInstruction instruction(atts.value(kContext), m_currentContext->rules().size(), - atts.value(kIncludeAttrib)); - - // Include rules (as many others) are not allowed as a child. - m_currentContext->addIncludeRulesInstruction(instruction); -} - -void HighlightDefinitionHandler::detectSpacesStarted(const QXmlAttributes &atts) -{ - ruleElementStarted(atts, QSharedPointer<Rule>(new DetectSpacesRule)); -} - -void HighlightDefinitionHandler::detectIdentifier(const QXmlAttributes &atts) -{ - ruleElementStarted(atts, QSharedPointer<Rule>(new DetectIdentifierRule)); -} - -void HighlightDefinitionHandler::processIncludeRules() const -{ - const QHash<QString, QSharedPointer<Context> > &allContexts = m_definition->contexts(); - foreach (const QSharedPointer<Context> &context, allContexts) - processIncludeRules(context); -} - -void HighlightDefinitionHandler::processIncludeRules(const QSharedPointer<Context> &context) const -{ - if (context->includeRulesInstructions().isEmpty()) - return; - - int rulesIncluded = 0; - const QList<IncludeRulesInstruction> &instructions = context->includeRulesInstructions(); - foreach (const IncludeRulesInstruction &instruction, instructions) { - - QSharedPointer<Context> sourceContext; - const QString &sourceName = instruction.sourceContext(); - if (sourceName.contains(kDoubleHash)) { - // This refers to an external definition. Context can be specified before the double - // hash (e.g. Normal##Javascript). If it isn't, the rules included are the ones from its - // initial context. Others contexts and rules from the external definition will work - // transparently to the highlighter. This is because contexts and rules know the - // definition they are from. - const QStringList values = sourceName.split(kDoubleHash); - if (values.count() != 2) - return; - const QString externalContext = values.at(0); - const QString externalName = values.at(1); - const QString &id = Manager::instance()->definitionIdByName(externalName); - - // If there is an incorrect circular dependency among definitions this is skipped. - if (Manager::instance()->isBuildingDefinition(id)) - continue; - - const QSharedPointer<HighlightDefinition> &externalDefinition = - Manager::instance()->definition(id); - if (externalDefinition.isNull() || !externalDefinition->isValid()) - continue; - - if (externalContext.isEmpty()) - sourceContext = externalDefinition->initialContext(); - else - sourceContext = externalDefinition->context(externalContext); - } else if (!sourceName.startsWith(kHash)) { - sourceContext = m_definition->context(sourceName); - - // Recursion is done only for context direct rules. Child rules are not processed - // because they cannot be include rules. - processIncludeRules(sourceContext); - } else { - continue; - } - - if (instruction.replaceItemData()) { - context->setItemData(sourceContext->itemData()); - context->setDefinition(sourceContext->definition()); - } - - foreach (QSharedPointer<Rule> rule, sourceContext->rules()) { - context->addRule(rule, instruction.indexHint() + rulesIncluded); - ++rulesIncluded; - } - } - context->clearIncludeRulesInstructions(); -} diff --git a/src/plugins/texteditor/generichighlighter/highlightdefinitionhandler.h b/src/plugins/texteditor/generichighlighter/highlightdefinitionhandler.h deleted file mode 100644 index bb7317ec51..0000000000 --- a/src/plugins/texteditor/generichighlighter/highlightdefinitionhandler.h +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include <QString> -#include <QSharedPointer> -#include <QStack> - -#include <QXmlDefaultHandler> - -namespace TextEditor { -namespace Internal { - -class KeywordList; -class Context; -class Rule; -class HighlightDefinition; - -class HighlightDefinitionHandler : public QXmlDefaultHandler -{ -public: - HighlightDefinitionHandler(const QSharedPointer<HighlightDefinition> &definition); - ~HighlightDefinitionHandler() override; - - bool startDocument() override; - bool endDocument() override; - bool startElement(const QString &namespaceURI, const QString &localName, - const QString &qName, const QXmlAttributes &atts) override; - bool endElement(const QString &namespaceURI, const QString &localName, - const QString &qName) override; - bool characters(const QString &ch) override; - -private: - void listElementStarted(const QXmlAttributes &atts); - void itemElementStarted(); - void contextElementStarted(const QXmlAttributes &atts); - void itemDataElementStarted(const QXmlAttributes &atts) const; - void commentElementStarted(const QXmlAttributes &atts) const; - void keywordsElementStarted(const QXmlAttributes &atts) const; - void foldingElementStarted(const QXmlAttributes &atts) const; - void ruleElementStarted(const QXmlAttributes &atts, const QSharedPointer<Rule> &rule); - - // Specific rules. - void detectCharStarted(const QXmlAttributes &atts); - void detect2CharsStarted(const QXmlAttributes &atts); - void anyCharStarted(const QXmlAttributes &atts); - void stringDetectedStarted(const QXmlAttributes &atts); - void wordDetectStarted(const QXmlAttributes &atts); - void regExprStarted(const QXmlAttributes &atts); - void keywordStarted(const QXmlAttributes &atts); - void intStarted(const QXmlAttributes &atts); - void floatStarted(const QXmlAttributes &atts); - void hlCOctStarted(const QXmlAttributes &atts); - void hlCHexStarted(const QXmlAttributes &atts); - void hlCStringCharStarted(const QXmlAttributes &atts); - void hlCCharStarted(const QXmlAttributes &atts); - void rangeDetectStarted(const QXmlAttributes &atts); - void lineContinue(const QXmlAttributes &atts); - void includeRulesStarted(const QXmlAttributes &atts); - void detectSpacesStarted(const QXmlAttributes &atts); - void detectIdentifier(const QXmlAttributes &atts); - - void processIncludeRules() const; - void processIncludeRules(const QSharedPointer<Context> &context) const; - - QSharedPointer<HighlightDefinition> m_definition; - - bool m_processingKeyword; - QString m_currentKeyword; - QSharedPointer<KeywordList> m_currentList; - QSharedPointer<Context> m_currentContext; - QStack<QSharedPointer<Rule> > m_currentRule; - - bool m_initialContext; -}; - -} // namespace Internal -} // namespace TextEditor diff --git a/src/plugins/texteditor/generichighlighter/highlightdefinitionmetadata.h b/src/plugins/texteditor/generichighlighter/highlightdefinitionmetadata.h deleted file mode 100644 index f201d3c189..0000000000 --- a/src/plugins/texteditor/generichighlighter/highlightdefinitionmetadata.h +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include <QSharedPointer> -#include <QStringList> -#include <QUrl> - -namespace TextEditor { -namespace Internal { - -class HighlightDefinitionMetaData -{ -public: - HighlightDefinitionMetaData() = default; - -public: - int priority = 0; - QString id; - QString name; - QString version; - QString fileName; - QStringList patterns; - QStringList mimeTypes; - QUrl url; -}; - -using DefinitionMetaDataPtr = QSharedPointer<HighlightDefinitionMetaData>; - -} // namespace Internal -} // namespace TextEditor diff --git a/src/plugins/texteditor/generichighlighter/highlighter.cpp b/src/plugins/texteditor/generichighlighter/highlighter.cpp deleted file mode 100644 index 8ea7dbbda3..0000000000 --- a/src/plugins/texteditor/generichighlighter/highlighter.cpp +++ /dev/null @@ -1,740 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "context.h" -#include "highlightdefinition.h" -#include "highlighter.h" -#include "highlighterexception.h" -#include "itemdata.h" -#include "progressdata.h" -#include "reuse.h" -#include "rule.h" -#include "tabsettings.h" - -#include <coreplugin/messagemanager.h> -#include <texteditor/fontsettings.h> -#include <texteditor/texteditorsettings.h> -#include <utils/qtcassert.h> - -#include <QCoreApplication> - -#include <cmath> - -using namespace TextEditor; -using namespace Internal; - -namespace { - static const QLatin1String kStay("#stay"); - static const QLatin1String kPop("#pop"); - static const QLatin1Char kBackSlash('\\'); - static const QLatin1Char kHash('#'); - static const QLatin1Char kExclamationMark('!'); -} - -class HighlighterCodeFormatterData : public CodeFormatterData -{ -public: - ~HighlighterCodeFormatterData() override = default; - int m_foldingIndentDelta = 0; - int m_originalObservableState = -1; - QStack<QString> m_foldingRegions; - int m_continueObservableState = -1; -}; - -HighlighterCodeFormatterData *formatterData(const QTextBlock &block) -{ - HighlighterCodeFormatterData *data = nullptr; - if (TextBlockUserData *userData = TextDocumentLayout::userData(block)) { - data = static_cast<HighlighterCodeFormatterData *>(userData->codeFormatterData()); - if (!data) { - data = new HighlighterCodeFormatterData; - userData->setCodeFormatterData(data); - } - } - return data; -} - -static TextStyle styleForFormat(int format) -{ - const auto f = Highlighter::TextFormatId(format); - switch (f) { - case Highlighter::Normal: return C_TEXT; - case Highlighter::Keyword: return C_KEYWORD; - case Highlighter::DataType: return C_TYPE; - case Highlighter::Comment: return C_COMMENT; - case Highlighter::Decimal: return C_NUMBER; - case Highlighter::BaseN: return C_NUMBER; - case Highlighter::Float: return C_NUMBER; - case Highlighter::Char: return C_STRING; - case Highlighter::SpecialChar: return C_STRING; - case Highlighter::String: return C_STRING; - case Highlighter::Alert: return C_WARNING; - case Highlighter::Information: return C_TEXT; - case Highlighter::Warning: return C_WARNING; - case Highlighter::Error: return C_ERROR; - case Highlighter::Function: return C_FUNCTION; - case Highlighter::RegionMarker: return C_TEXT; - case Highlighter::BuiltIn: return C_PREPROCESSOR; - case Highlighter::Extension: return C_PRIMITIVE_TYPE; - case Highlighter::Operator: return C_OPERATOR; - case Highlighter::Variable: return C_LOCAL; - case Highlighter::Attribute: return C_LABEL; - case Highlighter::Annotation: return C_TEXT; - case Highlighter::CommentVar: return C_COMMENT; - case Highlighter::Import: return C_PREPROCESSOR; - case Highlighter::Others: return C_TEXT; - case Highlighter::Identifier: return C_LOCAL; - case Highlighter::Documentation: return C_DOXYGEN_COMMENT; - case Highlighter::ControlFlow: return C_KEYWORD; - case Highlighter::Preprocessor: return C_PREPROCESSOR; - case Highlighter::VerbatimString: return C_STRING; - case Highlighter::SpecialString: return C_STRING; - case Highlighter::Constant: return C_KEYWORD; - case Highlighter::TextFormatIdCount: - QTC_CHECK(false); // should never get here - return C_TEXT; - } - QTC_CHECK(false); // should never get here - return C_TEXT; -} - -Highlighter::Highlighter(QTextDocument *parent) : - SyntaxHighlighter(parent) -{ - setTextFormatCategories(TextFormatIdCount, styleForFormat); -} - -Highlighter::~Highlighter() = default; - -// Mapping from Kate format strings to format ids. -struct KateFormatMap -{ - KateFormatMap(); - QHash<QString, Highlighter::TextFormatId> m_ids; -}; - -KateFormatMap::KateFormatMap() -{ - m_ids.insert(QLatin1String("dsNormal"), Highlighter::Normal); - m_ids.insert(QLatin1String("dsKeyword"), Highlighter::Keyword); - m_ids.insert(QLatin1String("dsDataType"), Highlighter::DataType); - m_ids.insert(QLatin1String("dsComment"), Highlighter::Comment); - m_ids.insert(QLatin1String("dsDecVal"), Highlighter::Decimal); - m_ids.insert(QLatin1String("dsBaseN"), Highlighter::BaseN); - m_ids.insert(QLatin1String("dsFloat"), Highlighter::Float); - m_ids.insert(QLatin1String("dsChar"), Highlighter::Char); - m_ids.insert(QLatin1String("dsSpecialChar"), Highlighter::SpecialChar); - m_ids.insert(QLatin1String("dsString"), Highlighter::String); - m_ids.insert(QLatin1String("dsAlert"), Highlighter::Alert); - m_ids.insert(QLatin1String("dsInformation"), Highlighter::Information); - m_ids.insert(QLatin1String("dsWarning"), Highlighter::Warning); - m_ids.insert(QLatin1String("dsError"), Highlighter::Error); - m_ids.insert(QLatin1String("dsFunction"), Highlighter::Function); - m_ids.insert(QLatin1String("dsRegionMarker"), Highlighter::RegionMarker); - m_ids.insert(QLatin1String("dsBuiltIn"), Highlighter::BuiltIn); - m_ids.insert(QLatin1String("dsExtension"), Highlighter::Extension); - m_ids.insert(QLatin1String("dsOperator"), Highlighter::Operator); - m_ids.insert(QLatin1String("dsVariable"), Highlighter::Variable); - m_ids.insert(QLatin1String("dsAttribute"), Highlighter::Attribute); - m_ids.insert(QLatin1String("dsAnnotation"), Highlighter::Annotation); - m_ids.insert(QLatin1String("dsCommentVar"), Highlighter::CommentVar); - m_ids.insert(QLatin1String("dsImport"), Highlighter::Import); - m_ids.insert(QLatin1String("dsOthers"), Highlighter::Others); - m_ids.insert(QLatin1String("dsIdentifier"), Highlighter::Identifier); - m_ids.insert(QLatin1String("dsDocumentation"), Highlighter::Documentation); - m_ids.insert(QLatin1String("dsControlFlow"), Highlighter::ControlFlow); - m_ids.insert(QLatin1String("dsPreprocessor"), Highlighter::Preprocessor); - m_ids.insert(QLatin1String("dsVerbatimString"), Highlighter::VerbatimString); - m_ids.insert(QLatin1String("dsSpecialString"), Highlighter::SpecialString); - m_ids.insert(QLatin1String("dsConstant"), Highlighter::Constant); -} - -Q_GLOBAL_STATIC(KateFormatMap, kateFormatMap) - -void Highlighter::setDefaultContext(const QSharedPointer<Context> &defaultContext) -{ - m_defaultContext = defaultContext; - m_persistentObservableStates.insert(m_defaultContext->name(), Default); - m_indentationBasedFolding = defaultContext->definition()->isIndentationBasedFolding(); -} - -void Highlighter::setTabSettings(const TabSettings &ts) -{ - m_tabSettings = &ts; -} - -static bool isOpeningParenthesis(QChar c) -{ - return c == QLatin1Char('{') || c == QLatin1Char('[') || c == QLatin1Char('('); -} - -static bool isClosingParenthesis(QChar c) -{ - return c == QLatin1Char('}') || c == QLatin1Char(']') || c == QLatin1Char(')'); -} - -void Highlighter::highlightBlock(const QString &text) -{ - if (!m_defaultContext.isNull() && !m_isBroken) { - try { - setupDataForBlock(text); - - handleContextChange(m_currentContext->lineBeginContext(), - m_currentContext->definition()); - - auto progress = new ProgressData; - const int length = text.length(); - while (progress->offset() < length) - iterateThroughRules(text, length, progress, false, m_currentContext->rules()); - - if (extractObservableState(currentBlockState()) != WillContinue) { - handleContextChange(m_currentContext->lineEndContext(), - m_currentContext->definition(), - false); - } - if (length == 0) { - handleContextChange(m_currentContext->lineEmptyContext(), - m_currentContext->definition(), - false); - } - delete progress; - m_contexts.clear(); - - if (m_indentationBasedFolding) { - applyIndentationBasedFolding(text); - } else { - applyRegionBasedFolding(); - - // In the case region depth has changed since the last time the state was set. - setCurrentBlockState(computeState(extractObservableState(currentBlockState()))); - } - - Parentheses parentheses; - for (int pos = 0; pos < length; ++pos) { - const QChar c = text.at(pos); - if (isOpeningParenthesis(c)) - parentheses.push_back(Parenthesis(Parenthesis::Opened, c, pos)); - else if (isClosingParenthesis(c)) - parentheses.push_back(Parenthesis(Parenthesis::Closed, c, pos)); - } - TextDocumentLayout::setParentheses(currentBlock(), parentheses); - - } catch (const HighlighterException &e) { - Core::MessageManager::write( - QCoreApplication::translate("GenericHighlighter", - "Generic highlighter error: %1") - .arg(e.message()), - Core::MessageManager::WithFocus); - m_isBroken = true; - } - } - - formatSpaces(text); -} - -void Highlighter::setupDataForBlock(const QString &text) -{ - if (extractObservableState(currentBlockState()) == WillContinue) - analyseConsistencyOfWillContinueBlock(text); - - if (previousBlockState() == -1) { - m_regionDepth = 0; - setupDefault(); - } else { - m_regionDepth = extractRegionDepth(previousBlockState()); - const int observablePreviousState = extractObservableState(previousBlockState()); - if (observablePreviousState == Default) - setupDefault(); - else if (observablePreviousState == WillContinue) - setupFromWillContinue(); - else if (observablePreviousState == Continued) - setupFromContinued(); - else - setupFromPersistent(); - - formatterData(currentBlock())->m_foldingRegions = - formatterData(currentBlock().previous())->m_foldingRegions; - } - - assignCurrentContext(); -} - -void Highlighter::setupDefault() -{ - m_contexts.push_back(m_defaultContext); - - setCurrentBlockState(computeState(Default)); -} - -void Highlighter::setupFromWillContinue() -{ - HighlighterCodeFormatterData *previousData = formatterData(currentBlock().previous()); - pushContextSequence(previousData->m_continueObservableState); - - HighlighterCodeFormatterData *data = formatterData(currentBlock()); - data->m_originalObservableState = previousData->m_originalObservableState; - - if (currentBlockState() == -1 || extractObservableState(currentBlockState()) == Default) - setCurrentBlockState(computeState(Continued)); -} - -void Highlighter::setupFromContinued() -{ - HighlighterCodeFormatterData *previousData = formatterData(currentBlock().previous()); - - Q_ASSERT(previousData->m_originalObservableState != WillContinue && - previousData->m_originalObservableState != Continued); - - if (previousData->m_originalObservableState == Default || - previousData->m_originalObservableState == -1) { - m_contexts.push_back(m_defaultContext); - } else { - pushContextSequence(previousData->m_originalObservableState); - } - - setCurrentBlockState(computeState(previousData->m_originalObservableState)); -} - -void Highlighter::setupFromPersistent() -{ - pushContextSequence(extractObservableState(previousBlockState())); - - setCurrentBlockState(previousBlockState()); -} - -void Highlighter::iterateThroughRules(const QString &text, - const int length, - ProgressData *progress, - const bool childRule, - const QList<QSharedPointer<Rule> > &rules) -{ - if (!childRule) { - if (progress->detectRecursion(m_currentContext->id())) { - progress->setOffset(length); - return; - } - } - - using RuleIterator = QList<QSharedPointer<Rule> >::const_iterator; - - bool contextChanged = false; - bool atLeastOneMatch = false; - - RuleIterator it = rules.begin(); - RuleIterator endIt = rules.end(); - while (it != endIt && progress->offset() < length) { - int startOffset = progress->offset(); - const QSharedPointer<Rule> &rule = *it; - if (rule->matchSucceed(text, length, progress)) { - atLeastOneMatch = true; - - if (!m_indentationBasedFolding) { - if (!rule->beginRegion().isEmpty()) { - formatterData(currentBlock())->m_foldingRegions.push(rule->beginRegion()); - ++m_regionDepth; - if (progress->isOpeningBraceMatchAtFirstNonSpace()) - ++formatterData(currentBlock())->m_foldingIndentDelta; - } - if (!rule->endRegion().isEmpty()) { - QStack<QString> *currentRegions = - &formatterData(currentBlock())->m_foldingRegions; - if (!currentRegions->isEmpty() && rule->endRegion() == currentRegions->top()) { - currentRegions->pop(); - --m_regionDepth; - if (progress->isClosingBraceMatchAtNonEnd()) - --formatterData(currentBlock())->m_foldingIndentDelta; - } - } - progress->clearBracesMatches(); - } - - const QString itemData = rule->itemData(); - const QSharedPointer<HighlightDefinition> definition = rule->definition(); - const bool lookAhead = rule->isLookAhead(); - if (progress->isWillContinueLine()) { - createWillContinueBlock(); - progress->setWillContinueLine(false); - } else { - if (rule->hasChildren()) - iterateThroughRules(text, length, progress, true, rule->children()); - if (!rule->context().isEmpty() && contextChangeRequired(rule->context())) { - m_currentCaptures = progress->captures(); - changeContext(rule->context(), definition); - contextChanged = true; - } - } - - // Do NOT access rule frome here on, because a context change might delete rule - - // Format is not applied to child rules directly (but relative to the offset of their - // parent) nor to look ahead rules. - if (!childRule && !lookAhead) { - if (itemData.isEmpty()) - applyFormat(startOffset, progress->offset() - startOffset, - m_currentContext->itemData(), m_currentContext->definition()); - else - applyFormat(startOffset, progress->offset() - startOffset, itemData, - definition); - } - - // When there is a match of one child rule the others should be skipped. Otherwise - // the highlighting would be incorret in a case like 9ULLLULLLUULLULLUL, for example. - if (contextChanged || childRule) { - break; - } else { - it = rules.begin(); - continue; - } - } - ++it; - } - - if (!childRule && !atLeastOneMatch) { - if (m_currentContext->isFallthrough()) { - handleContextChange(m_currentContext->fallthroughContext(), - m_currentContext->definition()); - iterateThroughRules(text, length, progress, false, m_currentContext->rules()); - } else { - applyFormat(progress->offset(), 1, m_currentContext->itemData(), - m_currentContext->definition()); - if (progress->isOnlySpacesSoFar() && !text.at(progress->offset()).isSpace()) - progress->setOnlySpacesSoFar(false); - progress->incrementOffset(); - } - } -} - -bool Highlighter::contextChangeRequired(const QString &contextName) const -{ - if (contextName == kStay) - return false; - return true; -} - -void Highlighter::changeContext(const QString &contextName, - const QSharedPointer<HighlightDefinition> &definition, - const bool assignCurrent) -{ - QString identifier = contextName; - if (identifier.startsWith(kPop)) { - const QStringList complexOrder = contextName.split(kExclamationMark); - const QString orders = complexOrder.first(); - identifier = complexOrder.size() > 1 ? complexOrder[1] : QString(); - - const int count = orders.splitRef(kHash, QString::SkipEmptyParts).size(); - for (int i = 0; i < count; ++i) { - if (m_contexts.isEmpty()) { - throw HighlighterException( - QCoreApplication::translate("GenericHighlighter", "Reached empty context.")); - } - m_contexts.pop_back(); - } - - if (extractObservableState(currentBlockState()) >= PersistentsStart) { - // One or more contexts were popped during during a persistent state. - const QString ¤tSequence = currentContextSequence(); - if (m_persistentObservableStates.contains(currentSequence)) - setCurrentBlockState( - computeState(m_persistentObservableStates.value(currentSequence))); - else - setCurrentBlockState( - computeState(m_leadingObservableStates.value(currentSequence))); - } - } - if (!identifier.isEmpty()) { - const QSharedPointer<Context> &context = definition->context(identifier); - - if (context->isDynamic()) - pushDynamicContext(context); - else - m_contexts.push_back(context); - - if (m_contexts.back()->lineEndContext() == kStay || - extractObservableState(currentBlockState()) >= PersistentsStart) { - const QString ¤tSequence = currentContextSequence(); - mapLeadingSequence(currentSequence); - if (m_contexts.back()->lineEndContext() == kStay) { - // A persistent context was pushed. - mapPersistentSequence(currentSequence); - setCurrentBlockState( - computeState(m_persistentObservableStates.value(currentSequence))); - } - } - } - - if (assignCurrent) - assignCurrentContext(); -} - -void Highlighter::handleContextChange(const QString &contextName, - const QSharedPointer<HighlightDefinition> &definition, - const bool setCurrent) -{ - if (!contextName.isEmpty() && contextChangeRequired(contextName)) - changeContext(contextName, definition, setCurrent); -} - - -static double luminance(const QColor &color) -{ - // calculate the luminance based on - // https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef - auto val = [](const double &colorVal) { - return colorVal < 0.03928 ? colorVal / 12.92 : std::pow((colorVal + 0.055) / 1.055, 2.4); - }; - - static QHash<QRgb, double> cache; - QHash<QRgb, double>::iterator it = cache.find(color.rgb()); - if (it == cache.end()) { - it = cache.insert(color.rgb(), 0.2126 * val(color.redF()) - + 0.7152 * val(color.greenF()) - + 0.0722 * val(color.blueF())); - } - return it.value(); -} - -static float contrastRatio(const QColor &color1, const QColor &color2) -{ - // calculate the contrast ratio based on - // https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef - auto contrast = (luminance(color1) + 0.05) / (luminance(color2) + 0.05); - if (contrast < 1) - return 1 / contrast; - return contrast; -} - - -static bool isReadableOn(const QColor &background, const QColor &foreground) -{ - // following the W3C Recommendation on contrast for large Text - // https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef - return contrastRatio(background, foreground) > 3; -} - -void Highlighter::applyFormat(int offset, - int count, - const QString &itemDataName, - const QSharedPointer<HighlightDefinition> &definition) -{ - if (count == 0) - return; - - QSharedPointer<ItemData> itemData; - try { - itemData = definition->itemData(itemDataName); - } catch (const HighlighterException &) { - // There are some broken files. For instance, the Printf context in java.xml points to an - // inexistent Printf item data. These cases are considered to have normal text style. - return; - } - - TextFormatId formatId = kateFormatMap()->m_ids.value(itemData->style(), Normal); - if (formatId != Normal) { - QTextCharFormat format = formatForCategory(formatId); - if (itemData->isCustomized()) { - // Please notice that the following are applied every time for item data which have - // customizations. The configureFormats function could be used to provide a "one time" - // configuration, but it would probably require to traverse all item data from all - // definitions available/loaded (either to set the values or for some "notifying" - // strategy). This is because the highlighter does not really know on which - // definition(s) it is working. Since not many item data specify customizations I - // think this approach would fit better. If there are other ideas... - QBrush bg = format.background(); - if (bg.style() == Qt::NoBrush) - bg = fontSettings().toTextCharFormat(C_TEXT).background(); - if (itemData->color().isValid() && isReadableOn(bg.color(), itemData->color())) - format.setForeground(itemData->color()); - if (itemData->isItalicSpecified()) - format.setFontItalic(itemData->isItalic()); - if (itemData->isBoldSpecified()) - format.setFontWeight(toFontWeight(itemData->isBold())); - if (itemData->isUnderlinedSpecified()) - format.setFontUnderline(itemData->isUnderlined()); - if (itemData->isStrikeOutSpecified()) - format.setFontStrikeOut(itemData->isStrikeOut()); - } - - setFormat(offset, count, format); - } -} - -void Highlighter::createWillContinueBlock() -{ - HighlighterCodeFormatterData *data = formatterData(currentBlock()); - const int currentObservableState = extractObservableState(currentBlockState()); - if (currentObservableState == Continued) { - HighlighterCodeFormatterData *previousData = formatterData(currentBlock().previous()); - data->m_originalObservableState = previousData->m_originalObservableState; - } else if (currentObservableState != WillContinue) { - data->m_originalObservableState = currentObservableState; - } - const QString currentSequence = currentContextSequence(); - mapPersistentSequence(currentSequence); - data->m_continueObservableState = m_persistentObservableStates.value(currentSequence); - m_persistentContexts.insert(data->m_continueObservableState, m_contexts); - - setCurrentBlockState(computeState(WillContinue)); -} - -void Highlighter::analyseConsistencyOfWillContinueBlock(const QString &text) -{ - if (currentBlock().next().isValid() && ( - text.length() == 0 || text.at(text.length() - 1) != kBackSlash) && - extractObservableState(currentBlock().next().userState()) != Continued) { - currentBlock().next().setUserState(computeState(Continued)); - } - - if (text.length() == 0 || text.at(text.length() - 1) != kBackSlash) { - HighlighterCodeFormatterData *data = formatterData(currentBlock()); - setCurrentBlockState(computeState(data->m_originalObservableState)); - } -} - -void Highlighter::mapPersistentSequence(const QString &contextSequence) -{ - if (!m_persistentObservableStates.contains(contextSequence)) { - int newState = m_persistentObservableStatesCounter; - m_persistentObservableStates.insert(contextSequence, newState); - m_persistentContexts.insert(newState, m_contexts); - ++m_persistentObservableStatesCounter; - } -} - -void Highlighter::mapLeadingSequence(const QString &contextSequence) -{ - if (!m_leadingObservableStates.contains(contextSequence)) - m_leadingObservableStates.insert(contextSequence, - extractObservableState(currentBlockState())); -} - -void Highlighter::pushContextSequence(int state) -{ - const QVector<QSharedPointer<Context> > &contexts = m_persistentContexts.value(state); - for (const auto &context : contexts) - m_contexts.push_back(context); -} - -QString Highlighter::currentContextSequence() const -{ - QString sequence; - for (int i = 0; i < m_contexts.size(); ++i) - sequence.append(m_contexts.at(i)->id()); - - return sequence; -} - -void Highlighter::pushDynamicContext(const QSharedPointer<Context> &baseContext) -{ - // A dynamic context is created from another context which serves as its basis. Then, - // its rules are updated according to the captures from the calling regular expression which - // triggered the push of the dynamic context. - QSharedPointer<Context> context(new Context(*baseContext)); - context->configureId(m_dynamicContextsCounter); - context->updateDynamicRules(m_currentCaptures); - m_contexts.push_back(context); - ++m_dynamicContextsCounter; -} - -void Highlighter::assignCurrentContext() -{ - if (m_contexts.isEmpty()) { - // This is not supposed to happen. However, there are broken files (for example, php.xml) - // which will cause this behaviour. In such cases pushing the default context is enough to - // keep highlighter working. - m_contexts.push_back(m_defaultContext); - } - m_currentContext = m_contexts.back(); -} - -int Highlighter::extractRegionDepth(const int state) -{ - return state >> 12; -} - -int Highlighter::extractObservableState(const int state) -{ - return state & 0xFFF; -} - -int Highlighter::computeState(const int observableState) const -{ - return m_regionDepth << 12 | observableState; -} - -void Highlighter::applyRegionBasedFolding() const -{ - int folding = 0; - TextBlockUserData *currentBlockUserData = TextDocumentLayout::userData(currentBlock()); - HighlighterCodeFormatterData *data = formatterData(currentBlock()); - HighlighterCodeFormatterData *previousData = formatterData(currentBlock().previous()); - if (previousData) { - folding = extractRegionDepth(previousBlockState()); - if (data->m_foldingIndentDelta != 0) { - folding += data->m_foldingIndentDelta; - if (data->m_foldingIndentDelta > 0) - currentBlockUserData->setFoldingStartIncluded(true); - else - TextDocumentLayout::userData(currentBlock().previous())->setFoldingEndIncluded(false); - data->m_foldingIndentDelta = 0; - } - } - currentBlockUserData->setFoldingEndIncluded(true); - currentBlockUserData->setFoldingIndent(folding); -} - -void Highlighter::applyIndentationBasedFolding(const QString &text) const -{ - TextBlockUserData *data = TextDocumentLayout::userData(currentBlock()); - data->setFoldingEndIncluded(true); - - // If this line is empty, check its neighbours. They all might be part of the same block. - if (text.trimmed().isEmpty()) { - data->setFoldingIndent(0); - const int previousIndent = neighbouringNonEmptyBlockIndent(currentBlock().previous(), true); - if (previousIndent > 0) { - const int nextIndent = neighbouringNonEmptyBlockIndent(currentBlock().next(), false); - if (previousIndent == nextIndent) - data->setFoldingIndent(previousIndent); - } - } else { - data->setFoldingIndent(m_tabSettings->indentationColumn(text)); - } -} - -int Highlighter::neighbouringNonEmptyBlockIndent(QTextBlock block, const bool previous) const -{ - while (true) { - if (!block.isValid()) - return 0; - if (block.text().trimmed().isEmpty()) { - if (previous) - block = block.previous(); - else - block = block.next(); - } else { - return m_tabSettings->indentationColumn(block.text()); - } - } -} diff --git a/src/plugins/texteditor/generichighlighter/highlighter.h b/src/plugins/texteditor/generichighlighter/highlighter.h deleted file mode 100644 index f814496600..0000000000 --- a/src/plugins/texteditor/generichighlighter/highlighter.h +++ /dev/null @@ -1,199 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include "context.h" - -// Yes, this is correct. These are found somewhere else when building the autotest. -#include <textdocumentlayout.h> -#include <syntaxhighlighter.h> - -#include <QString> -#include <QVector> -#include <QStack> -#include <QSharedPointer> -#include <QStringList> - -#include <QTextCharFormat> - -namespace TextEditor { - -class TabSettings; -namespace Internal { - -class Rule; -class HighlightDefinition; -class ProgressData; - -} // namespace Internal - -/* - Warning: Due to a very ugly hack with generichighlighter test - you can't export this class, so that it would be used from - other plugins. That's why highlighterutils.h was introduced. -*/ -class Highlighter : public TextEditor::SyntaxHighlighter -{ - Q_OBJECT - -public: - Highlighter(QTextDocument *parent = nullptr); - ~Highlighter() override; - - enum TextFormatId { - Normal, - Keyword, - DataType, - Comment, - Decimal, - BaseN, - Float, - Char, - SpecialChar, - String, - Alert, - Information, - Warning, - Error, - Function, - RegionMarker, - BuiltIn, - Extension, - Operator, - Variable, - Attribute, - Annotation, - CommentVar, - Import, - Others, - Identifier, - Documentation, - ControlFlow, - Preprocessor, - VerbatimString, - SpecialString, - Constant, - TextFormatIdCount - }; - - void setTabSettings(const TabSettings &ts); - void setDefaultContext(const QSharedPointer<Internal::Context> &defaultContext); - -protected: - void highlightBlock(const QString &text) override; - -private: - - void setupDataForBlock(const QString &text); - void setupDefault(); - void setupFromWillContinue(); - void setupFromContinued(); - void setupFromPersistent(); - - void iterateThroughRules(const QString &text, - const int length, - Internal::ProgressData *progress, - const bool childRule, - const QList<QSharedPointer<Internal::Rule> > &rules); - - void assignCurrentContext(); - bool contextChangeRequired(const QString &contextName) const; - void handleContextChange(const QString &contextName, - const QSharedPointer<Internal::HighlightDefinition> &definition, - const bool setCurrent = true); - void changeContext(const QString &contextName, - const QSharedPointer<Internal::HighlightDefinition> &definition, - const bool assignCurrent = true); - - QString currentContextSequence() const; - void mapPersistentSequence(const QString &contextSequence); - void mapLeadingSequence(const QString &contextSequence); - void pushContextSequence(int state); - - void pushDynamicContext(const QSharedPointer<Internal::Context> &baseContext); - - void createWillContinueBlock(); - void analyseConsistencyOfWillContinueBlock(const QString &text); - - void applyFormat(int offset, - int count, - const QString &itemDataName, - const QSharedPointer<Internal::HighlightDefinition> &definition); - - void applyRegionBasedFolding() const; - void applyIndentationBasedFolding(const QString &text) const; - int neighbouringNonEmptyBlockIndent(QTextBlock block, const bool previous) const; - - static TextBlockUserData *blockData(QTextBlockUserData *userData); - - // Block states are composed by the region depth (used for code folding) and what I call - // observable states. Observable states occupy the 12 least significant bits. They might have - // the following values: - // - Default [0]: Nothing special. - // - WillContinue [1]: When there is match of the LineContinue rule (backslash as the last - // character). - // - Continued [2]: Blocks that happen after a WillContinue block and continue from their - // context until the next line end. - // - Persistent(s) [Anything >= 3]: Correspond to persistent contexts which last until a pop - // occurs due to a matching rule. Every sequence of persistent contexts seen so far is - // associated with a number (incremented by a unit each time). - // Region depths occupy the remaining bits. - enum ObservableBlockState { - Default = 0, - WillContinue, - Continued, - PersistentsStart - }; - int computeState(const int observableState) const; - - static int extractRegionDepth(const int state); - static int extractObservableState(const int state); - - int m_regionDepth = 0; - bool m_indentationBasedFolding = false; - const TabSettings *m_tabSettings = nullptr; - - int m_persistentObservableStatesCounter = PersistentsStart; - int m_dynamicContextsCounter = 0; - - bool m_isBroken = false; - - QSharedPointer<Internal::Context> m_defaultContext; - QSharedPointer<Internal::Context> m_currentContext; - QVector<QSharedPointer<Internal::Context> > m_contexts; - - // Mapping from context sequences to the observable persistent state they represent. - QHash<QString, int> m_persistentObservableStates; - // Mapping from context sequences to the non-persistent observable state that led to them. - QHash<QString, int> m_leadingObservableStates; - // Mapping from observable persistent states to context sequences (the actual "stack"). - QHash<int, QVector<QSharedPointer<Internal::Context> > > m_persistentContexts; - - // Captures used in dynamic rules. - QStringList m_currentCaptures; -}; - -} // namespace TextEditor diff --git a/src/plugins/texteditor/generichighlighter/highlighterexception.h b/src/plugins/texteditor/generichighlighter/highlighterexception.h deleted file mode 100644 index 0850656966..0000000000 --- a/src/plugins/texteditor/generichighlighter/highlighterexception.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include <QString> - -namespace TextEditor { -namespace Internal { -class HighlighterException -{ -public: - HighlighterException(const QString &msg) : m_message(msg) {} - QString message() const { return m_message; } - -private: - QString m_message; -}; -} -} // namespace TextEditor diff --git a/src/plugins/texteditor/generichighlighter/highlightersettingspage.cpp b/src/plugins/texteditor/generichighlighter/highlightersettingspage.cpp deleted file mode 100644 index d43c528e08..0000000000 --- a/src/plugins/texteditor/generichighlighter/highlightersettingspage.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "highlightersettingspage.h" -#include "highlightersettings.h" -#include "manager.h" -#include "managedefinitionsdialog.h" -#include "ui_highlightersettingspage.h" - -#include <coreplugin/icore.h> - -#include <QMessageBox> -#include <QPointer> - -using namespace TextEditor; -using namespace Internal; - -struct HighlighterSettingsPage::HighlighterSettingsPagePrivate -{ - explicit HighlighterSettingsPagePrivate(Core::Id id); - void ensureInitialized(); - - bool m_initialized; - const Core::Id m_id; - const QString m_displayName; - const QString m_settingsPrefix; - - HighlighterSettings m_settings; - - QPointer<QWidget> m_widget; - Ui::HighlighterSettingsPage *m_page; -}; - -HighlighterSettingsPage::HighlighterSettingsPagePrivate:: -HighlighterSettingsPagePrivate(Core::Id id) : - m_initialized(false), - m_id(id), - m_displayName(tr("Generic Highlighter")), - m_settingsPrefix(QLatin1String("Text")), - m_page(nullptr) -{} - -void HighlighterSettingsPage::HighlighterSettingsPagePrivate::ensureInitialized() -{ - if (m_initialized) - return; - m_initialized = true; - m_settings.fromSettings(m_settingsPrefix, Core::ICore::settings()); -} - -HighlighterSettingsPage::HighlighterSettingsPage(Core::Id id, QObject *parent) : - TextEditorOptionsPage(parent), - m_requestHighlightFileRegistration(false), - m_d(new HighlighterSettingsPagePrivate(id)) -{ - setId(m_d->m_id); - setDisplayName(m_d->m_displayName); -} - -HighlighterSettingsPage::~HighlighterSettingsPage() -{ - delete m_d; -} - -QWidget *HighlighterSettingsPage::widget() -{ - if (!m_d->m_widget) { - m_d->m_widget = new QWidget; - m_d->m_page = new Ui::HighlighterSettingsPage; - m_d->m_page->setupUi(m_d->m_widget); - m_d->m_page->definitionFilesPath->setExpectedKind(Utils::PathChooser::ExistingDirectory); - m_d->m_page->definitionFilesPath->setHistoryCompleter(QLatin1String("TextEditor.Highlighter.History")); - m_d->m_page->definitionFilesPath->addButton(tr("Download Definitions..."), this, - [this] { requestAvailableDefinitionsMetaData(); }); - m_d->m_page->fallbackDefinitionFilesPath->setExpectedKind(Utils::PathChooser::ExistingDirectory); - m_d->m_page->fallbackDefinitionFilesPath->setHistoryCompleter(QLatin1String("TextEditor.Highlighter.History")); - m_d->m_page->fallbackDefinitionFilesPath->addButton(tr("Autodetect"), this, - [this] { resetDefinitionsLocation(); }); - - settingsToUI(); - - connect(m_d->m_page->useFallbackLocation, &QAbstractButton::clicked, - this, &HighlighterSettingsPage::setFallbackLocationState); - connect(m_d->m_page->definitionFilesPath, &Utils::PathChooser::validChanged, - this, &HighlighterSettingsPage::setDownloadDefinitionsState); - connect(m_d->m_widget.data(), &QObject::destroyed, - this, &HighlighterSettingsPage::ignoreDownloadReply); - } - return m_d->m_widget; -} - -void HighlighterSettingsPage::apply() -{ - if (!m_d->m_page) // page was not shown - return; - if (settingsChanged()) - settingsFromUI(); - - if (m_requestHighlightFileRegistration) { - Manager::instance()->registerHighlightingFiles(); - m_requestHighlightFileRegistration = false; - } -} - -void HighlighterSettingsPage::finish() -{ - delete m_d->m_widget; - if (!m_d->m_page) // page was not shown - return; - delete m_d->m_page; - m_d->m_page = nullptr; -} - -const HighlighterSettings &HighlighterSettingsPage::highlighterSettings() const -{ - m_d->ensureInitialized(); - return m_d->m_settings; -} - -void HighlighterSettingsPage::settingsFromUI() -{ - m_d->ensureInitialized(); - if (!m_requestHighlightFileRegistration && ( - m_d->m_settings.definitionFilesPath() != m_d->m_page->definitionFilesPath->path() || - m_d->m_settings.fallbackDefinitionFilesPath() != - m_d->m_page->fallbackDefinitionFilesPath->path() || - m_d->m_settings.useFallbackLocation() != m_d->m_page->useFallbackLocation->isChecked())) { - m_requestHighlightFileRegistration = true; - } - - m_d->m_settings.setDefinitionFilesPath(m_d->m_page->definitionFilesPath->path()); - m_d->m_settings.setFallbackDefinitionFilesPath(m_d->m_page->fallbackDefinitionFilesPath->path()); - m_d->m_settings.setUseFallbackLocation(m_d->m_page->useFallbackLocation->isChecked()); - m_d->m_settings.setIgnoredFilesPatterns(m_d->m_page->ignoreEdit->text()); - m_d->m_settings.toSettings(m_d->m_settingsPrefix, Core::ICore::settings()); -} - -void HighlighterSettingsPage::settingsToUI() -{ - m_d->ensureInitialized(); - m_d->m_page->definitionFilesPath->setPath(m_d->m_settings.definitionFilesPath()); - m_d->m_page->fallbackDefinitionFilesPath->setPath(m_d->m_settings.fallbackDefinitionFilesPath()); - m_d->m_page->useFallbackLocation->setChecked(m_d->m_settings.useFallbackLocation()); - m_d->m_page->ignoreEdit->setText(m_d->m_settings.ignoredFilesPatterns()); - - setFallbackLocationState(m_d->m_page->useFallbackLocation->isChecked()); - setDownloadDefinitionsState(m_d->m_page->definitionFilesPath->isValid()); -} - -void HighlighterSettingsPage::resetDefinitionsLocation() -{ - const QString &location = findFallbackDefinitionsLocation(); - if (location.isEmpty()) { - QMessageBox::information(Core::ICore::dialogParent(), tr("Autodetect Definitions"), - tr("No pre-installed definitions could be found.")); - } else { - m_d->m_page->fallbackDefinitionFilesPath->setPath(location); - } -} - -void HighlighterSettingsPage::requestAvailableDefinitionsMetaData() -{ - setDownloadDefinitionsState(false); - - connect(Manager::instance(), &Manager::definitionsMetaDataReady, - this, &HighlighterSettingsPage::manageDefinitions, Qt::UniqueConnection); - connect(Manager::instance(), &Manager::errorDownloadingDefinitionsMetaData, - this, &HighlighterSettingsPage::showError, Qt::UniqueConnection); - Manager::instance()->downloadAvailableDefinitionsMetaData(); -} - -void HighlighterSettingsPage::ignoreDownloadReply() -{ - disconnect(Manager::instance(), &Manager::definitionsMetaDataReady, - this, &HighlighterSettingsPage::manageDefinitions); - disconnect(Manager::instance(), &Manager::errorDownloadingDefinitionsMetaData, - this, &HighlighterSettingsPage::showError); -} - -void HighlighterSettingsPage::manageDefinitions(const QList<DefinitionMetaDataPtr> &metaData) -{ - ManageDefinitionsDialog dialog(metaData, - m_d->m_page->definitionFilesPath->path() + QLatin1Char('/'), - m_d->m_page->definitionFilesPath->buttonAtIndex(1)->window()); - if (dialog.exec() && !m_requestHighlightFileRegistration) - m_requestHighlightFileRegistration = true; - setDownloadDefinitionsState(m_d->m_page->definitionFilesPath->isValid()); -} - -void HighlighterSettingsPage::showError() -{ - QMessageBox::critical(m_d->m_page->definitionFilesPath->buttonAtIndex(1)->window(), - tr("Error connecting to server."), - tr("Not possible to retrieve data.")); - setDownloadDefinitionsState(m_d->m_page->definitionFilesPath->isValid()); -} - -void HighlighterSettingsPage::setFallbackLocationState(bool checked) -{ - m_d->m_page->fallbackDefinitionFilesPath->setEnabled(checked); -} - -void HighlighterSettingsPage::setDownloadDefinitionsState(bool valid) -{ - m_d->m_page->definitionFilesPath->buttonAtIndex(1)->setEnabled(valid); -} - -bool HighlighterSettingsPage::settingsChanged() const -{ - m_d->ensureInitialized(); - if (m_d->m_settings.definitionFilesPath() != m_d->m_page->definitionFilesPath->path()) - return true; - if (m_d->m_settings.fallbackDefinitionFilesPath() != - m_d->m_page->fallbackDefinitionFilesPath->path()) - return true; - if (m_d->m_settings.useFallbackLocation() != m_d->m_page->useFallbackLocation->isChecked()) - return true; - if (m_d->m_settings.ignoredFilesPatterns() != m_d->m_page->ignoreEdit->text()) - return true; - return false; -} diff --git a/src/plugins/texteditor/generichighlighter/includerulesinstruction.cpp b/src/plugins/texteditor/generichighlighter/includerulesinstruction.cpp deleted file mode 100644 index b9e30319ab..0000000000 --- a/src/plugins/texteditor/generichighlighter/includerulesinstruction.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "includerulesinstruction.h" -#include "reuse.h" - -using namespace TextEditor; -using namespace Internal; - -IncludeRulesInstruction::IncludeRulesInstruction(const QString &context, - int hint, - const QString &replaceItemData) : - m_sourceContext(context), m_indexHint(hint), m_replaceItemData(toBool(replaceItemData)) -{ -} - -const QString &IncludeRulesInstruction::sourceContext() const -{ return m_sourceContext; } - -int IncludeRulesInstruction::indexHint() const -{ return m_indexHint; } - -bool IncludeRulesInstruction::replaceItemData() const -{ return m_replaceItemData; } diff --git a/src/plugins/texteditor/generichighlighter/includerulesinstruction.h b/src/plugins/texteditor/generichighlighter/includerulesinstruction.h deleted file mode 100644 index aefdc42bb7..0000000000 --- a/src/plugins/texteditor/generichighlighter/includerulesinstruction.h +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include <QString> - -namespace TextEditor { -namespace Internal { - -class IncludeRulesInstruction -{ -public: - IncludeRulesInstruction(const QString &context, int hint, const QString &replaceItemData); - - const QString &sourceContext() const; - int indexHint() const; - bool replaceItemData() const; - -private: - QString m_sourceContext; - int m_indexHint; - bool m_replaceItemData; -}; - -} // namespace Internal -} // namespace TextEditor diff --git a/src/plugins/texteditor/generichighlighter/itemdata.cpp b/src/plugins/texteditor/generichighlighter/itemdata.cpp deleted file mode 100644 index e7ae9b9533..0000000000 --- a/src/plugins/texteditor/generichighlighter/itemdata.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "itemdata.h" -#include "reuse.h" - -using namespace TextEditor; -using namespace Internal; - -ItemData::ItemData() : - m_italic(false), - m_italicSpecified(false), - m_bold(false), - m_boldSpecified(false), - m_underlined(false), - m_underlinedSpecified(false), - m_strikedOut(false), - m_strikeOutSpecified(false), - m_isCustomized(false) -{} - -void ItemData::setStyle(const QString &style) -{ m_style = style; } - -const QString &ItemData::style() const -{ return m_style; } - -void ItemData::setColor(const QString &color) -{ - if (!color.isEmpty()) { - m_color.setNamedColor(color); - m_isCustomized = true; - } -} - -const QColor &ItemData::color() const -{ return m_color; } - -void ItemData::setSelectionColor(const QString &color) -{ - if (!color.isEmpty()) { - m_selectionColor.setNamedColor(color); - m_isCustomized = true; - } -} - -const QColor &ItemData::selectionColor() const -{ return m_selectionColor; } - -void ItemData::setItalic(const QString &italic) -{ - if (!italic.isEmpty()) { - m_italic = toBool(italic); - m_italicSpecified = true; - m_isCustomized = true; - } -} - -bool ItemData::isItalic() const -{ return m_italic; } - -bool ItemData::isItalicSpecified() const -{ return m_italicSpecified; } - -void ItemData::setBold(const QString &bold) -{ - if (!bold.isEmpty()) { - m_bold = toBool(bold); - m_boldSpecified = true; - m_isCustomized = true; - } -} - -bool ItemData::isBold() const -{ return m_bold; } - -bool ItemData::isBoldSpecified() const -{ return m_boldSpecified; } - -void ItemData::setUnderlined(const QString &underlined) -{ - if (!underlined.isEmpty()) { - m_underlined = toBool(underlined); - m_underlinedSpecified = true; - m_isCustomized = true; - } -} - -bool ItemData::isUnderlined() const -{ return m_underlined; } - -bool ItemData::isUnderlinedSpecified() const -{ return m_underlinedSpecified; } - -void ItemData::setStrikeOut(const QString &strike) -{ - if (!strike.isEmpty()) { - m_strikedOut = toBool(strike); - m_strikeOutSpecified = true; - m_isCustomized = true; - } -} - -bool ItemData::isStrikeOut() const -{ return m_strikedOut; } - -bool ItemData::isStrikeOutSpecified() const -{ return m_strikeOutSpecified; } - -bool ItemData::isCustomized() const -{ return m_isCustomized; } diff --git a/src/plugins/texteditor/generichighlighter/itemdata.h b/src/plugins/texteditor/generichighlighter/itemdata.h deleted file mode 100644 index 538d61ebde..0000000000 --- a/src/plugins/texteditor/generichighlighter/itemdata.h +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include <QString> -#include <QColor> - -namespace TextEditor { -namespace Internal { - -class ItemData -{ -public: - ItemData(); - - void setStyle(const QString &style); - const QString &style() const; - - void setColor(const QString &color); - const QColor &color() const; - - void setSelectionColor(const QString &color); - const QColor &selectionColor() const; - - void setItalic(const QString &italic); - bool isItalic() const; - bool isItalicSpecified() const; - - void setBold(const QString &bold); - bool isBold() const; - bool isBoldSpecified() const; - - void setUnderlined(const QString &underlined); - bool isUnderlined() const; - bool isUnderlinedSpecified() const; - - void setStrikeOut(const QString &strike); - bool isStrikeOut() const; - bool isStrikeOutSpecified() const; - - bool isCustomized() const; - -private: - bool m_italic; - bool m_italicSpecified; - bool m_bold; - bool m_boldSpecified; - bool m_underlined; - bool m_underlinedSpecified; - bool m_strikedOut; - bool m_strikeOutSpecified; - bool m_isCustomized; - QString m_style; - QColor m_color; - QColor m_selectionColor; -}; - -} // namespace Internal -} // namespace TextEditor diff --git a/src/plugins/texteditor/generichighlighter/keywordlist.cpp b/src/plugins/texteditor/generichighlighter/keywordlist.cpp deleted file mode 100644 index 86e7403f85..0000000000 --- a/src/plugins/texteditor/generichighlighter/keywordlist.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "keywordlist.h" - -using namespace TextEditor; -using namespace Internal; - -void KeywordList::addKeyword(const QString &keyword) -{ - if (keyword.isEmpty()) - return; - - m_keywords.insert(keyword); -} - -bool KeywordList::isKeyword(const QString &keyword, Qt::CaseSensitivity sensitivity) const -{ - if (keyword.isEmpty()) - return false; - - // Case sensitivity could be implemented, for example, by converting all keywords to lower - // if the global sensitivity attribute is insensitive, then always checking for containment - // (with a conversion to lower in the necessary cases). But the code below is one alternative - // to support the existence of local sensitivity attributes (which override the global one - - // currently not documented). - if (sensitivity == Qt::CaseSensitive) { - return m_keywords.contains(keyword); - } else { - foreach (const QString &s, m_keywords) - if (keyword.compare(s, Qt::CaseInsensitive) == 0) - return true; - return false; - } -} diff --git a/src/plugins/texteditor/generichighlighter/keywordlist.h b/src/plugins/texteditor/generichighlighter/keywordlist.h deleted file mode 100644 index f111afa4e0..0000000000 --- a/src/plugins/texteditor/generichighlighter/keywordlist.h +++ /dev/null @@ -1,46 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include <QString> -#include <QSet> - -namespace TextEditor { -namespace Internal { - -class KeywordList -{ -public: - - void addKeyword(const QString &keyword); - bool isKeyword(const QString &keyword, Qt::CaseSensitivity sensitivity) const; - -private: - QSet<QString> m_keywords; -}; - -} // namespace Internal -} // namespace TextEditor diff --git a/src/plugins/texteditor/generichighlighter/managedefinitionsdialog.cpp b/src/plugins/texteditor/generichighlighter/managedefinitionsdialog.cpp deleted file mode 100644 index 1a6aa42ce0..0000000000 --- a/src/plugins/texteditor/generichighlighter/managedefinitionsdialog.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "managedefinitionsdialog.h" -#include "manager.h" - -#include <QUrl> -#include <QIODevice> -#include <QFile> -#include <QFileInfo> -#include <QMessageBox> - -using namespace TextEditor; -using namespace Internal; - -ManageDefinitionsDialog::ManageDefinitionsDialog( - const QList<DefinitionMetaDataPtr> &metaDataList, - const QString &path, - QWidget *parent) : - QDialog(parent), - m_path(path) -{ - ui.setupUi(this); - ui.definitionsTable->setHorizontalHeaderLabels( - QStringList() << tr("Name") << tr("Installed") << tr("Available")); - ui.definitionsTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); - - setWindowTitle(tr("Download Definitions")); - - populateDefinitionsWidget(metaDataList); - ui.definitionsTable->sortItems(0); - - connect(ui.downloadButton, &QPushButton::clicked, this, &ManageDefinitionsDialog::downloadDefinitions); - connect(ui.allButton, &QPushButton::clicked, this, &ManageDefinitionsDialog::selectAll); - connect(ui.clearButton, &QPushButton::clicked, this, &ManageDefinitionsDialog::clearSelection); - connect(ui.invertButton, &QPushButton::clicked, this, &ManageDefinitionsDialog::invertSelection); -} - -void ManageDefinitionsDialog::populateDefinitionsWidget(const QList<DefinitionMetaDataPtr> &definitionsMetaData) -{ - const int size = definitionsMetaData.size(); - ui.definitionsTable->setRowCount(size); - for (int i = 0; i < size; ++i) { - const HighlightDefinitionMetaData &downloadData = *definitionsMetaData.at(i); - - // Look for this definition in the current path specified by the user, not the one - // stored in the settings. So the manager should not be queried for this information. - QString dirVersion; - QFileInfo fi(m_path + downloadData.fileName); - QFile definitionFile(fi.absoluteFilePath()); - if (definitionFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - const DefinitionMetaDataPtr data = Manager::parseMetadata(fi); - if (!data.isNull()) - dirVersion = data->version; - } - - for (int j = 0; j < 3; ++j) { - auto item = new QTableWidgetItem; - if (j == 0) { - item->setText(downloadData.name); - item->setData(Qt::UserRole, downloadData.url); - } else if (j == 1) { - item->setText(dirVersion); - item->setTextAlignment(Qt::AlignCenter); - } else if (j == 2) { - item->setText(downloadData.version); - item->setTextAlignment(Qt::AlignCenter); - } - ui.definitionsTable->setItem(i, j, item); - } - } -} - -void ManageDefinitionsDialog::downloadDefinitions() -{ - if (Manager::instance()->isDownloadingDefinitions()) { - QMessageBox::information( - this, - tr("Download Information"), - tr("There is already one download in progress. Please wait until it is finished.")); - return; - } - - QList<QUrl> urls; - foreach (const QModelIndex &index, ui.definitionsTable->selectionModel()->selectedRows()) { - const QVariant url = ui.definitionsTable->item(index.row(), 0)->data(Qt::UserRole); - urls.append(url.toUrl()); - } - Manager::instance()->downloadDefinitions(urls, m_path); - accept(); -} - -void ManageDefinitionsDialog::selectAll() -{ - ui.definitionsTable->selectAll(); - ui.definitionsTable->setFocus(); -} - -void ManageDefinitionsDialog::clearSelection() -{ - ui.definitionsTable->clearSelection(); -} - -void ManageDefinitionsDialog::invertSelection() -{ - const QModelIndex &topLeft = ui.definitionsTable->model()->index(0, 0); - const QModelIndex &bottomRight = - ui.definitionsTable->model()->index(ui.definitionsTable->rowCount() - 1, - ui.definitionsTable->columnCount() - 1); - QItemSelection itemSelection(topLeft, bottomRight); - ui.definitionsTable->selectionModel()->select(itemSelection, QItemSelectionModel::Toggle); - ui.definitionsTable->setFocus(); -} diff --git a/src/plugins/texteditor/generichighlighter/managedefinitionsdialog.h b/src/plugins/texteditor/generichighlighter/managedefinitionsdialog.h deleted file mode 100644 index 3a5512dcec..0000000000 --- a/src/plugins/texteditor/generichighlighter/managedefinitionsdialog.h +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include "ui_managedefinitionsdialog.h" -#include "highlightdefinitionmetadata.h" - -namespace TextEditor { -namespace Internal { - -class ManageDefinitionsDialog : public QDialog -{ - Q_OBJECT - -public: - explicit ManageDefinitionsDialog(const QList<DefinitionMetaDataPtr> &metaDataList, - const QString &path, - QWidget *parent = nullptr); - -private: - void downloadDefinitions(); - void selectAll(); - void clearSelection(); - void invertSelection(); - void populateDefinitionsWidget(const QList<DefinitionMetaDataPtr> &definitionsMetaData); - - QString m_path; - Ui::ManageDefinitionsDialog ui; -}; - -} // namespace Internal -} // namespace TextEditor diff --git a/src/plugins/texteditor/generichighlighter/managedefinitionsdialog.ui b/src/plugins/texteditor/generichighlighter/managedefinitionsdialog.ui deleted file mode 100644 index adab90f7d2..0000000000 --- a/src/plugins/texteditor/generichighlighter/managedefinitionsdialog.ui +++ /dev/null @@ -1,158 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>TextEditor::Internal::ManageDefinitionsDialog</class> - <widget class="QDialog" name="TextEditor::Internal::ManageDefinitionsDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>586</width> - <height>280</height> - </rect> - </property> - <property name="windowTitle"> - <string>Dialog</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QGroupBox" name="definitionsGroupBox"> - <property name="title"> - <string>Definitions</string> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0" rowspan="4"> - <widget class="QTableWidget" name="definitionsTable"> - <property name="editTriggers"> - <set>QAbstractItemView::NoEditTriggers</set> - </property> - <property name="alternatingRowColors"> - <bool>false</bool> - </property> - <property name="selectionMode"> - <enum>QAbstractItemView::ExtendedSelection</enum> - </property> - <property name="selectionBehavior"> - <enum>QAbstractItemView::SelectRows</enum> - </property> - <property name="showGrid"> - <bool>false</bool> - </property> - <property name="gridStyle"> - <enum>Qt::NoPen</enum> - </property> - <property name="sortingEnabled"> - <bool>true</bool> - </property> - <property name="columnCount"> - <number>3</number> - </property> - <attribute name="horizontalHeaderHighlightSections"> - <bool>false</bool> - </attribute> - <attribute name="horizontalHeaderShowSortIndicator" stdset="0"> - <bool>true</bool> - </attribute> - <attribute name="verticalHeaderVisible"> - <bool>false</bool> - </attribute> - <attribute name="verticalHeaderDefaultSectionSize"> - <number>20</number> - </attribute> - <attribute name="verticalHeaderHighlightSections"> - <bool>false</bool> - </attribute> - <column/> - <column/> - <column/> - </widget> - </item> - <item row="0" column="1"> - <widget class="QPushButton" name="allButton"> - <property name="text"> - <string>Select All</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QPushButton" name="clearButton"> - <property name="text"> - <string>Clear Selection</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QPushButton" name="invertButton"> - <property name="text"> - <string>Invert Selection</string> - </property> - </widget> - </item> - <item row="3" column="1"> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>244</height> - </size> - </property> - </spacer> - </item> - <item row="4" column="0" colspan="2"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QPushButton" name="downloadButton"> - <property name="text"> - <string>Download Selected Definitions</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>188</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="standardButtons"> - <set>QDialogButtonBox::Close</set> - </property> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>rejected()</signal> - <receiver>TextEditor::Internal::ManageDefinitionsDialog</receiver> - <slot>close()</slot> - <hints> - <hint type="sourcelabel"> - <x>385</x> - <y>420</y> - </hint> - <hint type="destinationlabel"> - <x>223</x> - <y>222</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/src/plugins/texteditor/generichighlighter/manager.cpp b/src/plugins/texteditor/generichighlighter/manager.cpp deleted file mode 100644 index 32da7ca4e5..0000000000 --- a/src/plugins/texteditor/generichighlighter/manager.cpp +++ /dev/null @@ -1,507 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "manager.h" -#include "highlightdefinition.h" -#include "highlightdefinitionhandler.h" -#include "highlighterexception.h" -#include "definitiondownloader.h" -#include "highlightersettings.h" -#include <texteditor/plaintexteditorfactory.h> -#include <texteditor/texteditorconstants.h> -#include <texteditor/texteditorsettings.h> - -#include <coreplugin/icore.h> -#include <coreplugin/messagemanager.h> -#include <coreplugin/progressmanager/progressmanager.h> -#include <utils/algorithm.h> -#include <utils/mapreduce.h> -#include <utils/mimetypes/mimedatabase.h> -#include <utils/networkaccessmanager.h> - -#include <QCoreApplication> -#include <QString> -#include <QStringList> -#include <QFile> -#include <QFileInfo> -#include <QDir> -#include <QRegExp> -#include <QFuture> -#include <QtConcurrentMap> -#include <QUrl> -#include <QSet> -#include <QXmlStreamReader> -#include <QXmlStreamAttributes> -#include <QMessageBox> -#include <QXmlSimpleReader> -#include <QXmlInputSource> -#include <QNetworkRequest> -#include <QNetworkReply> - -using namespace Core; - -namespace TextEditor { -namespace Internal { - -const char kPriority[] = "priority"; -const char kName[] = "name"; -const char kExtensions[] = "extensions"; -const char kMimeType[] = "mimetype"; -const char kVersion[] = "version"; -const char kUrl[] = "url"; - -class MultiDefinitionDownloader : public QObject -{ - Q_OBJECT - -public: - MultiDefinitionDownloader(const QString &savePath, const QList<QString> &installedDefinitions) : - m_installedDefinitions(installedDefinitions), - m_downloadPath(savePath) - { - connect(&m_downloadWatcher, &QFutureWatcherBase::finished, - this, &MultiDefinitionDownloader::downloadDefinitionsFinished); - } - - ~MultiDefinitionDownloader() override - { - if (m_downloadWatcher.isRunning()) - m_downloadWatcher.cancel(); - } - - void downloadDefinitions(const QList<QUrl> &urls); - -signals: - void finished(); - -private: - void downloadReferencedDefinition(const QString &name); - void downloadDefinitionsFinished(); - - QFutureWatcher<void> m_downloadWatcher; - QList<DefinitionDownloader *> m_downloaders; - QList<QString> m_installedDefinitions; - QSet<QString> m_referencedDefinitions; - QString m_downloadPath; -}; - -Manager::Manager() -{ - connect(&m_registeringWatcher, &QFutureWatcherBase::finished, - this, &Manager::registerHighlightingFilesFinished); -} - -Manager::~Manager() -{ - disconnect(&m_registeringWatcher); - disconnect(m_multiDownloader); - if (m_registeringWatcher.isRunning()) - m_registeringWatcher.cancel(); - delete m_multiDownloader; -} - -Manager *Manager::instance() -{ - static Manager manager; - return &manager; -} - -QString Manager::definitionIdByName(const QString &name) const -{ - return m_register.m_idByName.value(name); -} - -static bool matchesPattern(const QString &fileName, DefinitionMetaDataPtr metaData) -{ - if (metaData.isNull()) - return false; - foreach (const QString &pattern, metaData->patterns) { - QRegExp reg(pattern, Qt::CaseSensitive, QRegExp::Wildcard); - if (reg.exactMatch(fileName)) - return true; - } - return false; -} - -QString Manager::definitionIdByMimeType(const Utils::MimeType &mimeType) const -{ - QList<Utils::MimeType> queue; - queue.append(mimeType); - while (!queue.isEmpty()) { - const Utils::MimeType mt = queue.takeFirst(); - const QString id = m_register.m_idByMimeType.value(mt.name()); - if (!id.isEmpty()) - return id; - foreach (const QString &parent, mt.parentMimeTypes()) { - const Utils::MimeType parentMt = Utils::mimeTypeForName(parent); - if (parentMt.isValid()) - queue.append(parentMt); - } - } - return QString(); -} - -QString Manager::definitionIdByFile(const QString &filePath) const -{ - const QString fileName = QFileInfo(filePath).fileName(); - // find best match - QString bestId; - int bestPriority = -1; - auto it = m_register.m_definitionsMetaData.constBegin(); - while (it != m_register.m_definitionsMetaData.constEnd()) { - DefinitionMetaDataPtr metaData = it.value(); - if (metaData->priority > bestPriority && matchesPattern(fileName, metaData)) { - bestId = metaData->id; - bestPriority = metaData->priority; - } - ++it; - } - return bestId; -} - -QString Manager::definitionIdByMimeTypeAndFile(const Utils::MimeType &mimeType, - const QString &filePath) const -{ - QString id = definitionIdByMimeType(mimeType); - if (!filePath.isEmpty()) { - QString idByFile; - const QString fileName = QFileInfo(filePath).fileName(); - // if mime type check returned no result, or doesn't match the patterns, - // prefer a match by pattern - if (id.isEmpty() || !matchesPattern(fileName, m_register.m_definitionsMetaData.value(id))) - idByFile = definitionIdByFile(filePath); - if (!idByFile.isEmpty()) - id = idByFile; - } - return id; -} - -DefinitionMetaDataPtr Manager::availableDefinitionByName(const QString &name) const -{ - return m_availableDefinitions.value(name); -} - -QSharedPointer<HighlightDefinition> Manager::definition(const QString &id) -{ - if (!id.isEmpty() && !m_definitions.contains(id)) { - QFile definitionFile(id); - if (!definitionFile.open(QIODevice::ReadOnly | QIODevice::Text)) - return QSharedPointer<HighlightDefinition>(); - - QSharedPointer<HighlightDefinition> definition(new HighlightDefinition); - HighlightDefinitionHandler handler(definition); - - QXmlInputSource source(&definitionFile); - QXmlSimpleReader reader; - reader.setContentHandler(&handler); - m_isBuildingDefinition.insert(id); - try { - reader.parse(source); - } catch (const HighlighterException &e) { - MessageManager::write( - QCoreApplication::translate("GenericHighlighter", - "Generic highlighter error: ") + e.message(), - MessageManager::WithFocus); - definition.clear(); - } - m_isBuildingDefinition.remove(id); - definitionFile.close(); - - m_definitions.insert(id, definition); - } - - return m_definitions.value(id); -} - -DefinitionMetaDataPtr Manager::definitionMetaData(const QString &id) const -{ - return m_register.m_definitionsMetaData.value(id); -} - -bool Manager::isBuildingDefinition(const QString &id) const -{ - return m_isBuildingDefinition.contains(id); -} - -static const int kMaxProgress = 200; - -static void processHighlightingFiles(QFutureInterface<Manager::RegisterData> &future, - QStringList definitionPaths) -{ - future.setProgressRange(0, kMaxProgress); - - Manager::RegisterData data; - // iterate through paths in order, high priority > low priority - foreach (const QString &path, definitionPaths) { - if (path.isEmpty()) - continue; - - QDir definitionsDir(path); - QStringList filter(QLatin1String("*.xml")); - definitionsDir.setNameFilters(filter); - foreach (const QFileInfo &fileInfo, definitionsDir.entryInfoList()) { - if (future.isCanceled()) - return; - if (future.progressValue() < kMaxProgress - 1) - future.setProgressValue(future.progressValue() + 1); - - const DefinitionMetaDataPtr &metaData = - Manager::parseMetadata(fileInfo); - // skip failing or already existing definitions - if (!metaData.isNull() && !data.m_idByName.contains(metaData->name)) { - const QString id = metaData->id; - data.m_idByName.insert(metaData->name, id); - data.m_definitionsMetaData.insert(id, metaData); - foreach (const QString &mt, metaData->mimeTypes) { - bool insert = true; - // check if there is already a definition registered with higher priority - const QString existingDefinition = data.m_idByMimeType.value(mt); - if (!existingDefinition.isEmpty()) { - // check priorities - DefinitionMetaDataPtr existingMetaData = - data.m_definitionsMetaData.value(existingDefinition); - if (!existingMetaData.isNull() && existingMetaData->priority > metaData->priority) - insert = false; - } - if (insert) - data.m_idByMimeType.insert(mt, id); - } - } - } - } - - future.reportResult(data); -} - -void Manager::registerHighlightingFiles() -{ - if (!m_registeringWatcher.isRunning()) { - clear(); - - QStringList definitionsPaths; - const HighlighterSettings &settings = TextEditorSettings::highlighterSettings(); - definitionsPaths.append(settings.definitionFilesPath()); - if (settings.useFallbackLocation()) - definitionsPaths.append(settings.fallbackDefinitionFilesPath()); - - QFuture<RegisterData> future = Utils::runAsync(processHighlightingFiles, definitionsPaths); - m_registeringWatcher.setFuture(future); - } else { - m_hasQueuedRegistration = true; - m_registeringWatcher.cancel(); - } -} - -void Manager::registerHighlightingFilesFinished() -{ - if (m_hasQueuedRegistration) { - m_hasQueuedRegistration = false; - registerHighlightingFiles(); - } else if (!m_registeringWatcher.isCanceled()) { - m_register = m_registeringWatcher.result(); - - emit highlightingFilesRegistered(); - } -} - -DefinitionMetaDataPtr Manager::parseMetadata(const QFileInfo &fileInfo) -{ - static const QLatin1Char kSemiColon(';'); - static const QLatin1String kLanguage("language"); - - QFile definitionFile(fileInfo.absoluteFilePath()); - if (!definitionFile.open(QIODevice::ReadOnly | QIODevice::Text)) - return DefinitionMetaDataPtr(); - - DefinitionMetaDataPtr metaData(new HighlightDefinitionMetaData); - - QXmlStreamReader reader(&definitionFile); - while (!reader.atEnd() && !reader.hasError()) { - if (reader.readNext() == QXmlStreamReader::StartElement && reader.name() == kLanguage) { - const QXmlStreamAttributes &atts = reader.attributes(); - - metaData->fileName = fileInfo.fileName(); - metaData->id = fileInfo.absoluteFilePath(); - metaData->name = atts.value(QLatin1String(kName)).toString(); - metaData->version = atts.value(QLatin1String(kVersion)).toString(); - metaData->priority = atts.value(QLatin1String(kPriority)).toString().toInt(); - metaData->patterns = atts.value(QLatin1String(kExtensions)) - .toString().split(kSemiColon, QString::SkipEmptyParts); - - metaData->mimeTypes = atts.value(QLatin1String(kMimeType)). - toString().split(kSemiColon, QString::SkipEmptyParts); - break; - } - } - reader.clear(); - definitionFile.close(); - - return metaData; -} - -QList<DefinitionMetaDataPtr> Manager::parseAvailableDefinitionsList(QIODevice *device) -{ - static const QLatin1Char kSlash('/'); - static const QLatin1String kDefinition("Definition"); - - m_availableDefinitions.clear(); - QXmlStreamReader reader(device); - while (!reader.atEnd() && !reader.hasError()) { - if (reader.readNext() == QXmlStreamReader::StartElement && - reader.name() == kDefinition) { - const QXmlStreamAttributes &atts = reader.attributes(); - - DefinitionMetaDataPtr metaData(new HighlightDefinitionMetaData); - metaData->name = atts.value(QLatin1String(kName)).toString(); - metaData->version = atts.value(QLatin1String(kVersion)).toString(); - QString url = atts.value(QLatin1String(kUrl)).toString(); - metaData->url = QUrl(url); - const int slash = url.lastIndexOf(kSlash); - if (slash != -1) - metaData->fileName = url.right(url.length() - slash - 1); - - m_availableDefinitions.insert(metaData->name, metaData); - } - } - reader.clear(); - - return m_availableDefinitions.values(); -} - -void Manager::downloadAvailableDefinitionsMetaData() -{ - QUrl url(QLatin1String("https://www.kate-editor.org/syntax/update-5.60.xml")); - QNetworkRequest request(url); - // Currently this takes a couple of seconds on Windows 7: QTBUG-10106. - QNetworkReply *reply = Utils::NetworkAccessManager::instance()->get(request); - connect(reply, &QNetworkReply::finished, - this, &Manager::downloadAvailableDefinitionsListFinished); -} - -void Manager::downloadAvailableDefinitionsListFinished() -{ - if (auto reply = qobject_cast<QNetworkReply *>(sender())) { - if (reply->error() == QNetworkReply::NoError) - emit definitionsMetaDataReady(parseAvailableDefinitionsList(reply)); - else - emit errorDownloadingDefinitionsMetaData(); - reply->deleteLater(); - } -} - -void Manager::downloadDefinitions(const QList<QUrl> &urls, const QString &savePath) -{ - m_multiDownloader = new MultiDefinitionDownloader(savePath, m_register.m_idByName.keys()); - connect(m_multiDownloader, &MultiDefinitionDownloader::finished, - this, &Manager::downloadDefinitionsFinished); - m_multiDownloader->downloadDefinitions(urls); -} - -void MultiDefinitionDownloader::downloadDefinitions(const QList<QUrl> &urls) -{ - m_downloaders.clear(); - foreach (const QUrl &url, urls) { - auto downloader = new DefinitionDownloader(url, m_downloadPath); - connect(downloader, &DefinitionDownloader::foundReferencedDefinition, - this, &MultiDefinitionDownloader::downloadReferencedDefinition); - m_downloaders.append(downloader); - } - - QFuture<void> future = Utils::map(m_downloaders, &DefinitionDownloader::run); - m_downloadWatcher.setFuture(future); - ProgressManager::addTask(future, tr("Downloading Highlighting Definitions"), - "TextEditor.Task.Download"); -} - -void MultiDefinitionDownloader::downloadDefinitionsFinished() -{ - int errors = 0; - bool writeError = false; - foreach (DefinitionDownloader *downloader, m_downloaders) { - DefinitionDownloader::Status status = downloader->status(); - if (status != DefinitionDownloader::Ok) { - ++errors; - if (status == DefinitionDownloader::WriteError && !writeError) - writeError = true; - } - delete downloader; - } - - if (errors > 0) { - QString text; - if (errors == m_downloaders.size()) - text = tr("Error downloading selected definition(s)."); - else - text = tr("Error downloading one or more definitions."); - if (writeError) - text.append(QLatin1Char('\n') + tr("Please check the directory's access rights.")); - QMessageBox::critical(Core::ICore::dialogParent(), tr("Download Error"), text); - } - - QList<QUrl> urls; - foreach (const QString &definition, m_referencedDefinitions) { - if (DefinitionMetaDataPtr metaData = - Manager::instance()->availableDefinitionByName(definition)) { - urls << metaData->url; - } - } - m_referencedDefinitions.clear(); - if (urls.isEmpty()) - emit finished(); - else - downloadDefinitions(urls); -} - -void Manager::downloadDefinitionsFinished() -{ - delete m_multiDownloader; - m_multiDownloader = nullptr; -} - -void MultiDefinitionDownloader::downloadReferencedDefinition(const QString &name) -{ - if (m_installedDefinitions.contains(name)) - return; - m_referencedDefinitions.insert(name); - m_installedDefinitions.append(name); -} - -bool Manager::isDownloadingDefinitions() const -{ - return m_multiDownloader != nullptr; -} - -void Manager::clear() -{ - m_register.m_idByName.clear(); - m_register.m_idByMimeType.clear(); - m_register.m_definitionsMetaData.clear(); - m_definitions.clear(); -} - -} // namespace Internal -} // namespace TextEditor - -#include "manager.moc" diff --git a/src/plugins/texteditor/generichighlighter/manager.h b/src/plugins/texteditor/generichighlighter/manager.h deleted file mode 100644 index 18a6c3016f..0000000000 --- a/src/plugins/texteditor/generichighlighter/manager.h +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include "highlightdefinitionmetadata.h" - -#include <QString> -#include <QHash> -#include <QSet> -#include <QUrl> -#include <QList> -#include <QPair> -#include <QSharedPointer> -#include <QFutureWatcher> - -QT_BEGIN_NAMESPACE -class QFileInfo; -class QIODevice; -template <class> class QFutureInterface; -QT_END_NAMESPACE - -namespace Utils { class MimeType; } - -namespace TextEditor { -namespace Internal { - -class HighlightDefinition; -class ManagerProcessor; -class MultiDefinitionDownloader; - -// This is the generic highlighter manager. It is not thread-safe. - -class Manager : public QObject -{ - Q_OBJECT -public: - ~Manager() override; - static Manager *instance(); - - QString definitionIdByName(const QString &name) const; - QString definitionIdByMimeType(const Utils::MimeType &mimeType) const; - QString definitionIdByFile(const QString &filePath) const; - QString definitionIdByMimeTypeAndFile(const Utils::MimeType &mimeType, - const QString &filePath) const; - DefinitionMetaDataPtr availableDefinitionByName(const QString &name) const; - - bool isBuildingDefinition(const QString &id) const; - QSharedPointer<HighlightDefinition> definition(const QString &id); - DefinitionMetaDataPtr definitionMetaData(const QString &id) const; - - void downloadAvailableDefinitionsMetaData(); - void downloadDefinitions(const QList<QUrl> &urls, const QString &savePath); - bool isDownloadingDefinitions() const; - void registerHighlightingFiles(); - - static DefinitionMetaDataPtr parseMetadata(const QFileInfo &fileInfo); - - struct RegisterData - { - QHash<QString, QString> m_idByName; - QHash<QString, QString> m_idByMimeType; - QHash<QString, DefinitionMetaDataPtr> m_definitionsMetaData; - }; -private: - void registerHighlightingFilesFinished(); - void downloadAvailableDefinitionsListFinished(); - void downloadDefinitionsFinished(); - -signals: - void highlightingFilesRegistered(); - -private: - Manager(); - - void clear(); - - MultiDefinitionDownloader *m_multiDownloader = nullptr; - QList<DefinitionMetaDataPtr> parseAvailableDefinitionsList(QIODevice *device); - - QSet<QString> m_isBuildingDefinition; - QHash<QString, QSharedPointer<HighlightDefinition> > m_definitions; - QHash<QString, DefinitionMetaDataPtr> m_availableDefinitions; - - RegisterData m_register; - bool m_hasQueuedRegistration = false; - QFutureWatcher<RegisterData> m_registeringWatcher; - friend class ManagerProcessor; - -signals: - void definitionsMetaDataReady(const QList<Internal::DefinitionMetaDataPtr>&); - void errorDownloadingDefinitionsMetaData(); -}; - -} // namespace Internal -} // namespace TextEditor diff --git a/src/plugins/texteditor/generichighlighter/progressdata.cpp b/src/plugins/texteditor/generichighlighter/progressdata.cpp deleted file mode 100644 index a6453c8399..0000000000 --- a/src/plugins/texteditor/generichighlighter/progressdata.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "progressdata.h" -#include "rule.h" - -using namespace TextEditor; -using namespace Internal; - -ProgressData::ProgressData() : - m_offset(0), - m_savedOffset(-1), - m_onlySpacesSoFar(true), - m_openingBraceMatchAtFirstNonSpace(false), - m_closingBraceMatchAtNonEnd(false), - m_willContinueLine(false) -{} - -ProgressData::~ProgressData() -{ - foreach (Rule *rule, m_trackedRules) - rule->progressFinished(); -} - -void ProgressData::setOffset(const int offset) -{ m_offset = offset; } - -int ProgressData::offset() const -{ return m_offset; } - -void ProgressData::incrementOffset() -{ ++m_offset; } - -void ProgressData::incrementOffset(const int increment) -{ m_offset += increment; } - -void ProgressData::saveOffset() -{ m_savedOffset = m_offset; } - -void ProgressData::restoreOffset() -{ - Q_ASSERT(m_savedOffset != -1); - m_offset = m_savedOffset; - m_savedOffset = -1; -} - -void ProgressData::setOnlySpacesSoFar(const bool onlySpaces) -{ m_onlySpacesSoFar = onlySpaces; } - -bool ProgressData::isOnlySpacesSoFar() const -{ return m_onlySpacesSoFar; } - -void ProgressData::setOpeningBraceMatchAtFirstNonSpace(const bool match) -{ m_openingBraceMatchAtFirstNonSpace = match; } - -bool ProgressData::isOpeningBraceMatchAtFirstNonSpace() const -{ return m_openingBraceMatchAtFirstNonSpace; } - -void ProgressData::setClosingBraceMatchAtNonEnd(const bool match) -{ m_closingBraceMatchAtNonEnd = match; } - -bool ProgressData::isClosingBraceMatchAtNonEnd() const -{ return m_closingBraceMatchAtNonEnd; } - -void ProgressData::clearBracesMatches() -{ - if (m_openingBraceMatchAtFirstNonSpace) - m_openingBraceMatchAtFirstNonSpace = false; - if (m_closingBraceMatchAtNonEnd) - m_closingBraceMatchAtNonEnd = false; -} - -void ProgressData::setWillContinueLine(const bool willContinue) -{ m_willContinueLine = willContinue; } - -bool ProgressData::isWillContinueLine() const -{ return m_willContinueLine; } - -void ProgressData::setCaptures(const QStringList &captures) -{ m_captures = captures; } - -const QStringList &ProgressData::captures() const -{ return m_captures; } - -void ProgressData::trackRule(Rule *rule) -{ - m_trackedRules.append(rule); -} - -void ProgressData::unTrackRule(Rule *rule) -{ - m_trackedRules.removeAll(rule); -} - -bool ProgressData::detectRecursion(const QString &contextId) -{ - if (m_offset != m_iterationOffset) { - m_iterationOffset = m_offset; - m_iterationContextIds.clear(); - } - - if (m_iterationContextIds.contains(contextId)) - return true; - - m_iterationContextIds.append(contextId); - - return false; -} diff --git a/src/plugins/texteditor/generichighlighter/progressdata.h b/src/plugins/texteditor/generichighlighter/progressdata.h deleted file mode 100644 index 7350eb0d04..0000000000 --- a/src/plugins/texteditor/generichighlighter/progressdata.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include <QStringList> - -namespace TextEditor { -namespace Internal { - -class Rule; - -class ProgressData -{ -public: - ProgressData(); - ~ProgressData(); - - void setOffset(const int offset); - int offset() const; - - void incrementOffset(); - void incrementOffset(const int increment); - - void saveOffset(); - void restoreOffset(); - - void setOnlySpacesSoFar(const bool onlySpaces); - bool isOnlySpacesSoFar() const; - - void setOpeningBraceMatchAtFirstNonSpace(const bool match); - bool isOpeningBraceMatchAtFirstNonSpace() const; - - void setClosingBraceMatchAtNonEnd(const bool match); - bool isClosingBraceMatchAtNonEnd() const; - - void clearBracesMatches(); - - void setWillContinueLine(const bool willContinue); - bool isWillContinueLine() const; - - void setCaptures(const QStringList &captures); - const QStringList &captures() const; - - void trackRule(Rule *rule); - void unTrackRule(Rule *rule); - - bool detectRecursion(const QString &contextId); - -private: - int m_offset; - int m_savedOffset; - bool m_onlySpacesSoFar; - bool m_openingBraceMatchAtFirstNonSpace; - bool m_closingBraceMatchAtNonEnd; - bool m_willContinueLine; - QStringList m_captures; - QList<Rule *> m_trackedRules; - int m_iterationOffset = -1; - QStringList m_iterationContextIds; -}; - -} // namespace Internal -} // namespace TextEditor diff --git a/src/plugins/texteditor/generichighlighter/reuse.h b/src/plugins/texteditor/generichighlighter/reuse.h deleted file mode 100644 index d8d21f35c6..0000000000 --- a/src/plugins/texteditor/generichighlighter/reuse.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include <Qt> -#include <QString> -#include <QLatin1String> -#include <QChar> -#include <QFont> - -namespace TextEditor { -namespace Internal { - -inline bool toBool(const QString &s) -{ - static const QLatin1String kTrue("true"); - static const QLatin1String k1("1"); - - if (s.toLower() == kTrue || s == k1) - return true; - return false; -} - - -inline Qt::CaseSensitivity toCaseSensitivity(const bool sensitive) -{ - if (sensitive) - return Qt::CaseSensitive; - return Qt::CaseInsensitive; -} - -inline QFont::Weight toFontWeight(const bool bold) -{ - if (bold) - return QFont::Bold; - else - return QFont::Normal; -} - -inline bool isOctalDigit(const QChar &c) -{ - static const QLatin1Char k0('0'); - static const QLatin1Char k7('7'); - - return c >= k0 && c <= k7; -} - -inline bool isHexDigit(const QChar &c) -{ - static const QLatin1Char k0('0'); - static const QLatin1Char k9('9'); - static const QLatin1Char kA('A'); - static const QLatin1Char kF('F'); - static const QLatin1Char ka('a'); - static const QLatin1Char kf('f'); - - if ((c >= k0 && c <= k9) || (c >= kA && c <= kF) || (c >= ka && c <= kf)) - return true; - - return false; -} - -inline void setStartCharacter(QChar *c, const QString &character) -{ - if (!character.isEmpty()) - *c = character.at(0); -} - -} // namespace Internal -} // namespace TextEditor diff --git a/src/plugins/texteditor/generichighlighter/rule.cpp b/src/plugins/texteditor/generichighlighter/rule.cpp deleted file mode 100644 index 24e16267a2..0000000000 --- a/src/plugins/texteditor/generichighlighter/rule.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "rule.h" -#include "progressdata.h" -#include "highlightdefinition.h" -#include "reuse.h" - -#include <functional> - -using namespace TextEditor; -using namespace Internal; - -const QLatin1Char Rule::kBackSlash('\\'); -const QLatin1Char Rule::kUnderscore('_'); -const QLatin1Char Rule::kDot('.'); -const QLatin1Char Rule::kPlus('+'); -const QLatin1Char Rule::kMinus('-'); -const QLatin1Char Rule::kZero('0'); -const QLatin1Char Rule::kQuote('\"'); -const QLatin1Char Rule::kSingleQuote('\''); -const QLatin1Char Rule::kQuestion('?'); -const QLatin1Char Rule::kX('x'); -const QLatin1Char Rule::kA('a'); -const QLatin1Char Rule::kB('b'); -const QLatin1Char Rule::kE('e'); -const QLatin1Char Rule::kF('f'); -const QLatin1Char Rule::kN('n'); -const QLatin1Char Rule::kR('r'); -const QLatin1Char Rule::kT('t'); -const QLatin1Char Rule::kV('v'); -const QLatin1Char Rule::kOpeningBrace('{'); -const QLatin1Char Rule::kClosingBrace('}'); - -Rule::Rule(bool consumesNonSpace) : - m_lookAhead(false), m_firstNonSpace(false), m_column(-1), m_consumesNonSpace(consumesNonSpace) -{} - -Rule::~Rule() = default; - -void Rule::setContext(const QString &context) -{ m_context = context; } - -const QString &Rule::context() const -{ return m_context; } - -void Rule::setItemData(const QString &itemData) -{ m_itemData = itemData; } - -const QString &Rule::itemData() const -{ return m_itemData; } - -void Rule::setBeginRegion(const QString &begin) -{ m_beginRegion = begin; } - -const QString &Rule::beginRegion() const -{ return m_beginRegion; } - -void Rule::setEndRegion(const QString &end) -{ m_endRegion = end; } - -const QString &Rule::endRegion() const -{ return m_endRegion; } - -void Rule::setLookAhead(const QString &lookAhead) -{ m_lookAhead = toBool(lookAhead); } - -bool Rule::isLookAhead() const -{ return m_lookAhead; } - -void Rule::setFirstNonSpace(const QString &firstNonSpace) -{ m_firstNonSpace = toBool(firstNonSpace); } - -bool Rule::isFirstNonSpace() const -{ return m_firstNonSpace; } - -void Rule::setColumn(const QString &column) -{ - bool ok; - m_column = column.toInt(&ok); - if (!ok) - m_column = -1; -} - -int Rule::column() const -{ return m_column; } - -void Rule::addChild(const QSharedPointer<Rule> &rule) -{ m_children.append(rule); } - -bool Rule::hasChildren() const -{ return !m_children.isEmpty(); } - -const QList<QSharedPointer<Rule> > &Rule::children() const -{ return m_children; } - -void Rule::setDefinition(const QSharedPointer<HighlightDefinition> &definition) -{ m_definition = definition; } - -const QSharedPointer<HighlightDefinition> &Rule::definition() const -{ return m_definition; } - -template <class predicate_t> -bool Rule::predicateMatchSucceed(const QString &text, - const int length, - ProgressData *progress, - const predicate_t &p) const -{ - int original = progress->offset(); - while (progress->offset() < length && p(text.at(progress->offset()))) - progress->incrementOffset(); - - if (original != progress->offset()) - return true; - - return false; -} - -bool Rule::charPredicateMatchSucceed(const QString &text, - const int length, - ProgressData *progress, - bool (QChar::* predicate)() const) const -{ - return predicateMatchSucceed(text, length, progress, [predicate](const QChar &c) { - return (c.*predicate)(); - }); -} - -bool Rule::charPredicateMatchSucceed(const QString &text, - const int length, - ProgressData *progress, - bool (*predicate)(const QChar &)) const -{ - return predicateMatchSucceed(text, length, progress, [predicate](const QChar &c) { - return predicate(c); - }); -} - -bool Rule::matchSucceed(const QString &text, const int length, ProgressData *progress) -{ - if (m_firstNonSpace && !progress->isOnlySpacesSoFar()) - return false; - - if (m_column != -1 && m_column != progress->offset()) - return false; - - int original = progress->offset(); - if (doMatchSucceed(text, length, progress)) { - if (progress->isOnlySpacesSoFar() && !m_lookAhead && m_consumesNonSpace) - progress->setOnlySpacesSoFar(false); - - if (m_lookAhead) - progress->setOffset(original); - - return true; - } - - return false; -} - -Rule *Rule::clone() const -{ return doClone(); } - -void Rule::progressFinished() -{ doProgressFinished(); } - -bool Rule::matchCharacter(const QString &text, - const int length, - ProgressData *progress, - const QChar &c, - bool saveRestoreOffset) const -{ - Q_UNUSED(length) - Q_ASSERT(progress->offset() < length); - - if (text.at(progress->offset()) == c) { - if (saveRestoreOffset) - progress->saveOffset(); - progress->incrementOffset(); - return true; - } - - return false; -} - -bool Rule::matchEscapeSequence(const QString &text, - const int length, - ProgressData *progress, - bool saveRestoreOffset) const -{ - if (matchCharacter(text, length, progress, kBackSlash, saveRestoreOffset)) { - - if (progress->offset() < length) { - const QChar &c = text.at(progress->offset()); - if (c == kA || c == kB || c == kE || c == kF || c == kN || c == kR || c == kT || - c == kV || c == kQuestion || c == kSingleQuote || c == kQuote || c == kBackSlash) { - progress->incrementOffset(); - return true; - } else if (saveRestoreOffset) { - progress->restoreOffset(); - } - } else if (saveRestoreOffset) { - progress->restoreOffset(); - } - } - - return false; -} - -bool Rule::matchOctalSequence(const QString &text, - const int length, - ProgressData *progress, - bool saveRestoreOffset) const -{ - // An octal sequence is identified as in the C++ Standard. - // octal-escape-sequence: - // \ octal-digit - // \ octal-digit octal-digit - // \ octal-digit octal-digit octal-digit - - if (matchCharacter(text, length, progress, kBackSlash, saveRestoreOffset)) { - - int count = 0; - while (progress->offset() < length && - count < 3 && - isOctalDigit(text.at(progress->offset()))) { - ++count; - progress->incrementOffset(); - } - - if (count > 0) - return true; - else if (saveRestoreOffset) - progress->restoreOffset(); - } - - return false; -} - -bool Rule::matchHexSequence(const QString &text, - const int length, - ProgressData *progress, - bool saveRestoreOffset) const -{ - // An hex sequence is identified as in the C++ Standard. - // hexadecimal-escape-sequence: - // \x hexadecimal-digit - // hexadecimal-escape-sequence hexadecimal-digit - - if (matchCharacter(text, length, progress, kBackSlash, saveRestoreOffset)) { - - if (progress->offset() < length && matchCharacter(text, length, progress, kX, false)) { - bool found = false; - while (progress->offset() < length && isHexDigit(text.at(progress->offset()))) { - if (!found) - found = true; - progress->incrementOffset(); - } - - if (found) - return true; - else if (saveRestoreOffset) - progress->restoreOffset(); - } else if (saveRestoreOffset) { - progress->restoreOffset(); - } - } - - return false; -} diff --git a/src/plugins/texteditor/generichighlighter/rule.h b/src/plugins/texteditor/generichighlighter/rule.h deleted file mode 100644 index 4e25bef11a..0000000000 --- a/src/plugins/texteditor/generichighlighter/rule.h +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include <QString> -#include <QList> -#include <QSharedPointer> - -namespace TextEditor { -namespace Internal { - -class ProgressData; -class HighlightDefinition; - -class Rule -{ -public: - Rule(bool consumesNonSpace = true); - virtual ~Rule(); - - void setContext(const QString &context); - const QString &context() const; - - void setItemData(const QString &itemData); - const QString &itemData() const; - - void setBeginRegion(const QString &begin); - const QString &beginRegion() const; - - void setEndRegion(const QString &end); - const QString &endRegion() const; - - void setLookAhead(const QString &lookAhead); - bool isLookAhead() const; - - void setFirstNonSpace(const QString &firstNonSpace); - bool isFirstNonSpace() const; - - void setColumn(const QString &column); - int column() const; - - void addChild(const QSharedPointer<Rule> &rule); - const QList<QSharedPointer<Rule> > &children() const; - bool hasChildren() const; - - void setDefinition(const QSharedPointer<HighlightDefinition> &definition); - const QSharedPointer<HighlightDefinition> &definition() const; - - bool matchSucceed(const QString &text, const int length, ProgressData *progress); - - Rule *clone() const; - - void progressFinished(); - -protected: - bool charPredicateMatchSucceed(const QString &text, - const int length, - ProgressData *progress, - bool (QChar::* predicate)() const) const; - bool charPredicateMatchSucceed(const QString &text, - const int length, - ProgressData *progress, - bool (*predicate)(const QChar &)) const; - - bool matchCharacter(const QString &text, - const int length, - ProgressData *progress, - const QChar &c, - bool saveRestoreOffset = true) const; - bool matchEscapeSequence(const QString &text, - const int length, - ProgressData *progress, - bool saveRestoreOffset = true) const; - bool matchOctalSequence(const QString &text, - const int length, - ProgressData *progress, - bool saveRestoreOffset = true) const; - bool matchHexSequence(const QString &text, - const int length, - ProgressData *progress, - bool saveRestoreOffset = true) const; - - static const QLatin1Char kBackSlash; - static const QLatin1Char kUnderscore; - static const QLatin1Char kDot; - static const QLatin1Char kPlus; - static const QLatin1Char kMinus; - static const QLatin1Char kZero; - static const QLatin1Char kQuote; - static const QLatin1Char kSingleQuote; - static const QLatin1Char kQuestion; - static const QLatin1Char kX; - static const QLatin1Char kA; - static const QLatin1Char kB; - static const QLatin1Char kE; - static const QLatin1Char kF; - static const QLatin1Char kN; - static const QLatin1Char kR; - static const QLatin1Char kT; - static const QLatin1Char kV; - static const QLatin1Char kOpeningBrace; - static const QLatin1Char kClosingBrace; - -private: - virtual bool doMatchSucceed(const QString &text, const int length, ProgressData *progress) = 0; - - virtual Rule *doClone() const = 0; - - virtual void doProgressFinished() {} - - template <class predicate_t> - bool predicateMatchSucceed(const QString &text, - const int length, - ProgressData *progress, - const predicate_t &p) const; - - QString m_context; - QString m_itemData; - QString m_beginRegion; - QString m_endRegion; - bool m_lookAhead; - bool m_firstNonSpace; - int m_column; - bool m_consumesNonSpace; - - QList<QSharedPointer<Rule> > m_children; - - // Rules are represented within contexts. However, they have their own definition because - // of externally included rules. - QSharedPointer<HighlightDefinition> m_definition; -}; - -} // namespace Internal -} // namespace TextEditor diff --git a/src/plugins/texteditor/generichighlighter/specificrules.cpp b/src/plugins/texteditor/generichighlighter/specificrules.cpp deleted file mode 100644 index 1c52986b0c..0000000000 --- a/src/plugins/texteditor/generichighlighter/specificrules.cpp +++ /dev/null @@ -1,542 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "specificrules.h" -#include "highlightdefinition.h" -#include "keywordlist.h" -#include "progressdata.h" -#include "reuse.h" - -#include <QLatin1Char> - -using namespace TextEditor; -using namespace Internal; - -namespace { - -void replaceByCaptures(QChar *c, const QStringList &captures) -{ - int index = c->digitValue(); - if (index > 0) { - const QString &capture = captures.at(index); - if (!capture.isEmpty()) - *c = capture.at(0); - } -} - -void replaceByCaptures(QString *s, const QStringList &captures) -{ - static const QLatin1Char kPercent('%'); - - int index; - int from = 0; - while ((index = s->indexOf(kPercent, from)) != -1) { - from = index + 1; - - QString accumulator; - while (from < s->length() && s->at(from).isDigit()) { - accumulator.append(s->at(from)); - ++from; - } - - bool ok; - int number = accumulator.toInt(&ok); - Q_ASSERT(ok); - - s->replace(index, accumulator.length() + 1, captures.at(number)); - } -} -} - -// DetectChar -void DetectCharRule::setChar(const QString &character) -{ setStartCharacter(&m_char, character); } - -void DetectCharRule::doReplaceExpressions(const QStringList &captures) -{ replaceByCaptures(&m_char, captures); } - -bool DetectCharRule::doMatchSucceed(const QString &text, - const int length, - ProgressData *progress) -{ - if (matchCharacter(text, length, progress, m_char)) { - // This is to make code folding have a control flow style look in the case of braces. - // Naturally, this assumes that language definitions use braces with this meaning. - if (m_char == kOpeningBrace && progress->isOnlySpacesSoFar() && !isLookAhead()) { - progress->setOpeningBraceMatchAtFirstNonSpace(true); - } else if (m_char == kClosingBrace && - !text.right(length - progress->offset()).trimmed().isEmpty()) { - progress->setClosingBraceMatchAtNonEnd(true); - } - return true; - } - return false; -} - -// Detect2Chars -void Detect2CharsRule::setChar(const QString &character) -{ setStartCharacter(&m_char, character); } - -void Detect2CharsRule::setChar1(const QString &character) -{ setStartCharacter(&m_char1, character); } - -void Detect2CharsRule::doReplaceExpressions(const QStringList &captures) -{ - replaceByCaptures(&m_char, captures); - replaceByCaptures(&m_char1, captures); -} - -bool Detect2CharsRule::doMatchSucceed(const QString &text, - const int length, - ProgressData *progress) -{ - if (matchCharacter(text, length, progress, m_char)) { - if (progress->offset() < length && matchCharacter(text, length, progress, m_char1, false)) - return true; - else - progress->restoreOffset(); - } - - return false; -} - -// AnyChar -void AnyCharRule::setCharacterSet(const QString &s) -{ m_characterSet = s; } - -bool AnyCharRule::doMatchSucceed(const QString &text, - const int length, - ProgressData *progress) -{ - Q_UNUSED(length) - - if (m_characterSet.contains(text.at(progress->offset()))) { - progress->incrementOffset(); - return true; - } - - return false; -} - -// StringDetect -void StringDetectRule::setString(const QString &s) -{ - m_string = s; - m_length = m_string.length(); -} - -void StringDetectRule::setInsensitive(const QString &insensitive) -{ m_caseSensitivity = toCaseSensitivity(!toBool(insensitive)); } - -void StringDetectRule::doReplaceExpressions(const QStringList &captures) -{ - replaceByCaptures(&m_string, captures); - m_length = m_string.length(); -} - -bool StringDetectRule::doMatchSucceed(const QString &text, - const int length, - ProgressData *progress) -{ - if (length - progress->offset() >= m_length) { - QString candidate = text.fromRawData(text.unicode() + progress->offset(), m_length); - if (candidate.compare(m_string, m_caseSensitivity) == 0) { - progress->incrementOffset(m_length); - return true; - } - } - - return false; -} - -bool WordDetectRule::doMatchSucceed(const QString &text, const int length, ProgressData *progress) -{ - const int offset = progress->offset(); - if (length - offset < m_length) - return false; - if (offset > 0 && !definition()->isDelimiter(text.at(offset - 1))) - return false; - if (text.midRef(offset, m_string.size()).compare(m_string, m_caseSensitivity) != 0) - return false; - if (length > offset + m_string.size() && !definition()->isDelimiter(text.at(offset + m_string.size()))) - return false; - progress->incrementOffset(m_length); - return true; -} - -// RegExpr -RegExprRule::~RegExprRule() -{ - if (m_progress) - m_progress->unTrackRule(this); -} - -void RegExprRule::setPattern(const QString &pattern) -{ - if (pattern.startsWith(QLatin1Char('^'))) - m_onlyBegin = true; - m_expression.setPattern(pattern); -} - -void RegExprRule::setInsensitive(const QString &insensitive) -{ m_expression.setCaseSensitivity(toCaseSensitivity(!toBool(insensitive))); } - -void RegExprRule::setMinimal(const QString &minimal) -{ m_expression.setMinimal(toBool(minimal)); } - -void RegExprRule::doReplaceExpressions(const QStringList &captures) -{ - QString s = m_expression.pattern(); - replaceByCaptures(&s, captures); - m_expression.setPattern(s); -} - -void RegExprRule::doProgressFinished() -{ - m_progress = nullptr; - m_isCached = false; -} - -bool RegExprRule::isExactMatch(ProgressData *progress) -{ - if (progress->offset() == m_offset && m_length > 0) { - progress->incrementOffset(m_length); - progress->setCaptures(m_captures); - return true; - } - return false; -} - -bool RegExprRule::doMatchSucceed(const QString &text, - const int length, - ProgressData *progress) -{ - Q_UNUSED(length) - - // A regular expression match is considered valid if it happens at the current position - // and if the match length is not zero. - const int offset = progress->offset(); - if (offset > 0 && m_onlyBegin) - return false; - - if (m_isCached) { - if (offset < m_offset || m_offset == -1 || m_length == 0) - return false; - if (isExactMatch(progress)) - return true; - } - - m_offset = m_expression.indexIn(text, offset, QRegExp::CaretAtOffset); - m_length = m_expression.matchedLength(); - m_captures = m_expression.capturedTexts(); - - if (isExactMatch(progress)) - return true; - - m_isCached = true; - m_progress = progress; - progress->trackRule(this); - - return false; -} - -RegExprRule *RegExprRule::doClone() const -{ - auto clone = new RegExprRule(*this); - if (m_progress) - m_progress->trackRule(clone); - return clone; -} - -// Keyword -KeywordRule::KeywordRule(const QSharedPointer<HighlightDefinition> &definition) : - m_overrideGlobal(false), - m_localCaseSensitivity(Qt::CaseSensitive) -{ - setDefinition(definition); -} - -KeywordRule::~KeywordRule() = default; - -void KeywordRule::setInsensitive(const QString &insensitive) -{ - if (!insensitive.isEmpty()) { - m_overrideGlobal = true; - m_localCaseSensitivity = toCaseSensitivity(!toBool(insensitive)); - } -} - -void KeywordRule::setList(const QString &listName) -{ m_list = definition()->keywordList(listName); } - -bool KeywordRule::doMatchSucceed(const QString &text, - const int length, - ProgressData *progress) -{ - if (m_list.isNull()) // Happens if a keyword rule points to a none existing keyword list - return false; - - int current = progress->offset(); - - if (current > 0 && !definition()->isDelimiter(text.at(current - 1))) - return false; - if (definition()->isDelimiter(text.at(current))) - return false; - - while (current < length && !definition()->isDelimiter(text.at(current))) - ++current; - - QString candidate = - QString::fromRawData(text.unicode() + progress->offset(), current - progress->offset()); - if ((m_overrideGlobal && m_list->isKeyword(candidate, m_localCaseSensitivity)) || - (!m_overrideGlobal && m_list->isKeyword(candidate, definition()->keywordsSensitive()))) { - progress->setOffset(current); - return true; - } - - return false; -} - -// Int -bool IntRule::doMatchSucceed(const QString &text, - const int length, - ProgressData *progress) -{ - const int offset = progress->offset(); - - // This is necessary to correctly highlight an invalid octal like 09, for example. - if (offset > 0 && text.at(offset - 1).isDigit()) - return false; - - if (text.at(offset).isDigit() && text.at(offset) != kZero) { - progress->incrementOffset(); - charPredicateMatchSucceed(text, length, progress, &QChar::isDigit); - return true; - } - - return false; -} - -// Float -bool FloatRule::doMatchSucceed(const QString &text, const int length, ProgressData *progress) -{ - progress->saveOffset(); - - bool integralPart = charPredicateMatchSucceed(text, length, progress, &QChar::isDigit); - - bool decimalPoint = false; - if (progress->offset() < length && text.at(progress->offset()) == kDot) { - progress->incrementOffset(); - decimalPoint = true; - } - - bool fractionalPart = charPredicateMatchSucceed(text, length, progress, &QChar::isDigit); - - bool exponentialPart = false; - int offset = progress->offset(); - if (offset < length && (text.at(offset) == kE || text.at(offset).toLower() == kE)) { - progress->incrementOffset(); - - offset = progress->offset(); - if (offset < length && (text.at(offset) == kPlus || text.at(offset) == kMinus)) - progress->incrementOffset(); - - if (charPredicateMatchSucceed(text, length, progress, &QChar::isDigit)) { - exponentialPart = true; - } else { - progress->restoreOffset(); - return false; - } - } - - if ((integralPart || fractionalPart) && (decimalPoint || exponentialPart)) - return true; - - progress->restoreOffset(); - return false; -} - -// COctal -bool HlCOctRule::doMatchSucceed(const QString &text, - const int length, - ProgressData *progress) -{ - if (matchCharacter(text, length, progress, kZero)) { - // In the definition files the number matching rules which are more restrictive should - // appear before the rules which are least resctritive. Although this happens in general - // there is at least one case where this is not strictly followed for existent definition - // files (specifically, HlCHex comes before HlCOct). So the condition below. - const int offset = progress->offset(); - if (offset < length && (text.at(offset) == kX || text.at(offset).toLower() == kX)) { - progress->restoreOffset(); - return false; - } - - charPredicateMatchSucceed(text, length, progress, &isOctalDigit); - return true; - } - - return false; -} - -// CHex -bool HlCHexRule::doMatchSucceed(const QString &text, - const int length, - ProgressData *progress) -{ - if (matchCharacter(text, length, progress, kZero)) { - const int offset = progress->offset(); - if (offset < length && text.at(offset) != kX && text.at(offset).toLower() != kX) { - progress->restoreOffset(); - return false; - } - - progress->incrementOffset(); - if (charPredicateMatchSucceed(text, length, progress, &isHexDigit)) - return true; - else - progress->restoreOffset(); - } - - return false; -} - -// CString -bool HlCStringCharRule::doMatchSucceed(const QString &text, - const int length, - ProgressData *progress) -{ - if (matchEscapeSequence(text, length, progress)) - return true; - - if (matchOctalSequence(text, length, progress)) - return true; - - if (matchHexSequence(text, length, progress)) - return true; - - return false; -} - -// CChar -bool HlCCharRule::doMatchSucceed(const QString &text, - const int length, - ProgressData *progress) -{ - if (matchCharacter(text, length, progress, kSingleQuote)) { - if (progress->offset() < length) { - if (text.at(progress->offset()) != kBackSlash && - text.at(progress->offset()) != kSingleQuote) { - progress->incrementOffset(); - } else if (!matchEscapeSequence(text, length, progress, false)) { - progress->restoreOffset(); - return false; - } - - if (progress->offset() < length && - matchCharacter(text, length, progress, kSingleQuote, false)) { - return true; - } else { - progress->restoreOffset(); - } - } else { - progress->restoreOffset(); - } - } - - return false; -} - -// RangeDetect -void RangeDetectRule::setChar(const QString &character) -{ setStartCharacter(&m_char, character); } - -void RangeDetectRule::setChar1(const QString &character) -{ setStartCharacter(&m_char1, character); } - -bool RangeDetectRule::doMatchSucceed(const QString &text, - const int length, - ProgressData *progress) -{ - if (matchCharacter(text, length, progress, m_char)) { - while (progress->offset() < length) { - if (matchCharacter(text, length, progress, m_char1, false)) - return true; - progress->incrementOffset(); - } - progress->restoreOffset(); - } - - return false; -} - -// LineContinue -bool LineContinueRule::doMatchSucceed(const QString &text, - const int length, - ProgressData *progress) -{ - if (progress->offset() != length - 1) - return false; - - if (text.at(progress->offset()) == kBackSlash) { - progress->incrementOffset(); - progress->setWillContinueLine(true); - return true; - } - - return false; -} - -// DetectSpaces -DetectSpacesRule::DetectSpacesRule() : Rule(false) -{} - -bool DetectSpacesRule::doMatchSucceed(const QString &text, - const int length, - ProgressData *progress) -{ - return charPredicateMatchSucceed(text, length, progress, &QChar::isSpace); -} - -// DetectIdentifier -bool DetectIdentifierRule::doMatchSucceed(const QString &text, - const int length, - ProgressData *progress) -{ - // Identifiers are characterized by a letter or underscore as the first character and then - // zero or more word characters (\w*). - if (text.at(progress->offset()).isLetter() || text.at(progress->offset()) == kUnderscore) { - progress->incrementOffset(); - while (progress->offset() < length) { - const QChar ¤t = text.at(progress->offset()); - if (current.isLetterOrNumber() || current.isMark() || current == kUnderscore) - progress->incrementOffset(); - else - break; - } - return true; - } - return false; -} diff --git a/src/plugins/texteditor/generichighlighter/specificrules.h b/src/plugins/texteditor/generichighlighter/specificrules.h deleted file mode 100644 index 00c9cea816..0000000000 --- a/src/plugins/texteditor/generichighlighter/specificrules.h +++ /dev/null @@ -1,265 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include "rule.h" -#include "dynamicrule.h" - -#include <QChar> -#include <QStringList> -#include <QRegExp> -#include <QSharedPointer> - -namespace TextEditor { -namespace Internal { - -class KeywordList; -class HighlightDefinition; - -class DetectCharRule : public DynamicRule -{ -public: - ~DetectCharRule() override = default; - - void setChar(const QString &character); - -private: - bool doMatchSucceed(const QString &text, const int length, ProgressData *progress) override; - DetectCharRule *doClone() const override { return new DetectCharRule(*this); } - void doReplaceExpressions(const QStringList &captures) override; - - QChar m_char; -}; - -class Detect2CharsRule : public DynamicRule -{ -public: - ~Detect2CharsRule() override = default; - - void setChar(const QString &character); - void setChar1(const QString &character); - -private: - bool doMatchSucceed(const QString &text, const int length, ProgressData *progress) override; - Detect2CharsRule *doClone() const override { return new Detect2CharsRule(*this); } - void doReplaceExpressions(const QStringList &captures) override; - - QChar m_char; - QChar m_char1; -}; - -class AnyCharRule : public Rule -{ -public: - ~AnyCharRule() override = default; - - void setCharacterSet(const QString &s); - -private: - bool doMatchSucceed(const QString &text, const int length, ProgressData *progress) override; - AnyCharRule *doClone() const override { return new AnyCharRule(*this); } - - QString m_characterSet; -}; - -class StringDetectRule : public DynamicRule -{ -public: - ~StringDetectRule() override = default; - - void setString(const QString &s); - void setInsensitive(const QString &insensitive); - -protected: - bool doMatchSucceed(const QString &text, const int length, ProgressData *progress) override; - StringDetectRule *doClone() const override { return new StringDetectRule(*this); } - void doReplaceExpressions(const QStringList &captures) override; - - QString m_string; - int m_length = 0; - Qt::CaseSensitivity m_caseSensitivity = Qt::CaseSensitive; -}; - -class WordDetectRule : public StringDetectRule -{ -private: - bool doMatchSucceed(const QString &text, const int length, ProgressData *progress) override; - WordDetectRule *doClone() const override { return new WordDetectRule(*this); } -}; - -class RegExprRule : public DynamicRule -{ -public: - ~RegExprRule() override; - - void setPattern(const QString &pattern); - void setInsensitive(const QString &insensitive); - void setMinimal(const QString &minimal); - -private: - bool doMatchSucceed(const QString &text, const int length, ProgressData *progress) override; - RegExprRule *doClone() const override; - void doReplaceExpressions(const QStringList &captures) override; - void doProgressFinished() override; - - bool isExactMatch(ProgressData *progress); - - bool m_onlyBegin = false; - bool m_isCached = false; - int m_offset = 0; - int m_length = 0; - QStringList m_captures; - QRegExp m_expression; - ProgressData *m_progress = nullptr; -}; - -class KeywordRule : public Rule -{ -public: - KeywordRule(const QSharedPointer<HighlightDefinition> &definition); - ~KeywordRule() override; - - void setInsensitive(const QString &insensitive); - void setList(const QString &listName); - -private: - bool doMatchSucceed(const QString &text, const int length, ProgressData *progress) override; - KeywordRule *doClone() const override { return new KeywordRule(*this); } - - bool m_overrideGlobal; - Qt::CaseSensitivity m_localCaseSensitivity; - QSharedPointer<KeywordList> m_list; -}; - -class IntRule : public Rule -{ -public: - ~IntRule() override = default; - -private: - bool doMatchSucceed(const QString &text, const int length, ProgressData *progress) override; - IntRule *doClone() const override { return new IntRule(*this); } -}; - -class FloatRule : public Rule -{ -public: - ~FloatRule() override = default; - -private: - bool doMatchSucceed(const QString &text, const int length, ProgressData *progress) override; - FloatRule *doClone() const override { return new FloatRule(*this); } -}; - -class HlCOctRule : public Rule -{ -public: - ~HlCOctRule() override = default; - -private: - bool doMatchSucceed(const QString &text, const int length, ProgressData *progress) override; - HlCOctRule *doClone() const override { return new HlCOctRule(*this); } -}; - -class HlCHexRule : public Rule -{ -public: - ~HlCHexRule() override = default; - -private: - bool doMatchSucceed(const QString &text, const int length, ProgressData *progress) override; - HlCHexRule *doClone() const override { return new HlCHexRule(*this); } -}; - -class HlCStringCharRule : public Rule -{ -public: - ~HlCStringCharRule() override = default; - -private: - bool doMatchSucceed(const QString &text, const int length, ProgressData *progress) override; - HlCStringCharRule *doClone() const override { return new HlCStringCharRule(*this); } -}; - -class HlCCharRule : public Rule -{ -public: - ~HlCCharRule() override = default; - -private: - bool doMatchSucceed(const QString &text, const int length, ProgressData *progress) override; - HlCCharRule *doClone() const override { return new HlCCharRule(*this); } -}; - -class RangeDetectRule : public Rule -{ -public: - ~RangeDetectRule() override = default; - - void setChar(const QString &character); - void setChar1(const QString &character); - -private: - bool doMatchSucceed(const QString &text, const int length, ProgressData *progress) override; - RangeDetectRule *doClone() const override { return new RangeDetectRule(*this); } - - QChar m_char; - QChar m_char1; -}; - -class LineContinueRule : public Rule -{ -public: - ~LineContinueRule() override = default; - -private: - bool doMatchSucceed(const QString &text, const int length, ProgressData *progress) override; - LineContinueRule *doClone() const override { return new LineContinueRule(*this); } -}; - -class DetectSpacesRule : public Rule -{ -public: - DetectSpacesRule(); - ~DetectSpacesRule() override = default; - -private: - bool doMatchSucceed(const QString &text, const int length, ProgressData *progress) override; - DetectSpacesRule *doClone() const override { return new DetectSpacesRule(*this); } -}; - -class DetectIdentifierRule : public Rule -{ -public: - ~DetectIdentifierRule() override = default; - -private: - bool doMatchSucceed(const QString &text, const int length, ProgressData *progress) override; - DetectIdentifierRule *doClone() const override { return new DetectIdentifierRule(*this); } -}; - -} // namespace Internal -} // namespace TextEditor diff --git a/src/plugins/texteditor/highlighter.cpp b/src/plugins/texteditor/highlighter.cpp new file mode 100644 index 0000000000..170ec12bc8 --- /dev/null +++ b/src/plugins/texteditor/highlighter.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2019 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 "highlighter.h" + +#include "definitiondownloader.h" +#include "highlightersettings.h" +#include "textdocumentlayout.h" +#include "texteditorsettings.h" + +#include <coreplugin/icore.h> +#include <coreplugin/messagemanager.h> + +#include <Format> +#include <Repository> +#include <SyntaxHighlighter> + +#include <QDir> +#include <QMetaEnum> + +using namespace TextEditor; + +KSyntaxHighlighting::Repository *highlightRepository() +{ + static KSyntaxHighlighting::Repository *repository = nullptr; + if (!repository) { + repository = new KSyntaxHighlighting::Repository(); + repository->addCustomSearchPath(TextEditorSettings::highlighterSettings().definitionFilesPath()); + QDir dir(Core::ICore::resourcePath() + QLatin1String("/generic-highlighter/syntax")); + if (dir.exists() && dir.cdUp()) + repository->addCustomSearchPath(dir.path()); + } + return repository; +} + +TextStyle categoryForTextStyle(int style) +{ + switch (style) { + case KSyntaxHighlighting::Theme::Normal: return C_TEXT; + case KSyntaxHighlighting::Theme::Keyword: return C_KEYWORD; + case KSyntaxHighlighting::Theme::Function: return C_FUNCTION; + case KSyntaxHighlighting::Theme::Variable: return C_LOCAL; + case KSyntaxHighlighting::Theme::ControlFlow: return C_KEYWORD; + case KSyntaxHighlighting::Theme::Operator: return C_OPERATOR; + case KSyntaxHighlighting::Theme::BuiltIn: return C_PRIMITIVE_TYPE; + case KSyntaxHighlighting::Theme::Extension: return C_GLOBAL; + case KSyntaxHighlighting::Theme::Preprocessor: return C_PREPROCESSOR; + case KSyntaxHighlighting::Theme::Attribute: return C_LOCAL; + case KSyntaxHighlighting::Theme::Char: return C_STRING; + case KSyntaxHighlighting::Theme::SpecialChar: return C_STRING; + case KSyntaxHighlighting::Theme::String: return C_STRING; + case KSyntaxHighlighting::Theme::VerbatimString: return C_STRING; + case KSyntaxHighlighting::Theme::SpecialString: return C_STRING; + case KSyntaxHighlighting::Theme::Import: return C_PREPROCESSOR; + case KSyntaxHighlighting::Theme::DataType: return C_TYPE; + case KSyntaxHighlighting::Theme::DecVal: return C_NUMBER; + case KSyntaxHighlighting::Theme::BaseN: return C_NUMBER; + case KSyntaxHighlighting::Theme::Float: return C_NUMBER; + case KSyntaxHighlighting::Theme::Constant: return C_KEYWORD; + case KSyntaxHighlighting::Theme::Comment: return C_COMMENT; + case KSyntaxHighlighting::Theme::Documentation: return C_DOXYGEN_COMMENT; + case KSyntaxHighlighting::Theme::Annotation: return C_DOXYGEN_TAG; + case KSyntaxHighlighting::Theme::CommentVar: return C_DOXYGEN_TAG; + case KSyntaxHighlighting::Theme::RegionMarker: return C_PREPROCESSOR; + case KSyntaxHighlighting::Theme::Information: return C_WARNING; + case KSyntaxHighlighting::Theme::Warning: return C_WARNING; + case KSyntaxHighlighting::Theme::Alert: return C_ERROR; + case KSyntaxHighlighting::Theme::Error: return C_ERROR; + case KSyntaxHighlighting::Theme::Others: return C_TEXT; + } + return C_TEXT; +} + +Highlighter::Highlighter() +{ + setTextFormatCategories(QMetaEnum::fromType<KSyntaxHighlighting::Theme::TextStyle>().keyCount(), + &categoryForTextStyle); +} + +KSyntaxHighlighting::Definition Highlighter::definitionForMimeType(const QString &mimeType) +{ + return highlightRepository()->definitionForMimeType(mimeType); +} + +KSyntaxHighlighting::Definition Highlighter::definitionForFileName(const QString &fileName) +{ + return highlightRepository()->definitionForFileName(fileName); +} + +void Highlighter::addCustomHighlighterPath(const Utils::FileName &path) +{ + highlightRepository()->addCustomSearchPath(path.toString()); +} + +void Highlighter::updateDefinitions(std::function<void()> callback) { + auto downloader = + new KSyntaxHighlighting::DefinitionDownloader(highlightRepository()); + connect(downloader, &KSyntaxHighlighting::DefinitionDownloader::done, + [downloader, callback]() { + Core::MessageManager::write(tr("Highlighter updates: done"), + Core::MessageManager::ModeSwitch); + downloader->deleteLater(); + if (callback) + callback(); + }); + connect(downloader, + &KSyntaxHighlighting::DefinitionDownloader::informationMessage, + [](const QString &message) { + Core::MessageManager::write(tr("Highlighter updates:") + ' ' + + message, + Core::MessageManager::ModeSwitch); + }); + downloader->start(); +} + +void Highlighter::handleShutdown() +{ + delete highlightRepository(); +} + +void Highlighter::highlightBlock(const QString &text) +{ + if (!definition().isValid()) + return; + QTextBlock block = currentBlock(); + KSyntaxHighlighting::State state = TextDocumentLayout::userData(block)->syntaxState(); + state = highlightLine(text, state); + block = block.next(); + if (block.isValid()) + TextDocumentLayout::userData(block)->setSyntaxState(state); +} + +void Highlighter::applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format) +{ + setFormat(offset, length, formatForCategory(format.textStyle())); +} diff --git a/tests/auto/generichighlighter/highlighterengine/syntaxhighlighter.h b/src/plugins/texteditor/highlighter.h index f9111d68c0..90ab31332a 100644 --- a/tests/auto/generichighlighter/highlighterengine/syntaxhighlighter.h +++ b/src/plugins/texteditor/highlighter.h @@ -25,32 +25,32 @@ #pragma once -// Replaces the "real" syntaxhighlighter.h file. The scope of this test is restricted to the -// highlight definition's context engine. Using a mock derived from QSyntaxHighlighter as a -// base instead of the real TextEditor::SyntaxHighlighter should not affect it. +#include "syntaxhighlighter.h" -#include <QSyntaxHighlighter> -#include <texteditor/texteditorconstants.h> +#include <utils/fileutils.h> -#include <functional> +#include <AbstractHighlighter> +#include <Definition> namespace TextEditor { - class FontSettings; -class SyntaxHighlighter : public QSyntaxHighlighter +class Highlighter : public SyntaxHighlighter, public KSyntaxHighlighting::AbstractHighlighter { public: - SyntaxHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent) {} - virtual ~SyntaxHighlighter() {} + Highlighter(); + + static KSyntaxHighlighting::Definition definitionForMimeType(const QString &mimeType); + static KSyntaxHighlighting::Definition definitionForFileName(const QString &fileName); + + static void addCustomHighlighterPath(const Utils::FileName &path); + static void updateDefinitions(std::function<void()> callback = nullptr); + + static void handleShutdown(); protected: - void formatSpaces(const QString &) - {} - void setTextFormatCategories(int, std::function<TextStyle(int)>) - {} - QTextCharFormat formatForCategory(int categoryIndex) const; - FontSettings fontSettings() const; + void highlightBlock(const QString &text) override; + void applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format) override; }; -} +} // namespace TextEditor diff --git a/src/plugins/texteditor/generichighlighter/highlightersettings.cpp b/src/plugins/texteditor/highlightersettings.cpp index f0a00d3bc8..76b88b063a 100644 --- a/src/plugins/texteditor/generichighlighter/highlightersettings.cpp +++ b/src/plugins/texteditor/highlightersettings.cpp @@ -96,8 +96,6 @@ QString findFallbackDefinitionsLocation() namespace { static const QLatin1String kDefinitionFilesPath("UserDefinitionFilesPath"); -static const QLatin1String kFallbackDefinitionFilesPath("FallbackDefinitionFilesPath"); -static const QLatin1String kUseFallbackLocation("UseFallbackLocation"); static const QLatin1String kIgnoredFilesPatterns("IgnoredFilesPatterns"); static const QLatin1String kGroupPostfix("HighlighterSettings"); @@ -113,17 +111,11 @@ QString groupSpecifier(const QString &postFix, const QString &category) using namespace TextEditor; using namespace Internal; -HighlighterSettings::HighlighterSettings() : - m_useFallbackLocation(true) -{} - void HighlighterSettings::toSettings(const QString &category, QSettings *s) const { const QString &group = groupSpecifier(kGroupPostfix, category); s->beginGroup(group); s->setValue(kDefinitionFilesPath, m_definitionFilesPath); - s->setValue(kFallbackDefinitionFilesPath, m_fallbackDefinitionFilesPath); - s->setValue(kUseFallbackLocation, m_useFallbackLocation); s->setValue(kIgnoredFilesPatterns, ignoredFilesPatterns()); s->endGroup(); } @@ -137,16 +129,6 @@ void HighlighterSettings::fromSettings(const QString &category, QSettings *s) assignDefaultDefinitionsPath(); else m_definitionFilesPath = s->value(kDefinitionFilesPath).toString(); - if (!s->contains(kFallbackDefinitionFilesPath)) { - m_fallbackDefinitionFilesPath = findFallbackDefinitionsLocation(); - if (m_fallbackDefinitionFilesPath.isEmpty()) - m_useFallbackLocation = false; - else - m_useFallbackLocation = true; - } else { - m_fallbackDefinitionFilesPath = s->value(kFallbackDefinitionFilesPath).toString(); - m_useFallbackLocation = s->value(kUseFallbackLocation, true).toBool(); - } if (!s->contains(kIgnoredFilesPatterns)) assignDefaultIgnoredPatterns(); else @@ -187,7 +169,7 @@ void HighlighterSettings::assignDefaultDefinitionsPath() bool HighlighterSettings::isIgnoredFilePattern(const QString &fileName) const { - for (auto ®Exp : m_ignoredFiles) + for (const QRegExp ®Exp : m_ignoredFiles) if (regExp.indexIn(fileName) != -1) return true; @@ -197,8 +179,6 @@ bool HighlighterSettings::isIgnoredFilePattern(const QString &fileName) const bool HighlighterSettings::equals(const HighlighterSettings &highlighterSettings) const { return m_definitionFilesPath == highlighterSettings.m_definitionFilesPath && - m_fallbackDefinitionFilesPath == highlighterSettings.m_fallbackDefinitionFilesPath && - m_useFallbackLocation == highlighterSettings.m_useFallbackLocation && m_ignoredFiles == highlighterSettings.m_ignoredFiles; } @@ -208,7 +188,7 @@ void HighlighterSettings::setExpressionsFromList(const QStringList &patterns) QRegExp regExp; regExp.setCaseSensitivity(Qt::CaseInsensitive); regExp.setPatternSyntax(QRegExp::Wildcard); - for (auto &pattern : patterns) { + for (const QString &pattern : patterns) { regExp.setPattern(pattern); m_ignoredFiles.append(regExp); } @@ -217,7 +197,7 @@ void HighlighterSettings::setExpressionsFromList(const QStringList &patterns) QStringList HighlighterSettings::listFromExpressions() const { QStringList patterns; - foreach (const QRegExp ®Exp, m_ignoredFiles) + for (const QRegExp ®Exp : m_ignoredFiles) patterns.append(regExp.pattern()); return patterns; } diff --git a/src/plugins/texteditor/generichighlighter/highlightersettings.h b/src/plugins/texteditor/highlightersettings.h index 3323b5bd39..16d2eab318 100644 --- a/src/plugins/texteditor/generichighlighter/highlightersettings.h +++ b/src/plugins/texteditor/highlightersettings.h @@ -39,7 +39,7 @@ namespace TextEditor { class HighlighterSettings { public: - HighlighterSettings(); + HighlighterSettings() = default; void toSettings(const QString &category, QSettings *s) const; void fromSettings(const QString &category, QSettings *s); @@ -47,12 +47,6 @@ public: void setDefinitionFilesPath(const QString &path) { m_definitionFilesPath = path; } const QString &definitionFilesPath() const { return m_definitionFilesPath; } - void setFallbackDefinitionFilesPath(const QString &path){ m_fallbackDefinitionFilesPath = path;} - const QString &fallbackDefinitionFilesPath() const { return m_fallbackDefinitionFilesPath; } - - void setUseFallbackLocation(const bool use) { m_useFallbackLocation = use; } - bool useFallbackLocation() const { return m_useFallbackLocation; } - void setIgnoredFilesPatterns(const QString &patterns); QString ignoredFilesPatterns() const; bool isIgnoredFilePattern(const QString &fileName) const; @@ -66,9 +60,7 @@ private: void setExpressionsFromList(const QStringList &patterns); QStringList listFromExpressions() const; - bool m_useFallbackLocation; QString m_definitionFilesPath; - QString m_fallbackDefinitionFilesPath; QList<QRegExp> m_ignoredFiles; }; diff --git a/src/plugins/texteditor/highlightersettingspage.cpp b/src/plugins/texteditor/highlightersettingspage.cpp new file mode 100644 index 0000000000..ec9d34ee65 --- /dev/null +++ b/src/plugins/texteditor/highlightersettingspage.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2019 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 "highlightersettingspage.h" +#include "highlightersettings.h" +#include "highlighter.h" +#include "ui_highlightersettingspage.h" + +#include <coreplugin/icore.h> + +#include <QDir> +#include <QMessageBox> +#include <QPointer> + +using namespace TextEditor; +using namespace Internal; + +struct HighlighterSettingsPage::HighlighterSettingsPagePrivate +{ + explicit HighlighterSettingsPagePrivate(Core::Id id); + void ensureInitialized(); + void migrateGenericHighlighterFiles(); + + bool m_initialized = false; + const Core::Id m_id; + const QString m_displayName; + const QString m_settingsPrefix; + + HighlighterSettings m_settings; + + QPointer<QWidget> m_widget; + Ui::HighlighterSettingsPage *m_page = nullptr; +}; + +HighlighterSettingsPage::HighlighterSettingsPagePrivate:: +HighlighterSettingsPagePrivate(Core::Id id) + : m_id(id) + , m_displayName(tr("Generic Highlighter")) + , m_settingsPrefix("Text") +{} + +void HighlighterSettingsPage::HighlighterSettingsPagePrivate::migrateGenericHighlighterFiles() +{ + QDir userDefinitionPath(m_settings.definitionFilesPath()); + if (userDefinitionPath.mkdir("syntax")) { + const auto link = Utils::HostOsInfo::isAnyUnixHost() + ? QOverload<const QString &, const QString &>::of(&QFile::link) + : QOverload<const QString &, const QString &>::of(&QFile::copy); + + for (const QFileInfo &file : userDefinitionPath.entryInfoList({"*.xml"}, QDir::Files)) + link(file.filePath(), file.absolutePath() + "/syntax/" + file.fileName()); + } +} + +void HighlighterSettingsPage::HighlighterSettingsPagePrivate::ensureInitialized() +{ + if (m_initialized) + return; + m_initialized = true; + m_settings.fromSettings(m_settingsPrefix, Core::ICore::settings()); + migrateGenericHighlighterFiles(); +} + +HighlighterSettingsPage::HighlighterSettingsPage(Core::Id id, QObject *parent) : + TextEditorOptionsPage(parent), + m_d(new HighlighterSettingsPagePrivate(id)) +{ + setId(m_d->m_id); + setDisplayName(m_d->m_displayName); +} + +HighlighterSettingsPage::~HighlighterSettingsPage() +{ + delete m_d; +} + +QWidget *HighlighterSettingsPage::widget() +{ + if (!m_d->m_widget) { + m_d->m_widget = new QWidget; + m_d->m_page = new Ui::HighlighterSettingsPage; + m_d->m_page->setupUi(m_d->m_widget); + m_d->m_page->definitionFilesPath->setExpectedKind(Utils::PathChooser::ExistingDirectory); + m_d->m_page->definitionFilesPath->setHistoryCompleter(QLatin1String("TextEditor.Highlighter.History")); + connect(m_d->m_page->updateDefinitions, + &QPushButton::pressed, + [label = QPointer<QLabel>(m_d->m_page->updateStatus)]() { + Highlighter::updateDefinitions([label](){ + if (label) + label->setText(tr("Update finished")); + }); + }); + + settingsToUI(); + } + return m_d->m_widget; +} + +void HighlighterSettingsPage::apply() +{ + if (!m_d->m_page) // page was not shown + return; + if (settingsChanged()) + settingsFromUI(); +} + +void HighlighterSettingsPage::finish() +{ + delete m_d->m_widget; + if (!m_d->m_page) // page was not shown + return; + delete m_d->m_page; + m_d->m_page = nullptr; +} + +const HighlighterSettings &HighlighterSettingsPage::highlighterSettings() const +{ + m_d->ensureInitialized(); + return m_d->m_settings; +} + +void HighlighterSettingsPage::settingsFromUI() +{ + m_d->ensureInitialized(); + m_d->m_settings.setDefinitionFilesPath(m_d->m_page->definitionFilesPath->path()); + m_d->m_settings.setIgnoredFilesPatterns(m_d->m_page->ignoreEdit->text()); + m_d->m_settings.toSettings(m_d->m_settingsPrefix, Core::ICore::settings()); +} + +void HighlighterSettingsPage::settingsToUI() +{ + m_d->ensureInitialized(); + m_d->m_page->definitionFilesPath->setPath(m_d->m_settings.definitionFilesPath()); + m_d->m_page->ignoreEdit->setText(m_d->m_settings.ignoredFilesPatterns()); +} + +bool HighlighterSettingsPage::settingsChanged() const +{ + m_d->ensureInitialized(); + return (m_d->m_settings.definitionFilesPath() != m_d->m_page->definitionFilesPath->path()) + || (m_d->m_settings.ignoredFilesPatterns() != m_d->m_page->ignoreEdit->text()); +} diff --git a/src/plugins/texteditor/generichighlighter/highlightersettingspage.h b/src/plugins/texteditor/highlightersettingspage.h index 86831876f9..5391016fbb 100644 --- a/src/plugins/texteditor/generichighlighter/highlightersettingspage.h +++ b/src/plugins/texteditor/highlightersettingspage.h @@ -25,8 +25,7 @@ #pragma once -#include "highlightdefinitionmetadata.h" -#include "../texteditoroptionspage.h" +#include "texteditoroptionspage.h" QT_BEGIN_NAMESPACE template <class> class QList; @@ -51,21 +50,11 @@ public: const HighlighterSettings &highlighterSettings() const; private: - void manageDefinitions(const QList<Internal::DefinitionMetaDataPtr> &metaData); - void showError(); - void ignoreDownloadReply(); - void setFallbackLocationState(bool checked); - void setDownloadDefinitionsState(bool valid); - - void resetDefinitionsLocation(); - void requestAvailableDefinitionsMetaData(); void settingsFromUI(); void settingsToUI(); bool settingsChanged() const; - bool m_requestHighlightFileRegistration; - struct HighlighterSettingsPagePrivate; HighlighterSettingsPagePrivate *m_d; }; diff --git a/src/plugins/texteditor/generichighlighter/highlightersettingspage.ui b/src/plugins/texteditor/highlightersettingspage.ui index 1861515176..bcc5d5fe11 100644 --- a/src/plugins/texteditor/generichighlighter/highlightersettingspage.ui +++ b/src/plugins/texteditor/highlightersettingspage.ui @@ -23,8 +23,7 @@ </sizepolicy> </property> <property name="text"> - <string><html><head/><body> -<p>Highlight definitions are provided by the <a href="http://kate-editor.org/">Kate Text Editor</a>.</p></body></html></string> + <string><html><head/><body><p>Highlight definitions are provided by the <a href="https://api.kde.org/frameworks/syntax-highlighting/html/index.html">KSyntaxHighlighting</a> engine.</p></body></html></string> </property> <property name="textFormat"> <enum>Qt::RichText</enum> @@ -63,13 +62,44 @@ </property> <layout class="QVBoxLayout" name="verticalLayout_3"> <item> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <widget class="QPushButton" name="updateDefinitions"> + <property name="text"> + <string>Update Definitions</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="updateStatus"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> <layout class="QHBoxLayout" name="horizontalLayout_3"> <item> <layout class="QHBoxLayout" name="horizontalLayout"> <item> <widget class="QLabel" name="locationLabel"> <property name="text"> - <string>Location:</string> + <string>User Highlight Definition Files</string> </property> </widget> </item> @@ -80,48 +110,22 @@ </item> </layout> </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout"> - <property name="spacing"> - <number>0</number> - </property> - <item> - <widget class="QCheckBox" name="useFallbackLocation"> - <property name="text"> - <string>Use fallback location</string> - </property> - </widget> - </item> - <item> - <widget class="Utils::PathChooser" name="fallbackDefinitionFilesPath" native="true"/> - </item> - </layout> - </item> </layout> </widget> </item> <item> - <widget class="QGroupBox" name="behaviorGroupBox"> - <property name="title"> - <string>Behavior</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QLabel" name="ignoreLabel"> - <property name="text"> - <string>Ignored file patterns:</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="ignoreEdit"/> - </item> - </layout> - </item> - </layout> - </widget> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="ignoreLabel"> + <property name="text"> + <string>Ignored file patterns:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="ignoreEdit"/> + </item> + </layout> </item> <item> <spacer name="verticalSpacer"> @@ -151,7 +155,6 @@ </customwidget> </customwidgets> <tabstops> - <tabstop>useFallbackLocation</tabstop> <tabstop>ignoreEdit</tabstop> </tabstops> <resources/> diff --git a/src/plugins/texteditor/highlighterutils.cpp b/src/plugins/texteditor/highlighterutils.cpp deleted file mode 100644 index 9b7332823b..0000000000 --- a/src/plugins/texteditor/highlighterutils.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "highlighterutils.h" -#include "generichighlighter/highlighter.h" -#include "generichighlighter/highlightdefinition.h" -#include "generichighlighter/manager.h" -#include <coreplugin/icore.h> -#include <utils/mimetypes/mimetype.h> - -using namespace TextEditor; -using namespace Internal; - -void TextEditor::setMimeTypeForHighlighter(Highlighter *highlighter, const Utils::MimeType &mimeType, - const QString &filePath, QString *foundDefinitionId) -{ - QString definitionId = Manager::instance()->definitionIdByMimeTypeAndFile(mimeType, filePath); - if (!definitionId.isEmpty()) { - const QSharedPointer<HighlightDefinition> &definition = - Manager::instance()->definition(definitionId); - if (!definition.isNull() && definition->isValid()) - highlighter->setDefaultContext(definition->initialContext()); - } - - if (foundDefinitionId) - *foundDefinitionId = definitionId; -} - diff --git a/src/plugins/texteditor/highlighterutils.h b/src/plugins/texteditor/highlighterutils.h deleted file mode 100644 index 57b62c0712..0000000000 --- a/src/plugins/texteditor/highlighterutils.h +++ /dev/null @@ -1,45 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include <QString> -#include "texteditor_global.h" - -/* These functions were originally a part of TextEditor::Highlighter, - * but due to a very hackish test of that generic highlighter, - * there functions must be outside. */ - -namespace Utils { class MimeType; } - -namespace TextEditor { - -class Highlighter; - -void setMimeTypeForHighlighter(Highlighter *highlighter, const Utils::MimeType &mimeType, - const QString &filePath, - QString *foundDefinitionId = nullptr); - -} // namespace TextEditor diff --git a/src/plugins/texteditor/snippets/snippetprovider.cpp b/src/plugins/texteditor/snippets/snippetprovider.cpp index 0d5caa5229..be84ef8bdb 100644 --- a/src/plugins/texteditor/snippets/snippetprovider.cpp +++ b/src/plugins/texteditor/snippets/snippetprovider.cpp @@ -25,7 +25,7 @@ #include "snippetprovider.h" -#include "texteditorplugin.h" +#include <texteditor/texteditorplugin.h> #include <utils/algorithm.h> diff --git a/src/plugins/texteditor/snippets/snippetssettingspage.cpp b/src/plugins/texteditor/snippets/snippetssettingspage.cpp index 6b947c4375..32daaa503b 100644 --- a/src/plugins/texteditor/snippets/snippetssettingspage.cpp +++ b/src/plugins/texteditor/snippets/snippetssettingspage.cpp @@ -29,10 +29,10 @@ #include "snippet.h" #include "snippetscollection.h" #include "snippetssettings.h" -#include "textdocument.h" #include "ui_snippetssettingspage.h" #include <coreplugin/icore.h> +#include <texteditor/textdocument.h> #include <texteditor/texteditorconstants.h> #include <texteditor/texteditorsettings.h> #include <extensionsystem/pluginmanager.h> diff --git a/src/plugins/texteditor/textdocument.cpp b/src/plugins/texteditor/textdocument.cpp index ef504447a5..352c609143 100644 --- a/src/plugins/texteditor/textdocument.cpp +++ b/src/plugins/texteditor/textdocument.cpp @@ -35,7 +35,6 @@ #include "texteditor.h" #include "texteditorconstants.h" #include "typingsettings.h" -#include <texteditor/generichighlighter/highlighter.h> #include <coreplugin/diffservice.h> #include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/documentmodel.h> @@ -340,9 +339,6 @@ void TextDocument::setTabSettings(const TabSettings &newTabSettings) return; d->m_tabSettings = newTabSettings; - if (auto highlighter = qobject_cast<Highlighter *>(d->m_highlighter)) - highlighter->setTabSettings(tabSettings()); - emit tabSettingsChanged(); } diff --git a/src/plugins/texteditor/textdocumentlayout.h b/src/plugins/texteditor/textdocumentlayout.h index f436b30d03..119dcb7e2c 100644 --- a/src/plugins/texteditor/textdocumentlayout.h +++ b/src/plugins/texteditor/textdocumentlayout.h @@ -30,6 +30,8 @@ #include "textmark.h" #include "textdocument.h" +#include <State> + #include <QTextBlockUserData> #include <QPlainTextDocumentLayout> @@ -133,6 +135,9 @@ public: CodeFormatterData *codeFormatterData() const { return m_codeFormatterData; } void setCodeFormatterData(CodeFormatterData *data); + KSyntaxHighlighting::State syntaxState() { return m_syntaxState; } + void setSyntaxState(KSyntaxHighlighting::State state) { m_syntaxState = state; } + private: TextMarks m_marks; int m_foldingIndent : 16; @@ -144,6 +149,7 @@ private: int m_additionalAnnotationHeight = 0; Parentheses m_parentheses; CodeFormatterData *m_codeFormatterData; + KSyntaxHighlighting::State m_syntaxState; }; diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 96cf099c5e..aed04a3ba7 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -37,31 +37,27 @@ #include "circularclipboardassist.h" #include "codecselector.h" #include "completionsettings.h" -#include "highlighterutils.h" +#include "extraencodingsettings.h" +#include "highlighter.h" +#include "highlightersettings.h" #include "icodestylepreferences.h" #include "indenter.h" +#include "refactoroverlay.h" #include "snippets/snippet.h" +#include "storagesettings.h" #include "syntaxhighlighter.h" #include "tabsettings.h" #include "textdocument.h" #include "textdocumentlayout.h" #include "texteditorconstants.h" #include "texteditoroverlay.h" -#include "refactoroverlay.h" #include "texteditorsettings.h" #include "typingsettings.h" -#include "extraencodingsettings.h" -#include "storagesettings.h" #include <texteditor/codeassist/assistinterface.h> #include <texteditor/codeassist/codeassistant.h> #include <texteditor/codeassist/completionassistprovider.h> #include <texteditor/codeassist/documentcontentcompletion.h> -#include <texteditor/generichighlighter/context.h> -#include <texteditor/generichighlighter/highlightdefinition.h> -#include <texteditor/generichighlighter/highlighter.h> -#include <texteditor/generichighlighter/highlightersettings.h> -#include <texteditor/generichighlighter/manager.h> #include <coreplugin/icore.h> #include <aggregation/aggregate.h> @@ -94,6 +90,7 @@ #include <QClipboard> #include <QCoreApplication> #include <QDebug> +#include <QFutureWatcher> #include <QGridLayout> #include <QKeyEvent> #include <QMap> @@ -847,17 +844,21 @@ TextEditorWidgetPrivate::~TextEditorWidgetPrivate() */ static void updateEditorInfoBar(TextEditorWidget *widget) { - Id infoSyntaxDefinition(Constants::INFO_SYNTAX_DEFINITION); + Id id(Constants::INFO_SYNTAX_DEFINITION); InfoBar *infoBar = widget->textDocument()->infoBar(); if (!widget->isMissingSyntaxDefinition()) { - infoBar->removeInfo(infoSyntaxDefinition); - } else if (infoBar->canInfoBeAdded(infoSyntaxDefinition)) { - InfoBarEntry info(infoSyntaxDefinition, + infoBar->removeInfo(id); + } else if (infoBar->canInfoBeAdded(id)) { + InfoBarEntry info(id, BaseTextEditor::tr("A highlight definition was not found for this file. " - "Would you like to try to find one?"), + "Would you like to update highlight definition files?"), InfoBarEntry::GlobalSuppressionEnabled); - info.setCustomButtonInfo(BaseTextEditor::tr("Show Highlighter Options..."), [widget]() { - ICore::showOptionsDialog(Constants::TEXT_EDITOR_HIGHLIGHTER_SETTINGS, widget); + info.setCustomButtonInfo(BaseTextEditor::tr("Update Definitions"), [id, widget]() { + widget->textDocument()->infoBar()->removeInfo(id); + Highlighter::updateDefinitions([widget = QPointer<TextEditorWidget>(widget)]() { + if (widget) + widget->configureGenericHighlighter(); + }); }); infoBar->addInfo(info); @@ -8463,37 +8464,30 @@ QString TextEditorWidget::textAt(int from, int to) const void TextEditorWidget::configureGenericHighlighter() { auto highlighter = new Highlighter(); - highlighter->setTabSettings(textDocument()->tabSettings()); textDocument()->setSyntaxHighlighter(highlighter); setCodeFoldingSupported(false); const QString type = textDocument()->mimeType(); const MimeType mimeType = Utils::mimeTypeForName(type); - if (mimeType.isValid()) { - d->m_isMissingSyntaxDefinition = true; - - QString definitionId; - setMimeTypeForHighlighter(highlighter, mimeType, textDocument()->filePath().toString(), - &definitionId); - - if (!definitionId.isEmpty()) { - d->m_isMissingSyntaxDefinition = false; - const QSharedPointer<HighlightDefinition> &definition = - Manager::instance()->definition(definitionId); - if (!definition.isNull() && definition->isValid()) { - d->m_commentDefinition.isAfterWhiteSpaces = definition->isCommentAfterWhiteSpaces(); - d->m_commentDefinition.singleLine = definition->singleLineComment(); - d->m_commentDefinition.multiLineStart = definition->multiLineCommentStart(); - d->m_commentDefinition.multiLineEnd = definition->multiLineCommentEnd(); - - setCodeFoldingSupported(true); - } - } else { - const QString fileName = textDocument()->filePath().toString(); - if (TextEditorSettings::highlighterSettings().isIgnoredFilePattern(fileName)) - d->m_isMissingSyntaxDefinition = false; - } + const QString fileName = textDocument()->filePath().fileName(); + KSyntaxHighlighting::Definition definition; + if (mimeType.isValid()) + definition = Highlighter::definitionForMimeType(mimeType.name()); + if (!definition.isValid()) + definition = Highlighter::definitionForFileName(fileName); + + if (definition.isValid()) { + highlighter->setDefinition(definition); + d->m_isMissingSyntaxDefinition = false; + d->m_commentDefinition.singleLine = definition.singleLineCommentMarker(); + d->m_commentDefinition.multiLineStart = definition.multiLineCommentMarker().first; + d->m_commentDefinition.multiLineEnd = definition.multiLineCommentMarker().second; + + setCodeFoldingSupported(true); + } else { + d->m_isMissingSyntaxDefinition = + !TextEditorSettings::highlighterSettings().isIgnoredFilePattern(fileName); } textDocument()->setFontSettings(TextEditorSettings::fontSettings()); @@ -8546,9 +8540,6 @@ void TextEditorWidget::setupGenericHighlighter() connect(textDocument(), &IDocument::filePathChanged, d, &TextEditorWidgetPrivate::reconfigure); - connect(Manager::instance(), &Manager::highlightingFilesRegistered, - d, &TextEditorWidgetPrivate::reconfigure); - updateEditorInfoBar(this); } diff --git a/src/plugins/texteditor/texteditor.pro b/src/plugins/texteditor/texteditor.pro index 6de9e93469..d5bf895ee4 100644 --- a/src/plugins/texteditor/texteditor.pro +++ b/src/plugins/texteditor/texteditor.pro @@ -34,23 +34,9 @@ SOURCES += texteditorplugin.cpp \ textindenter.cpp \ quickfix.cpp \ syntaxhighlighter.cpp \ - highlighterutils.cpp \ - generichighlighter/itemdata.cpp \ - generichighlighter/specificrules.cpp \ - generichighlighter/rule.cpp \ - generichighlighter/dynamicrule.cpp \ - generichighlighter/context.cpp \ - generichighlighter/includerulesinstruction.cpp \ - generichighlighter/progressdata.cpp \ - generichighlighter/keywordlist.cpp \ - generichighlighter/highlightdefinition.cpp \ - generichighlighter/highlighter.cpp \ - generichighlighter/manager.cpp \ - generichighlighter/highlightdefinitionhandler.cpp \ - generichighlighter/highlightersettingspage.cpp \ - generichighlighter/highlightersettings.cpp \ - generichighlighter/managedefinitionsdialog.cpp \ - generichighlighter/definitiondownloader.cpp \ + highlighter.cpp \ + highlightersettings.cpp \ + highlightersettingspage.cpp \ refactoringchanges.cpp \ refactoroverlay.cpp \ outlinefactory.cpp \ @@ -137,27 +123,9 @@ HEADERS += texteditorplugin.h \ textindenter.h \ quickfix.h \ syntaxhighlighter.h \ - highlighterutils.h \ - generichighlighter/reuse.h \ - generichighlighter/itemdata.h \ - generichighlighter/specificrules.h \ - generichighlighter/rule.h \ - generichighlighter/reuse.h \ - generichighlighter/dynamicrule.h \ - generichighlighter/context.h \ - generichighlighter/includerulesinstruction.h \ - generichighlighter/progressdata.h \ - generichighlighter/keywordlist.h \ - generichighlighter/highlighterexception.h \ - generichighlighter/highlightdefinition.h \ - generichighlighter/highlighter.h \ - generichighlighter/manager.h \ - generichighlighter/highlightdefinitionhandler.h \ - generichighlighter/highlightersettingspage.h \ - generichighlighter/highlightersettings.h \ - generichighlighter/managedefinitionsdialog.h \ - generichighlighter/highlightdefinitionmetadata.h \ - generichighlighter/definitiondownloader.h \ + highlighter.h \ + highlightersettings.h \ + highlightersettingspage.h \ refactoringchanges.h \ refactoroverlay.h \ outlinefactory.h \ @@ -223,14 +191,14 @@ FORMS += \ displaysettingspage.ui \ fontsettingspage.ui \ colorschemeedit.ui \ - generichighlighter/highlightersettingspage.ui \ - generichighlighter/managedefinitionsdialog.ui \ snippets/snippetssettingspage.ui \ behaviorsettingswidget.ui \ behaviorsettingspage.ui \ tabsettingswidget.ui \ completionsettingspage.ui \ - codestyleselectorwidget.ui + codestyleselectorwidget.ui \ + highlightersettingspage.ui + RESOURCES += texteditor.qrc equals(TEST, 1) { diff --git a/src/plugins/texteditor/texteditor.qbs b/src/plugins/texteditor/texteditor.qbs index 1e8b4c5be8..475e414dbc 100644 --- a/src/plugins/texteditor/texteditor.qbs +++ b/src/plugins/texteditor/texteditor.qbs @@ -1,4 +1,6 @@ import qbs 1.0 +import qbs.FileInfo +import qbs.Environment Project { name: "TextEditor" @@ -9,10 +11,14 @@ Project { Depends { name: "Qt"; submodules: ["widgets", "xml", "network", "printsupport"] } Depends { name: "Aggregation" } Depends { name: "Utils" } + Depends { name: "KSyntaxHighlighting" } + + Export { + Depends { name: "KSyntaxHighlighting" } + } Depends { name: "Core" } - cpp.includePaths: base.concat([path]) // Needed for the highlighterengine autotest. cpp.enableExceptions: true files: [ @@ -80,8 +86,13 @@ Project { "fontsettingspage.ui", "formattexteditor.cpp", "formattexteditor.h", - "highlighterutils.cpp", - "highlighterutils.h", + "highlighter.cpp", + "highlighter.h", + "highlightersettings.cpp", + "highlightersettings.h", + "highlightersettingspage.cpp", + "highlightersettingspage.h", + "highlightersettingspage.ui", "icodestylepreferences.cpp", "icodestylepreferences.h", "icodestylepreferencesfactory.cpp", @@ -198,50 +209,6 @@ Project { } Group { - name: "GenericHighlighter" - prefix: "generichighlighter/" - files: [ - "context.cpp", - "context.h", - "definitiondownloader.cpp", - "definitiondownloader.h", - "dynamicrule.cpp", - "dynamicrule.h", - "highlightdefinition.cpp", - "highlightdefinition.h", - "highlightdefinitionhandler.cpp", - "highlightdefinitionhandler.h", - "highlightdefinitionmetadata.h", - "highlighter.cpp", - "highlighter.h", - "highlighterexception.h", - "highlightersettings.cpp", - "highlightersettings.h", - "highlightersettingspage.cpp", - "highlightersettingspage.h", - "highlightersettingspage.ui", - "includerulesinstruction.cpp", - "includerulesinstruction.h", - "itemdata.cpp", - "itemdata.h", - "keywordlist.cpp", - "keywordlist.h", - "managedefinitionsdialog.cpp", - "managedefinitionsdialog.h", - "managedefinitionsdialog.ui", - "manager.cpp", - "manager.h", - "progressdata.cpp", - "progressdata.h", - "reuse.h", - "rule.cpp", - "rule.h", - "specificrules.cpp", - "specificrules.h", - ] - } - - Group { name: "Snippets" prefix: "snippets/" files: [ diff --git a/src/plugins/texteditor/texteditor_dependencies.pri b/src/plugins/texteditor/texteditor_dependencies.pri index 1bab312c8a..c624e4cfb2 100644 --- a/src/plugins/texteditor/texteditor_dependencies.pri +++ b/src/plugins/texteditor/texteditor_dependencies.pri @@ -2,6 +2,7 @@ QTC_PLUGIN_NAME = TextEditor QTC_LIB_DEPENDS += \ aggregation \ extensionsystem \ - utils + utils \ + syntax-highlighting QTC_PLUGIN_DEPENDS += \ coreplugin diff --git a/src/plugins/texteditor/texteditorplugin.cpp b/src/plugins/texteditor/texteditorplugin.cpp index 5cacd941c4..e08ecbe75d 100644 --- a/src/plugins/texteditor/texteditorplugin.cpp +++ b/src/plugins/texteditor/texteditorplugin.cpp @@ -25,16 +25,16 @@ #include "texteditorplugin.h" -#include "texteditor.h" #include "findincurrentfile.h" #include "findinfiles.h" #include "findinopenfiles.h" #include "fontsettings.h" -#include "generichighlighter/manager.h" +#include "highlighter.h" #include "linenumberfilter.h" #include "outlinefactory.h" #include "plaintexteditorfactory.h" #include "snippets/snippetprovider.h" +#include "texteditor.h" #include "texteditoractionhandler.h" #include "texteditorsettings.h" @@ -144,9 +144,6 @@ bool TextEditorPlugin::initialize(const QStringList &arguments, QString *errorMe editor->editorWidget()->showContextMenu(); }); - // Generic highlighter. - connect(ICore::instance(), &ICore::coreOpened, Manager::instance(), &Manager::registerHighlightingFiles); - // Add text snippet provider. SnippetProvider::registerGroup(Constants::TEXT_SNIPPET_GROUP_ID, tr("Text", "SnippetProvider")); @@ -229,6 +226,12 @@ LineNumberFilter *TextEditorPlugin::lineNumberFilter() return &m_instance->d->lineNumberFilter; } +ExtensionSystem::IPlugin::ShutdownFlag TextEditorPlugin::aboutToShutdown() +{ + Highlighter::handleShutdown(); + return SynchronousShutdown; +} + void TextEditorPluginPrivate::updateSearchResultsFont(const FontSettings &settings) { if (auto window = SearchResultWindow::instance()) { diff --git a/src/plugins/texteditor/texteditorplugin.h b/src/plugins/texteditor/texteditorplugin.h index 297cde9a8b..e5dba0f4ac 100644 --- a/src/plugins/texteditor/texteditorplugin.h +++ b/src/plugins/texteditor/texteditorplugin.h @@ -44,6 +44,8 @@ public: static TextEditorPlugin *instance(); static LineNumberFilter *lineNumberFilter(); + ShutdownFlag aboutToShutdown() override; + private: bool initialize(const QStringList &arguments, QString *errorMessage) final; void extensionsInitialized() final; diff --git a/src/plugins/texteditor/texteditorsettings.cpp b/src/plugins/texteditor/texteditorsettings.cpp index c6b1710c7c..78cea2b828 100644 --- a/src/plugins/texteditor/texteditorsettings.cpp +++ b/src/plugins/texteditor/texteditorsettings.cpp @@ -25,23 +25,24 @@ #include "texteditorsettings.h" -#include "fontsettings.h" -#include "texteditor.h" #include "behaviorsettings.h" #include "behaviorsettingspage.h" #include "completionsettings.h" -#include "marginsettings.h" +#include "completionsettingspage.h" #include "displaysettings.h" #include "displaysettingspage.h" -#include "fontsettingspage.h" -#include "typingsettings.h" -#include "storagesettings.h" -#include "tabsettings.h" #include "extraencodingsettings.h" +#include "fontsettings.h" +#include "fontsettingspage.h" +#include "highlightersettingspage.h" #include "icodestylepreferences.h" #include "icodestylepreferencesfactory.h" -#include "completionsettingspage.h" -#include <texteditor/generichighlighter/highlightersettingspage.h> +#include "marginsettings.h" +#include "storagesettings.h" +#include "tabsettings.h" +#include "texteditor.h" +#include "typingsettings.h" + #include <texteditor/snippets/snippetssettingspage.h> #include <extensionsystem/pluginmanager.h> diff --git a/src/share/3rdparty/data.pro b/src/share/3rdparty/data.pro index 17ad36c8d2..3c3ab29bcd 100644 --- a/src/share/3rdparty/data.pro +++ b/src/share/3rdparty/data.pro @@ -7,7 +7,6 @@ STATIC_OUTPUT_BASE = $$IDE_DATA_PATH STATIC_INSTALL_BASE = $$INSTALL_DATA_PATH DATA_DIRS = \ - generic-highlighter \ fonts for(data_dir, DATA_DIRS) { diff --git a/src/share/3rdparty/generic-highlighter/autoconf.xml b/src/share/3rdparty/generic-highlighter/autoconf.xml deleted file mode 100644 index 71740f8a8c..0000000000 --- a/src/share/3rdparty/generic-highlighter/autoconf.xml +++ /dev/null @@ -1,396 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE language SYSTEM "/opt/kde3/share/apps/katepart/syntax/language.dtd"> -<!-- (c) 2008-2011 by Jürgen Heinemann http://www.hjcms.de - @see http://www.gnu.org/software/automake/manual/autoconf/ ---> -<language name="Autoconf Language" version="1.11" kateversion="2.4" section="Other" - extensions="configure.ac;configure.in;configure.in.in;*.m4;*.M4" - mimetype="text/x-m4;text/x-autoconf" - author="Juergen Heinemann (nospam@hjcms.de)" license="LGPL"> - <highlighting> - <!-- http://www.gnu.org/software/automake/manual/autoconf/Program-_0026-Function-Index.html --> - <list name="keywords"> - <item> if </item> - <item> then </item> - <item> elif </item> - <item> else </item> - <item> fi </item> - <item> for </item> - <item> in </item> - <item> do </item> - <item> don </item> - <item> function </item> - <item> select </item> - <item> until </item> - <item> while </item> - <item> set </item> - <item> ifelse </item> - <item> case </item> - <item> esac </item> - </list> - - <!-- http://www.gnu.org/software/automake/manual/autoconf/Limitations-of-Builtins.html --> - <list name="builtins"> - <item> : </item> - <item> source </item> - <item> alias </item> - <item> bg </item> - <item> bind </item> - <item> break </item> - <item> builtin </item> - <item> cd </item> - <item> caller </item> - <item> command </item> - <item> compgen </item> - <item> complete </item> - <item> continue </item> - <item> dirs </item> - <item> disown </item> - <item> echo </item> - <item> enable </item> - <item> eval </item> - <item> exec </item> - <item> exit </item> - <item> fc </item> - <item> fg </item> - <item> getopts </item> - <item> hash </item> - <item> help </item> - <item> history </item> - <item> jobs </item> - <item> kill </item> - <item> let </item> - <item> logout </item> - <item> popd </item> - <item> printf </item> - <item> pushd </item> - <item> pwd </item> - <item> return </item> - <item> set </item> - <item> shift </item> - <item> shopt </item> - <item> suspend </item> - <item> test </item> - <item> time </item> - <item> times </item> - <item> trap </item> - <item> type </item> - <item> ulimit </item> - <item> umask </item> - <item> unalias </item> - <item> wait </item> - </list> - - <list name="bools"> - <item> no </item> - <item> yes </item> - <item> false </item> - <item> true </item> - </list> - - <!-- - This is an alphabetical list of the M4, M4sugar, and M4sh macros. - http://www.gnu.org/software/automake/manual/autoconf/M4-Macro-Index.html - --> - <list name="m4sugar"> - <item> AS_BOURNE_COMPATIBLE </item> - <item> AS_BOX </item> - <item> AS_CASE </item> - <item> AS_DIRNAME </item> - <item> AS_ECHO </item> - <item> AS_ECHO_N </item> - <item> AS_ESCAPE </item> - <item> AS_EXIT </item> - <item> AS_HELP_STRING </item> - <item> AS_IF </item> - <item> AS_INIT </item> - <item> AS_INIT_GENERATED </item> - <item> AS_LINENO_PREPARE </item> - <item> AS_LITERAL_IF </item> - <item> AS_LITERAL_WORD_IF </item> - <item> AS_ME_PREPARE </item> - <item> AS_MESSAGE_FD </item> - <item> AS_MESSAGE_LOG_FD </item> - <item> AS_MKDIR_P </item> - <item> AS_ORIGINAL_STDIN_FD </item> - <item> AS_SET_CATFILE </item> - <item> AS_SET_STATUS </item> - <item> AS_SHELL_SANITIZE </item> - <item> AS_TMPDIR </item> - <item> AS_TR_CPP </item> - <item> AS_TR_SH </item> - <item> AS_UNSET </item> - <item> AS_VAR_APPEND </item> - <item> AS_VAR_ARITH </item> - <item> AS_VAR_COPY </item> - <item> AS_VAR_IF </item> - <item> AS_VAR_POPDEF </item> - <item> AS_VAR_PUSHDEF </item> - <item> AS_VAR_SET </item> - <item> AS_VAR_SET_IF </item> - <item> AS_VAR_TEST_SET </item> - <item> AS_VERSION_COMPARE </item> - <item> m4_append </item> - <item> m4_append_uniq </item> - <item> m4_append_uniq_w </item> - <item> m4_apply </item> - <item> m4_argn </item> - <item> m4_assert </item> - <item> m4_bmatch </item> - <item> m4_bpatsubst </item> - <item> m4_bpatsubsts </item> - <item> m4_bregexp </item> - <item> m4_builtin </item> - <item> m4_car </item> - <item> m4_case </item> - <item> m4_cdr </item> - <item> m4_changecom </item> - <item> m4_changequote </item> - <item> m4_chomp </item> - <item> m4_chomp_all </item> - <item> m4_cleardivert </item> - <item> m4_cmp </item> - <item> m4_combine </item> - <item> m4_cond </item> - <item> m4_copy </item> - <item> m4_copy_force </item> - <item> m4_count </item> - <item> m4_curry </item> - <item> m4_debugfile </item> - <item> m4_debugmode </item> - <item> m4_decr </item> - <item> m4_default </item> - <item> m4_default_nblank </item> - <item> m4_default_nblank_quoted </item> - <item> m4_default_quoted </item> - <item> m4_define </item> - <item> m4_define_default </item> - <item> m4_defn </item> - <item> m4_divert </item> - <item> m4_divert_once </item> - <item> m4_divert_pop </item> - <item> m4_divert_push </item> - <item> m4_divert_text </item> - <item> m4_divnum </item> - <item> m4_do </item> - <item> m4_dquote </item> - <item> m4_dquote_elt </item> - <item> m4_dumpdef </item> - <item> m4_dumpdefs </item> - <item> m4_echo </item> - <item> m4_errprint </item> - <item> m4_errprintn </item> - <item> m4_escape </item> - <item> m4_esyscmd </item> - <item> m4_esyscmd_s </item> - <item> m4_eval </item> - <item> m4_exit </item> - <item> m4_expand </item> - <item> m4_fatal </item> - <item> m4_flatten </item> - <item> m4_for </item> - <item> m4_foreach </item> - <item> m4_foreach_w </item> - <item> m4_format </item> - <item> m4_if </item> - <item> m4_ifblank </item> - <item> m4_ifdef </item> - <item> m4_ifnblank </item> - <item> m4_ifndef </item> - <item> m4_ifset </item> - <item> m4_ifval </item> - <item> m4_ifvaln </item> - <item> m4_ignore </item> - <item> m4_include </item> - <item> m4_incr </item> - <item> m4_index </item> - <item> m4_indir </item> - <item> m4_init </item> - <item> m4_join </item> - <item> m4_joinall </item> - <item> m4_len </item> - <item> m4_list_cmp </item> - <item> m4_location </item> - <item> m4_make_list </item> - <item> m4_maketemp </item> - <item> m4_map </item> - <item> m4_map_args </item> - <item> m4_map_args_pair </item> - <item> m4_map_args_sep </item> - <item> m4_map_args_w </item> - <item> m4_map_sep </item> - <item> m4_mapall </item> - <item> m4_mapall_sep </item> - <item> m4_max </item> - <item> m4_min </item> - <item> m4_mkstemp </item> - <item> m4_n </item> - <item> m4_newline </item> - <item> m4_normalize </item> - <item> m4_pattern_allow </item> - <item> m4_pattern_forbid </item> - <item> m4_popdef </item> - <item> m4_pushdef </item> - <item> m4_quote </item> - <item> m4_re_escape </item> - <item> m4_rename </item> - <item> m4_rename_force </item> - <item> m4_reverse </item> - <item> m4_set_add </item> - <item> m4_set_add_all </item> - <item> m4_set_contains </item> - <item> m4_set_contents </item> - <item> m4_set_delete </item> - <item> m4_set_difference </item> - <item> m4_set_dump </item> - <item> m4_set_empty </item> - <item> m4_set_foreach </item> - <item> m4_set_intersection </item> - <item> m4_set_list </item> - <item> m4_set_listc </item> - <item> m4_set_map </item> - <item> m4_set_map_sep </item> - <item> m4_set_remove </item> - <item> m4_set_size </item> - <item> m4_set_union </item> - <item> m4_shift </item> - <item> m4_shift2 </item> - <item> m4_shift3 </item> - <item> m4_shiftn </item> - <item> m4_sign </item> - <item> m4_sinclude </item> - <item> m4_split </item> - <item> m4_stack_foreach </item> - <item> m4_stack_foreach_lifo </item> - <item> m4_stack_foreach_sep </item> - <item> m4_stack_foreach_sep_lifo </item> - <item> m4_strip </item> - <item> m4_substr </item> - <item> m4_syscmd </item> - <item> m4_sysval </item> - <item> m4_text_box </item> - <item> m4_text_wrap </item> - <item> m4_tolower </item> - <item> m4_toupper </item> - <item> m4_traceoff </item> - <item> m4_traceon </item> - <item> m4_translit </item> - <item> m4_undefine </item> - <item> m4_undivert </item> - <item> m4_unquote </item> - <item> m4_version_compare </item> - <item> m4_version_prereq </item> - <item> m4_warn </item> - <item> m4_wrap </item> - <item> m4_wrap_lifo </item> - </list> - - <!-- Autotest Macro Index --> - <list name="autotest_macro"> - <item> AT_ARG_OPTION </item> - <item> AT_ARG_OPTION_ARG </item> - <item> AT_BANNER </item> - <item> AT_CAPTURE_FILE </item> - <item> AT_CHECK </item> - <item> AT_CHECK_EUNIT </item> - <item> AT_CHECK_UNQUOTED </item> - <item> AT_CLEANUP </item> - <item> AT_COLOR_TESTS </item> - <item> AT_COPYRIGHT </item> - <item> AT_DATA </item> - <item> AT_FAIL_IF </item> - <item> AT_INIT </item> - <item> AT_KEYWORDS </item> - <item> AT_PACKAGE_BUGREPORT </item> - <item> AT_PACKAGE_NAME </item> - <item> AT_PACKAGE_STRING </item> - <item> AT_PACKAGE_TARNAME </item> - <item> AT_PACKAGE_URL </item> - <item> AT_PACKAGE_VERSION </item> - <item> AT_SETUP </item> - <item> AT_SKIP_IF </item> - <item> AT_TESTED </item> - <item> AT_XFAIL_IF </item> - </list> - - <list name="libtool"> - <item> LT_PREREQ </item> - <item> LT_LANG </item> - <item> LT_INIT </item> - <item> LTDL_INIT </item> - <item> LT_CONFIG_LTDL_DIR </item> - </list> - - <list name="pkgconfig"> - <item> PKG_CHECK_MODULES </item> - <item> PKG_PROG_PKG_CONFIG </item> - <item> PKG_CHECK_EXISTS </item> - </list> - - <contexts> - <context attribute="Normal Text" lineEndContext="#stay" name="Default"> - <!-- <IncludeRules context="##Bash" /> --> - <keyword attribute="Keyword" context="#stay" String="keywords" /> - <RegExpr attribute="Builtin" context="#stay" String="\.(?=\s)" /> - <keyword attribute="Builtin" context="#stay" String="builtins" /> - <keyword attribute="Boolean" context="#stay" String="bools" /> - <!-- Autoconf Macros --> - <keyword attribute="M4 Sugar Macros" context="#stay" String="m4sugar" /> - <!-- Autotest Macro Index --> - <keyword attribute="Autotest Macros" context="#stay" String="autotest_macro" /> - <!-- Other Macros --> - <keyword attribute="pkg-config Macros" context="#stay" String="pkgconfig" /> - <!-- libtool Macros --> - <keyword attribute="Libtool Macros" context="#stay" String="libtool" /> - <!-- Autoconf Macros --> - <RegExpr attribute="Autoconf Macros" context="#stay" String="\bAC_[A-Z0-9_]+\b" insensitive="false" endRegion="BeginRegion" /> - <!-- Automake Macros --> - <RegExpr attribute="Automake Macros" context="#stay" String="\bAM_[A-Z0-9_]+\b" insensitive="false" endRegion="BeginRegion" /> - <!-- Script temp Defined Macros --> - <RegExpr attribute="Inline Macros" context="#stay" String="\bac_[a-z_]+\b" insensitive="false" endRegion="BeginRegion" /> - <RegExpr attribute="Char" context="#stay" String="'.'"/> - <DetectChar attribute="String" context="String" char="""/> - <AnyChar attribute="Symbol" context="#stay" String=":!%&()+,-/.*<=>|"/> - <RegExpr attribute="Variable" context="#stay" String="\$[a-z_]+" insensitive="true" endRegion="BeginRegion" /> - <Float attribute="Float" context="#stay"/> - <Int attribute="Decimal" context="#stay"/> - <RegExpr attribute="Pragmas" context="#stay" String="([\s\t]+#).*$" insensitive="true" endRegion="BeginRegion" /> - <RegExpr attribute="Comment" context="#stay" String="(^#).*$" insensitive="true" endRegion="BeginRegion" /> - <RegExpr attribute="Comment" context="#stay" String="(\bdnl\s).*$" insensitive="true" endRegion="BeginRegion" /> - </context> - <context attribute="Region Marker" lineEndContext="#pop" name="Region Marker"/> - <context attribute="String" lineEndContext="#pop" name="String"> - <DetectChar attribute="String" context="#pop" char="""/> - </context> - </contexts> - <itemDatas> - <itemData name="Normal Text" defStyleNum="dsNormal" /> - <itemData name="Keyword" defStyleNum="dsKeyword" /> - <itemData name="Builtin" defStyleNum="dsKeyword" color="#808" /> - <itemData name="M4 Sugar Macros" defStyleNum="dsKeyword" /> - <itemData name="Autotest Macros" defStyleNum="dsKeyword" /> - <itemData name="Autoconf Macros" defStyleNum="dsKeyword" color="#0095ff" selColor="#ffffff" bold="1" /> - <itemData name="Automake Macros" defStyleNum="dsKeyword" color="#6666cc" selColor="#ffffff" bold="1" /> - <itemData name="Libtool Macros" defStyleNum="dsKeyword" color="#6666cc" selColor="#ffffff" bold="1" /> - <itemData name="Inline Macros" defStyleNum="dsKeyword" color="#6666cc" selColor="#ffffff" /> - <itemData name="pkg-config Macros" defStyleNum="dsKeyword" /> - <itemData name="Boolean" defStyleNum="dsOthers" /> - <itemData name="Variable" defStyleNum="dsOthers" /> - <itemData name="Decimal" defStyleNum="dsDecVal" /> - <itemData name="Float" defStyleNum="dsFloat" /> - <itemData name="Char" defStyleNum="dsChar" /> - <itemData name="String" defStyleNum="dsString" /> - <itemData name="Pragmas" defStyleNum="dsOthers" color="#00C000" /> - <itemData name="Comment" defStyleNum="dsComment" /> - <itemData name="Symbol" defStyleNum="dsNormal"/> - <itemData name="Region Marker" defStyleNum="dsRegionMarker" /> - </itemDatas> - </highlighting> - <general> - <comments> - <comment name="singleLine" start="dnl" /> - <comment name="multiLine" start="/*" end="*/" /> - </comments> - <keywords casesensitive="0" /> - </general> -</language> diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 78e8634810..d68d3ed43f 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -10,7 +10,6 @@ SUBDIRS += \ extensionsystem \ externaltool \ environment \ - generichighlighter \ pointeralgorithm \ profilewriter \ ssh \ diff --git a/tests/auto/auto.qbs b/tests/auto/auto.qbs index 1b6c5a7b30..895f7d8da8 100644 --- a/tests/auto/auto.qbs +++ b/tests/auto/auto.qbs @@ -14,7 +14,6 @@ Project { "extensionsystem/extensionsystem.qbs", "externaltool/externaltool.qbs", "filesearch/filesearch.qbs", - "generichighlighter/generichighlighter.qbs", "json/json.qbs", "languageserverprotocol/languageserverprotocol.qbs", "profilewriter/profilewriter.qbs", diff --git a/tests/auto/generichighlighter/generichighlighter.pro b/tests/auto/generichighlighter/generichighlighter.pro deleted file mode 100644 index a4fea71061..0000000000 --- a/tests/auto/generichighlighter/generichighlighter.pro +++ /dev/null @@ -1,2 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS += highlighterengine specificrules diff --git a/tests/auto/generichighlighter/generichighlighter.qbs b/tests/auto/generichighlighter/generichighlighter.qbs deleted file mode 100644 index 07ab96a02e..0000000000 --- a/tests/auto/generichighlighter/generichighlighter.qbs +++ /dev/null @@ -1,11 +0,0 @@ -import qbs - -Project { - name: "Generic highlighter autotests" - property path genericHighlighterDir: project.ide_source_tree - + "/src/plugins/texteditor/generichighlighter" - references: [ - "highlighterengine/highlighterengine.qbs", - "specificrules/specificrules.qbs" - ] -} diff --git a/tests/auto/generichighlighter/highlighterengine/formats.cpp b/tests/auto/generichighlighter/highlighterengine/formats.cpp deleted file mode 100644 index cf8fc790cf..0000000000 --- a/tests/auto/generichighlighter/highlighterengine/formats.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "formats.h" - -#include <Qt> - -Formats::Formats() -{ - m_keywordFormat.setForeground(Qt::darkGray); - m_dataTypeFormat.setForeground(Qt::gray); - m_decimalFormat.setForeground(Qt::lightGray); - m_baseNFormat.setForeground(Qt::red); - m_floatFormat.setForeground(Qt::green); - m_charFormat.setForeground(Qt::blue); - m_stringFormat.setForeground(Qt::cyan); - m_commentFormat.setForeground(Qt::magenta); - m_alertFormat.setForeground(Qt::yellow); - m_errorFormat.setForeground(Qt::darkRed); - m_functionFormat.setForeground(Qt::darkGreen); - m_regionMarkerFormat.setForeground(Qt::darkBlue); - m_othersFormat.setForeground(Qt::darkCyan); -} - -Formats &Formats::instance() -{ - static Formats formats; - return formats; -} - -QString Formats::name(const QTextCharFormat &format) const -{ - if (format == QTextCharFormat()) - return "Default format"; - else if (format == m_keywordFormat) - return "Keyword"; - else if (format == m_dataTypeFormat) - return "Data type format"; - else if (format == m_decimalFormat) - return "Decimal format"; - else if (format == m_baseNFormat) - return "Base N format"; - else if (format == m_floatFormat) - return "Float format"; - else if (format == m_charFormat) - return "Char format"; - else if (format == m_stringFormat) - return "String format"; - else if (format == m_commentFormat) - return "Comment format"; - else if (format == m_alertFormat) - return "Alert format"; - else if (format == m_errorFormat) - return "Error format"; - else if (format == m_functionFormat) - return "Function format"; - else if (format == m_regionMarkerFormat) - return "Region Marker format"; - else if (format == m_othersFormat) - return "Others format"; - else - return "Unidentified format"; -} diff --git a/tests/auto/generichighlighter/highlighterengine/formats.h b/tests/auto/generichighlighter/highlighterengine/formats.h deleted file mode 100644 index 11c3916a8b..0000000000 --- a/tests/auto/generichighlighter/highlighterengine/formats.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include <QTextCharFormat> - -class Formats -{ -public: - static Formats &instance(); - - const QTextCharFormat &keywordFormat() const { return m_keywordFormat; } - const QTextCharFormat &dataTypeFormat() const { return m_dataTypeFormat; } - const QTextCharFormat &decimalFormat() const { return m_decimalFormat; } - const QTextCharFormat &baseNFormat() const { return m_baseNFormat; } - const QTextCharFormat &floatFormat() const { return m_floatFormat; } - const QTextCharFormat &charFormat() const { return m_charFormat; } - const QTextCharFormat &stringFormat() const { return m_stringFormat; } - const QTextCharFormat &commentFormat() const { return m_commentFormat; } - const QTextCharFormat &alertFormat() const { return m_alertFormat; } - const QTextCharFormat &errorFormat() const { return m_errorFormat; } - const QTextCharFormat &functionFormat() const { return m_functionFormat; } - const QTextCharFormat ®ionMarketFormat() const { return m_regionMarkerFormat; } - const QTextCharFormat &othersFormat() const { return m_othersFormat; } - - QString name(const QTextCharFormat &format) const; - -private: - Formats(); - Q_DISABLE_COPY(Formats); - - QTextCharFormat m_keywordFormat; - QTextCharFormat m_dataTypeFormat; - QTextCharFormat m_decimalFormat; - QTextCharFormat m_baseNFormat; - QTextCharFormat m_floatFormat; - QTextCharFormat m_charFormat; - QTextCharFormat m_stringFormat; - QTextCharFormat m_commentFormat; - QTextCharFormat m_alertFormat; - QTextCharFormat m_errorFormat; - QTextCharFormat m_functionFormat; - QTextCharFormat m_regionMarkerFormat; - QTextCharFormat m_othersFormat; -}; diff --git a/tests/auto/generichighlighter/highlighterengine/highlighterengine.pro b/tests/auto/generichighlighter/highlighterengine/highlighterengine.pro deleted file mode 100644 index d78de7871e..0000000000 --- a/tests/auto/generichighlighter/highlighterengine/highlighterengine.pro +++ /dev/null @@ -1,39 +0,0 @@ -QTC_PLUGIN_DEPENDS += coreplugin texteditor -include(../../qttest.pri) -QT += gui -PLUGINSDIR = $$IDE_SOURCE_TREE/src/plugins -GENERICHIGHLIGHTERDIR = $$PLUGINSDIR/texteditor/generichighlighter - -SOURCES += \ - tst_highlighterengine.cpp \ - highlightermock.cpp \ - formats.cpp \ - textdocumentlayout.cpp \ - syntaxhighlighter.cpp \ - $$GENERICHIGHLIGHTERDIR/highlighter.cpp \ - $$GENERICHIGHLIGHTERDIR/context.cpp \ - $$GENERICHIGHLIGHTERDIR/dynamicrule.cpp \ - $$GENERICHIGHLIGHTERDIR/rule.cpp \ - $$GENERICHIGHLIGHTERDIR/specificrules.cpp \ - $$GENERICHIGHLIGHTERDIR/progressdata.cpp \ - $$GENERICHIGHLIGHTERDIR/highlightdefinition.cpp \ - $$GENERICHIGHLIGHTERDIR/keywordlist.cpp \ - $$GENERICHIGHLIGHTERDIR/itemdata.cpp - -HEADERS += \ - highlightermock.h \ - formats.h \ - textdocumentlayout.h \ - syntaxhighlighter.h \ - tabsettings.h \ - $$GENERICHIGHLIGHTERDIR/highlighter.h \ - $$GENERICHIGHLIGHTERDIR/context.h \ - $$GENERICHIGHLIGHTERDIR/dynamicrule.h \ - $$GENERICHIGHLIGHTERDIR/rule.h \ - $$GENERICHIGHLIGHTERDIR/specificrules.h \ - $$GENERICHIGHLIGHTERDIR/progressdata.h \ - $$GENERICHIGHLIGHTERDIR/highlightdefinition.h \ - $$GENERICHIGHLIGHTERDIR/keywordlist.h \ - $$GENERICHIGHLIGHTERDIR/itemdata.h - -INCLUDEPATH += $$PWD diff --git a/tests/auto/generichighlighter/highlighterengine/highlighterengine.qbs b/tests/auto/generichighlighter/highlighterengine/highlighterengine.qbs deleted file mode 100644 index 8e12d56d15..0000000000 --- a/tests/auto/generichighlighter/highlighterengine/highlighterengine.qbs +++ /dev/null @@ -1,45 +0,0 @@ -import qbs - -QtcAutotest { - name: "Highlighter engine autotest" - Depends { name: "Core" } - Depends { name: "Utils" } - Depends { name: "TextEditor" } - Depends { name: "Qt.widgets" } - Group { - name: "Sources from TextEditor plugin" - prefix: project.genericHighlighterDir + '/' - files: [ - "context.h", "context.cpp", - "dynamicrule.h", "dynamicrule.cpp", - "highlightdefinition.h", "highlightdefinition.cpp", - "highlighter.h", "highlighter.cpp", - "itemdata.h", "itemdata.cpp", - "keywordlist.h", "keywordlist.cpp", - "progressdata.h", "progressdata.cpp", - "rule.h", "rule.cpp", - "specificrules.h", "specificrules.cpp" - ] - } - Group { - name: "Test sources" - files: [ - "formats.h", "formats.cpp", - "highlightermock.h", "highlightermock.cpp", - "tst_highlighterengine.cpp" - ] - } - Group { - name: "Drop-in sources for the plugin" - files: [ - "textdocumentlayout.h", "textdocumentlayout.cpp", - "syntaxhighlighter.h", "syntaxhighlighter.cpp", - "tabsettings.h" - ] - } - - cpp.includePaths: base.concat([ - path, - project.genericHighlighterDir + "/../..", - ]) -} diff --git a/tests/auto/generichighlighter/highlighterengine/highlightermock.cpp b/tests/auto/generichighlighter/highlighterengine/highlightermock.cpp deleted file mode 100644 index 1cdabee5d3..0000000000 --- a/tests/auto/generichighlighter/highlighterengine/highlightermock.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "formats.h" -#include "highlightermock.h" - -#include <texteditor/generichighlighter/context.h> -#include <texteditor/generichighlighter/highlightdefinition.h> - -#include <QDebug> -#include <QtTest> - -QT_BEGIN_NAMESPACE -namespace QTest { - template<> inline char *toString(const QTextCharFormat &format) - { - QByteArray ba = Formats::instance().name(format).toLatin1(); - return qstrdup(ba.data()); - } -} -QT_END_NAMESPACE - -using namespace TextEditor; -using namespace Internal; - -HighlighterMock::HighlighterMock(QTextDocument *parent) : - Highlighter(parent), - m_statesCounter(0), - m_formatsCounter(0), - m_debugDetails(false), - m_noTestCall(false), - m_considerEmptyLines(false) -{} - -void HighlighterMock::reset() -{ - m_states.clear(); - m_statesCounter = 0; - m_formatSequence.clear(); - m_formatsCounter = 0; - m_debugDetails = false; - m_noTestCall = false; - m_considerEmptyLines = false; -} - -void HighlighterMock::showDebugDetails() -{ m_debugDetails = true; } - -void HighlighterMock::considerEmptyLines() -{ m_considerEmptyLines = true; } - -void HighlighterMock::startNoTestCalls() -{ m_noTestCall = true; } - -void HighlighterMock::endNoTestCalls() -{ m_noTestCall = false; } - -void HighlighterMock::setExpectedBlockState(const int state) -{ m_states << state; } - -void HighlighterMock::setExpectedBlockStates(const QList<int> &states) -{ m_states = states; } - -void HighlighterMock::setExpectedHighlightSequence(const HighlightSequence &format) -{ m_formatSequence << format; } - -void HighlighterMock::setExpectedHighlightSequences(const QList<HighlightSequence> &formats) -{ m_formatSequence = formats; } - -void HighlighterMock::highlightBlock(const QString &text) -{ - Highlighter::highlightBlock(text); - - if (text.isEmpty() && !m_considerEmptyLines) - return; - - if (m_noTestCall) - return; - - if (m_states.isEmpty() || m_formatSequence.isEmpty()) - QFAIL("No expected data setup."); - - if (m_debugDetails) - qDebug() << "Highlighting" << text; - - if (m_states.size() <= m_statesCounter) - QFAIL("Expected state for current block not set."); - const int observableState = currentBlockState() & 0xFFF; - QCOMPARE(observableState, m_states.at(m_statesCounter++)); - - if (m_formatSequence.size() <= m_formatsCounter) - QFAIL("Expected highlight sequence for current block not set."); - for (int i = 0; i < text.length(); ++i) { - if (text.at(i).isSpace()) - continue; - if (m_debugDetails) - qDebug() << "at offset" << i; - QCOMPARE(format(i), m_formatSequence.at(m_formatsCounter).m_formats.at(i)); - } - ++m_formatsCounter; -} diff --git a/tests/auto/generichighlighter/highlighterengine/highlightermock.h b/tests/auto/generichighlighter/highlighterengine/highlightermock.h deleted file mode 100644 index 09cfcef5bb..0000000000 --- a/tests/auto/generichighlighter/highlighterengine/highlightermock.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include <texteditor/generichighlighter/highlighter.h> - -#include <QList> - -struct HighlightSequence -{ - HighlightSequence() {} - HighlightSequence(int from, int to, const QTextCharFormat &format = QTextCharFormat()) - { add(from, to, format); } - HighlightSequence(const HighlightSequence &sequence) - { m_formats = sequence.m_formats; } - - void add(int from, int to, const QTextCharFormat &format = QTextCharFormat()) - { - for (int i = from; i < to; ++i) - m_formats.append(format); - } - - QList<QTextCharFormat> m_formats; -}; - -class HighlighterMock : public TextEditor::Highlighter -{ -public: - HighlighterMock(QTextDocument *parent = 0); - - void reset(); - void showDebugDetails(); - void considerEmptyLines(); - - void startNoTestCalls(); - void endNoTestCalls(); - - void setExpectedBlockState(const int state); - void setExpectedBlockStates(const QList<int> &states); - void setExpectedHighlightSequence(const HighlightSequence &format); - void setExpectedHighlightSequences(const QList<HighlightSequence> &formats); - -protected: - virtual void highlightBlock(const QString &text); - -private: - QList<int> m_states; - int m_statesCounter; - QList<HighlightSequence> m_formatSequence; - int m_formatsCounter; - bool m_debugDetails; - bool m_noTestCall; - bool m_considerEmptyLines; -}; diff --git a/tests/auto/generichighlighter/highlighterengine/syntaxhighlighter.cpp b/tests/auto/generichighlighter/highlighterengine/syntaxhighlighter.cpp deleted file mode 100644 index 4e4a9cfb47..0000000000 --- a/tests/auto/generichighlighter/highlighterengine/syntaxhighlighter.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "syntaxhighlighter.h" -#include "formats.h" - -#include <texteditor/fontsettings.h> -#include <texteditor/generichighlighter/highlighter.h> - -using namespace TextEditor; -using namespace Internal; - -QTextCharFormat SyntaxHighlighter::formatForCategory(int categoryIndex) const -{ - switch (categoryIndex) { - case Highlighter::Keyword: return Formats::instance().keywordFormat(); - case Highlighter::DataType: return Formats::instance().dataTypeFormat(); - case Highlighter::Decimal: return Formats::instance().decimalFormat(); - case Highlighter::BaseN: return Formats::instance().baseNFormat(); - case Highlighter::Float: return Formats::instance().floatFormat(); - case Highlighter::Char: return Formats::instance().charFormat(); - case Highlighter::String: return Formats::instance().stringFormat(); - case Highlighter::Comment: return Formats::instance().commentFormat(); - case Highlighter::Alert: return Formats::instance().alertFormat(); - case Highlighter::Error: return Formats::instance().errorFormat(); - case Highlighter::Function: return Formats::instance().functionFormat(); - case Highlighter::RegionMarker: return Formats::instance().regionMarketFormat(); - case Highlighter::Others: return Formats::instance().othersFormat(); - default: return QTextCharFormat(); - } -} - -FontSettings SyntaxHighlighter::fontSettings() const -{ - return FontSettings(); -} diff --git a/tests/auto/generichighlighter/highlighterengine/textdocumentlayout.cpp b/tests/auto/generichighlighter/highlighterengine/textdocumentlayout.cpp deleted file mode 100644 index 5b0d50f0e7..0000000000 --- a/tests/auto/generichighlighter/highlighterengine/textdocumentlayout.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "textdocumentlayout.h" - -namespace TextEditor { - -TextBlockUserData *TextDocumentLayout::userData(const QTextBlock &block) -{ - TextBlockUserData *data = static_cast<TextBlockUserData*>(block.userData()); - if (!data && block.isValid()) - const_cast<QTextBlock &>(block).setUserData((data = new TextBlockUserData)); - return data; -} - -void TextDocumentLayout::setParentheses(const QTextBlock &, const Parentheses &) {} - -} // namespace TextEditor diff --git a/tests/auto/generichighlighter/highlighterengine/textdocumentlayout.h b/tests/auto/generichighlighter/highlighterengine/textdocumentlayout.h deleted file mode 100644 index aa0751c484..0000000000 --- a/tests/auto/generichighlighter/highlighterengine/textdocumentlayout.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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. -** -****************************************************************************/ - -#pragma once - -#include <QTextBlockUserData> - -// Replaces the "real" textdocumentlayout.h file. -namespace TextEditor { -struct Parenthesis; -typedef QVector<Parenthesis> Parentheses; - -struct Parenthesis -{ - enum Type { Opened, Closed }; - - inline Parenthesis() : type(Opened), pos(-1) {} - inline Parenthesis(Type t, QChar c, int position) - : type(t), chr(c), pos(position) {} - Type type; - QChar chr; - int pos; -}; - -struct CodeFormatterData { virtual ~CodeFormatterData() {} }; - -struct TextBlockUserData : QTextBlockUserData -{ - TextBlockUserData() : m_data(0) {} - virtual ~TextBlockUserData() {} - - void setFoldingStartIncluded(const bool) {} - void setFoldingEndIncluded(const bool) {} - void setFoldingIndent(const int) {} - void setCodeFormatterData(CodeFormatterData *data) { m_data = data; } - CodeFormatterData *codeFormatterData() { return m_data; } - CodeFormatterData *m_data; -}; - -namespace TextDocumentLayout { -TextBlockUserData *userData(const QTextBlock &block); -void setParentheses(const QTextBlock &, const Parentheses &); -} - -} // namespace TextEditor diff --git a/tests/auto/generichighlighter/highlighterengine/tst_highlighterengine.cpp b/tests/auto/generichighlighter/highlighterengine/tst_highlighterengine.cpp deleted file mode 100644 index e671d7b393..0000000000 --- a/tests/auto/generichighlighter/highlighterengine/tst_highlighterengine.cpp +++ /dev/null @@ -1,1105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "formats.h" -#include "highlightermock.h" - -#include <texteditor/generichighlighter/context.h> -#include <texteditor/generichighlighter/highlightdefinition.h> -#include <texteditor/generichighlighter/itemdata.h> -#include <texteditor/generichighlighter/keywordlist.h> -#include <texteditor/generichighlighter/specificrules.h> - -#include <QSharedPointer> -#include <QScopedPointer> -#include <QList> -#include <QMetaType> -#include <QPlainTextEdit> -#include <QtTest> - -using namespace TextEditor; -using namespace Internal; - -Q_DECLARE_METATYPE(HighlightSequence) - -//TESTED_COMPONENT=src/plugins/texteditor/generichighlighter - -class tst_HighlighterEngine : public QObject -{ - Q_OBJECT -public: - tst_HighlighterEngine(); - -private slots: - void initTestCase(); - void init(); - - void testSimpleLine(); - void testSimpleLine_data(); - - void testLineContinue(); - void testLineContinue_data(); - void testEditingLineContinue0(); - void testEditingLineContinue1(); - void testEditingLineContinue2(); - void testEditingLineContinue3(); - void testEditingLineContinue4(); - void testEditingLineContinue5(); - - void testPersistentStates(); - void testPersistentStates_data(); - void testEditingPersistentStates0(); - void testEditingPersistentStates1(); - void testEditingPersistentStates2(); - - void testDynamicContexts(); - void testDynamicContexts_data(); - - void testFirstNonSpace(); - void testFirstNonSpace_data(); - -private: - void createKeywords(); - void createContexts(); - void createItemDatas(); - - void setExpectedData(int state, const HighlightSequence &seq); - void setExpectedData(const QList<int> &states, const QList<HighlightSequence> &seqs); - void createColumns(); - void test(); - void test(int state, const HighlightSequence &seq, const QString &line); - void test(const QList<int> &states, const QList<HighlightSequence> &seqs, const QString &lines); - - void clear(QList<int> *states, QList<HighlightSequence> *sequences) const; - - QList<int> createlDefaultStatesList(int size) const; - - void addCharactersToBegin(QTextBlock block, const QString &s); - void addCharactersToEnd(QTextBlock block, const QString &s); - void removeFirstCharacters(const QTextBlock &block, int n); - void removeLastCharacters(const QTextBlock &block, int n); - - void setupForEditingLineContinue(); - - QSharedPointer<HighlightDefinition> m_definition; - QScopedPointer<HighlighterMock> m_highlighterMock; - QPlainTextEdit m_text; -}; - -tst_HighlighterEngine::tst_HighlighterEngine() : - m_definition(new HighlightDefinition) -{} - -void tst_HighlighterEngine::initTestCase() -{ - /***********************************************************/ - /*** Spaces are ignored when comparing text char formats ***/ - /***********************************************************/ - - createKeywords(); - createContexts(); - createItemDatas(); -} - -void tst_HighlighterEngine::init() -{ - m_highlighterMock.reset(new HighlighterMock()); - m_highlighterMock->setDefaultContext(m_definition->initialContext()); - m_highlighterMock->setDocument(m_text.document()); -} - -void tst_HighlighterEngine::createKeywords() -{ - QSharedPointer<KeywordList> keywords = m_definition->createKeywordList("keywords"); - keywords->addKeyword("int"); - keywords->addKeyword("long"); -} - -void tst_HighlighterEngine::createContexts() -{ - // Normal context - QSharedPointer<Context> normal = m_definition->createContext("Normal", true); - normal->setItemData("Normal Text"); - normal->setLineEndContext("#stay"); - normal->setDefinition(m_definition); - - // AfterHash context - QSharedPointer<Context> afterHash = m_definition->createContext("AfterHash", false); - afterHash->setItemData("Error"); - afterHash->setLineEndContext("#pop"); - afterHash->setDefinition(m_definition); - - // Define context - QSharedPointer<Context> define = m_definition->createContext("Define", false); - define->setItemData("Preprocessor"); - define->setLineEndContext("#pop"); - define->setDefinition(m_definition); - - // Preprocessor context - QSharedPointer<Context> preprocessor = m_definition->createContext("Preprocessor", false); - preprocessor->setItemData("Preprocessor"); - preprocessor->setLineEndContext("#pop"); - preprocessor->setDefinition(m_definition); - - // SimpleComment context - QSharedPointer<Context> simpleComment = m_definition->createContext("SimpleComment", false); - simpleComment->setItemData("Comment"); - simpleComment->setLineEndContext("#pop"); - simpleComment->setDefinition(m_definition); - - // MultilineComment context - QSharedPointer<Context> multiComment = m_definition->createContext("MultilineComment", false); - multiComment->setItemData("Comment"); - multiComment->setLineEndContext("#stay"); - multiComment->setDefinition(m_definition); - - // NestedComment context - QSharedPointer<Context> nestedComment = m_definition->createContext("NestedComment", false); - nestedComment->setItemData("Other Comment"); - nestedComment->setLineEndContext("#stay"); - nestedComment->setDefinition(m_definition); - - // SimpleNestedComment context - QSharedPointer<Context> simpleNestedComment = - m_definition->createContext("SimpleNestedComment", false); - simpleNestedComment->setItemData("Comment"); - simpleNestedComment->setLineEndContext("#pop"); - simpleNestedComment->setDefinition(m_definition); - - // Dummy context - QSharedPointer<Context> dummy = m_definition->createContext("Dummy", false); - dummy->setItemData("Dummy"); - dummy->setLineEndContext("#pop"); - dummy->setDefinition(m_definition); - - // AfterPlus context - QSharedPointer<Context> afterPlus = m_definition->createContext("AfterPlus", false); - afterPlus->setItemData("Char"); - afterPlus->setLineEndContext("#pop"); - afterPlus->setDefinition(m_definition); - - // AfterMinus context - QSharedPointer<Context> afterMinus = m_definition->createContext("AfterMinus", false); - afterMinus->setItemData("String"); - afterMinus->setLineEndContext("#pop#pop"); - afterMinus->setDefinition(m_definition); - - // AfterEqual context - QSharedPointer<Context> afterEqual = m_definition->createContext("AfterEqual", false); - afterEqual->setItemData("Float"); - afterEqual->setLineEndContext("#pop#pop#pop"); - afterEqual->setDefinition(m_definition); - - // Dynamic context - QSharedPointer<Context> dynamic = m_definition->createContext("Dynamic", false); - dynamic->setItemData("Marker"); - dynamic->setLineEndContext("#pop"); - dynamic->setDynamic("true"); - dynamic->setDefinition(m_definition); - - // Rules - DetectCharRule *r = new DetectCharRule; - r->setChar("?"); - r->setContext("#stay"); - r->setItemData("Decimal"); - r->setDefinition(m_definition); - normal->addRule(QSharedPointer<Rule>(r)); // Needs to be the first one added. - - DetectCharRule *r0 = new DetectCharRule; - r0->setChar("#"); - r0->setContext("AfterHash"); - r0->setFirstNonSpace("true"); - r0->setLookAhead("true"); - r0->setDefinition(m_definition); - normal->addRule(QSharedPointer<Rule>(r0)); - - RegExprRule *r1 = new RegExprRule; - r1->setPattern("#\\s*define.*((?=\\\\))"); - r1->setInsensitive("true"); - r1->setContext("Define"); - r1->setItemData("Preprocessor"); - r1->setFirstNonSpace("true"); - r1->setDefinition(m_definition); - afterHash->addRule(QSharedPointer<Rule>(r1)); - - RegExprRule *r2 = new RegExprRule; - r2->setPattern("#\\s*(?:define|undef)"); - r2->setInsensitive("true"); - r2->setContext("Preprocessor"); - r2->setItemData("Preprocessor"); - r2->setFirstNonSpace("true"); - r2->setDefinition(m_definition); - afterHash->addRule(QSharedPointer<Rule>(r2)); - - LineContinueRule *r3 = new LineContinueRule; - r3->setItemData("Preprocessor"); - r3->setContext("#stay"); - r3->setDefinition(m_definition); - define->addRule(QSharedPointer<Rule>(r3)); - - LineContinueRule *r4 = new LineContinueRule; - r4->setItemData("Preprocessor"); - r4->setContext("#stay"); - r4->setDefinition(m_definition); - preprocessor->addRule(QSharedPointer<Rule>(r4)); - - KeywordRule *r5 = new KeywordRule(m_definition); - r5->setList("keywords"); - r5->setItemData("Keyword"); - r5->setContext("#stay"); - r5->setDefinition(m_definition); - normal->addRule(QSharedPointer<Rule>(r5)); - - IntRule *r6 = new IntRule; - r6->setItemData("Decimal"); - r6->setContext("#stay"); - r6->setDefinition(m_definition); - normal->addRule(QSharedPointer<Rule>(r6)); - - StringDetectRule *r7 = new StringDetectRule; - r7->setItemData("Decimal"); - r7->setContext("#stay"); - r7->setString("LL"); - r7->setInsensitive("true"); - r7->setDefinition(m_definition); - r6->addChild(QSharedPointer<Rule>(r7)); - - StringDetectRule *r8 = new StringDetectRule; - r8->setItemData("Decimal"); - r8->setContext("#stay"); - r8->setString("UL"); - r8->setInsensitive("true"); - r8->setDefinition(m_definition); - r6->addChild(QSharedPointer<Rule>(r8)); - - HlCOctRule *r9 = new HlCOctRule; - r9->setItemData("Octal"); - r9->setContext("#stay"); - r9->setDefinition(m_definition); - normal->addRule(QSharedPointer<Rule>(r9)); - - Detect2CharsRule *r10 = new Detect2CharsRule; - r10->setChar("/"); - r10->setChar1("/"); - r10->setItemData("Comment"); - r10->setContext("SimpleComment"); - r10->setDefinition(m_definition); - normal->addRule(QSharedPointer<Rule>(r10)); - - DetectIdentifierRule *r11 = new DetectIdentifierRule; - r11->setDefinition(m_definition); - simpleComment->addRule(QSharedPointer<Rule>(r11)); - - Detect2CharsRule *r12 = new Detect2CharsRule; - r12->setChar("/"); - r12->setChar1("*"); - r12->setItemData("Comment"); - r12->setContext("MultilineComment"); - r12->setDefinition(m_definition); - normal->addRule(QSharedPointer<Rule>(r12)); - - Detect2CharsRule *r13 = new Detect2CharsRule; - r13->setChar("*"); - r13->setChar1("/"); - r13->setItemData("Comment"); - r13->setContext("#pop"); - r13->setDefinition(m_definition); - multiComment->addRule(QSharedPointer<Rule>(r13)); - - Detect2CharsRule *r14 = new Detect2CharsRule; - r14->setChar("/"); - r14->setChar1("#"); - r14->setItemData("Other Comment"); - r14->setContext("NestedComment"); - r14->setDefinition(m_definition); - QSharedPointer<Rule> sr14(r14); - multiComment->addRule(sr14); - dummy->addRule(sr14); - afterEqual->addRule(sr14); - afterMinus->addRule(sr14); - afterPlus->addRule(sr14); - - Detect2CharsRule *r15 = new Detect2CharsRule; - r15->setChar("#"); - r15->setChar1("/"); - r15->setItemData("Other Comment"); - r15->setContext("#pop"); - r15->setDefinition(m_definition); - nestedComment->addRule(QSharedPointer<Rule>(r15)); - - DetectCharRule *r16 = new DetectCharRule; - r16->setChar("@"); - r16->setItemData("Marker"); - r16->setContext("Dummy"); - r16->setDefinition(m_definition); - multiComment->addRule(QSharedPointer<Rule>(r16)); - - StringDetectRule *r17 = new StringDetectRule; - r17->setString("dummy"); - r17->setItemData("Dummy"); - r17->setContext("#stay"); - r17->setDefinition(m_definition); - dummy->addRule(QSharedPointer<Rule>(r17)); - - DetectCharRule *r18 = new DetectCharRule; - r18->setChar("+"); - r18->setContext("AfterPlus"); - r18->setDefinition(m_definition); - QSharedPointer<Rule> sr18(r18); - multiComment->addRule(sr18); - nestedComment->addRule(sr18); - afterMinus->addRule(sr18); - afterEqual->addRule(sr18); - - DetectCharRule *r19 = new DetectCharRule; - r19->setChar("-"); - r19->setContext("AfterMinus"); - r19->setDefinition(m_definition); - QSharedPointer<Rule> sr19(r19); - multiComment->addRule(sr19); - nestedComment->addRule(sr19); - afterPlus->addRule(sr19); - afterEqual->addRule(sr19); - - DetectCharRule *r20 = new DetectCharRule; - r20->setChar("="); - r20->setContext("AfterEqual"); - r20->setDefinition(m_definition); - QSharedPointer<Rule> sr20(r20); - multiComment->addRule(sr20); - nestedComment->addRule(sr20); - afterPlus->addRule(sr20); - afterMinus->addRule(sr20); - - DetectCharRule *r22 = new DetectCharRule; - r22->setChar("$"); - r22->setContext("#stay"); - r22->setDefinition(m_definition); - normal->addRule(QSharedPointer<Rule>(r22)); - - DetectCharRule *r23 = new DetectCharRule; - r23->setChar("?"); - r23->setContext("#stay"); - r23->setItemData("Comment"); - r23->setDefinition(m_definition); - normal->addRule(QSharedPointer<Rule>(r23)); - - RegExprRule *r24 = new RegExprRule; - r24->setInsensitive("true"); - r24->setPattern("---([a-c]*)([d-f]*)"); - r24->setDefinition(m_definition); - r24->setItemData("Dummy"); - r24->setContext("Dynamic"); - normal->addRule(QSharedPointer<Rule>(r24)); - - DetectCharRule *r25 = new DetectCharRule; - r25->setChar("1"); - r25->setItemData("Preprocessor"); - r25->setActive("true"); - r25->setDefinition(m_definition); - dynamic->addRule(QSharedPointer<Rule>(r25)); - - StringDetectRule *r26 = new StringDetectRule; - r26->setString("begin%2end"); - r26->setItemData("Error"); - r26->setActive("true"); - r26->setDefinition(m_definition); - dynamic->addRule(QSharedPointer<Rule>(r26)); - - DetectCharRule *r27 = new DetectCharRule; - r27->setChar("|"); - r27->setItemData("Error"); - r27->setFirstNonSpace("true"); - r27->setDefinition(m_definition); - normal->addRule(QSharedPointer<Rule>(r27)); - - Detect2CharsRule *r28 = new Detect2CharsRule; - r28->setChar("#"); - r28->setChar1("#"); - r28->setItemData("Comment"); - r28->setContext("SimpleNestedComment"); - r28->setDefinition(m_definition); - QSharedPointer<Rule> sr28(r28); - multiComment->addRule(sr28); - nestedComment->addRule(sr28); - - LineContinueRule *r29 = new LineContinueRule; - r29->setItemData("Comment"); - r29->setContext("#stay"); - r29->setDefinition(m_definition); - simpleNestedComment->addRule(QSharedPointer<Rule>(r29)); -} - -void tst_HighlighterEngine::createItemDatas() -{ - QSharedPointer<ItemData> normalText = m_definition->createItemData("Normal Text"); - normalText->setStyle("dsNormal"); - QSharedPointer<ItemData> preprocessor = m_definition->createItemData("Preprocessor"); - preprocessor->setStyle("dsOthers"); - QSharedPointer<ItemData> error = m_definition->createItemData("Error"); - error->setStyle("dsError"); - QSharedPointer<ItemData> keyword = m_definition->createItemData("Keyword"); - keyword->setStyle("dsKeyword"); - QSharedPointer<ItemData> decimal = m_definition->createItemData("Decimal"); - decimal->setStyle("dsDecVal"); - QSharedPointer<ItemData> octal = m_definition->createItemData("Octal"); - octal->setStyle("dsBaseN"); - QSharedPointer<ItemData> comment = m_definition->createItemData("Comment"); - comment->setStyle("dsComment"); - QSharedPointer<ItemData> otherComment = m_definition->createItemData("Other Comment"); - otherComment->setStyle("dsError"); - QSharedPointer<ItemData> marker = m_definition->createItemData("Marker"); - marker->setStyle("dsRegionMarker"); - QSharedPointer<ItemData> dummy = m_definition->createItemData("Dummy"); - dummy->setStyle("dsDataType"); - QSharedPointer<ItemData> charStyle = m_definition->createItemData("Char"); - charStyle->setStyle("dsChar"); - QSharedPointer<ItemData> stringStyle = m_definition->createItemData("String"); - stringStyle->setStyle("dsString"); - QSharedPointer<ItemData> floatStyle = m_definition->createItemData("Float"); - floatStyle->setStyle("dsFloat"); -} - -void tst_HighlighterEngine::setExpectedData(int state, const HighlightSequence &seq) -{ - m_highlighterMock->setExpectedBlockState(state); - m_highlighterMock->setExpectedHighlightSequence(seq); -} - -void tst_HighlighterEngine::setExpectedData(const QList<int> &states, - const QList<HighlightSequence> &seqs) -{ - m_highlighterMock->setExpectedBlockStates(states); - m_highlighterMock->setExpectedHighlightSequences(seqs); -} - -void tst_HighlighterEngine::createColumns() -{ - QTest::addColumn<QList<int> >("states"); - QTest::addColumn<QList<HighlightSequence> >("sequences"); - QTest::addColumn<QString>("lines"); -} - -void tst_HighlighterEngine::test() -{ - QFETCH(QList<int>, states); - QFETCH(QList<HighlightSequence>, sequences); - QFETCH(QString, lines); - - init(); - test(states, sequences, lines); -} - -void tst_HighlighterEngine::test(int state, const HighlightSequence &seq, const QString &line) -{ - setExpectedData(state, seq); - m_text.setPlainText(line); -} - -void tst_HighlighterEngine::test(const QList<int> &states, - const QList<HighlightSequence> &seqs, - const QString &lines) -{ - setExpectedData(states, seqs); - m_text.setPlainText(lines); -} - -void tst_HighlighterEngine::clear(QList<int> *states, QList<HighlightSequence> *sequences) const -{ - states->clear(); - sequences->clear(); -} - -QList<int> tst_HighlighterEngine::createlDefaultStatesList(int size) const -{ - QList<int> states; - for (int i = 0; i < size; ++i) - states.append(0); - return states; -} - -void tst_HighlighterEngine::addCharactersToBegin(QTextBlock block, const QString &s) -{ - QTextCursor cursor = m_text.textCursor(); - cursor.beginEditBlock(); - cursor.setPosition(block.position()); - cursor.insertText(s); - cursor.endEditBlock(); -} - -void tst_HighlighterEngine::addCharactersToEnd(QTextBlock block, const QString &s) -{ - QTextCursor cursor = m_text.textCursor(); - cursor.beginEditBlock(); - cursor.setPosition(block.position() + block.length() - 1); - cursor.insertText(s); - cursor.endEditBlock(); -} - -void tst_HighlighterEngine::removeFirstCharacters(const QTextBlock &block, int n) -{ - QTextCursor cursor = m_text.textCursor(); - cursor.beginEditBlock(); - cursor.setPosition(block.position()); - cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, n); - cursor.removeSelectedText(); - cursor.endEditBlock(); -} - -void tst_HighlighterEngine::removeLastCharacters(const QTextBlock &block, int n) -{ - QTextCursor cursor = m_text.textCursor(); - cursor.beginEditBlock(); - cursor.setPosition(block.position() + block.length() - 1); - cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, n); - cursor.removeSelectedText(); - cursor.endEditBlock(); -} - -void tst_HighlighterEngine::testSimpleLine() -{ - test(); -} - -void tst_HighlighterEngine::testSimpleLine_data() -{ - createColumns(); - - QList<int> states; - QList<HighlightSequence> sequences; - QString text; - - HighlightSequence seqa(0, 3); - HighlightSequence seqb(0, 15, Formats::instance().othersFormat()); - HighlightSequence seqc(0, 1, Formats::instance().errorFormat()); - HighlightSequence seqd(0, 3, Formats::instance().keywordFormat()); - seqd.add(3, 8); - seqd.add(8, 9, Formats::instance().baseNFormat()); - HighlightSequence seqe(0, 4, Formats::instance().keywordFormat()); - seqe.add(4, 9); - seqe.add(9, 12, Formats::instance().decimalFormat()); - HighlightSequence seqf(seqe); - seqf.add(12, 13); - HighlightSequence seqg(seqf); - seqg.add(13, 14); - HighlightSequence seqh(0, 8, Formats::instance().commentFormat()); - HighlightSequence seqi(seqd); - seqi.add(9, 17, Formats::instance().commentFormat()); - HighlightSequence seqj(seqd); - seqj.add(9, 11, Formats::instance().commentFormat()); - HighlightSequence seqk(0, 3); - HighlightSequence seql(0, 3, Formats::instance().keywordFormat()); - HighlightSequence seqm(0, 2); - HighlightSequence seqn(0, 8, Formats::instance().commentFormat()); - HighlightSequence seqo(0, 1); - seqo.add(1, 2, Formats::instance().decimalFormat()); - - states << 0; - sequences << seqa; - text = "abc"; - QTest::newRow("case 0") << states << sequences << text; - - sequences.clear(); - sequences << seqb; - text = "#define max 100"; - QTest::newRow("case 1") << states << sequences << text; - - sequences.clear(); - sequences << seqc; - text = "#"; - QTest::newRow("case 2") << states << sequences << text; - - sequences.clear(); - sequences << seqd; - text = "int i = 0"; - QTest::newRow("case 3") << states << sequences << text; - - sequences.clear(); - sequences << seqe; - text = "long i = 1LL"; - QTest::newRow("case 4") << states << sequences << text; - - text = "long i = 1ul"; - QTest::newRow("case 5") << states << sequences << text; - - sequences.clear(); - sequences << seqf; - text = "long i = 1ULL"; - QTest::newRow("case 6") << states << sequences << text; - - sequences.clear(); - sequences << seqg; - text = "long i = 1LLUL"; - QTest::newRow("case 7") << states << sequences << text; - - text = "long i = 1ULLL"; - QTest::newRow("case 8") << states << sequences << text; - - sequences.clear(); - sequences << seqh; - text = "//int i;"; - QTest::newRow("case 9") << states << sequences << text; - - sequences.clear(); - sequences << seqi; - text = "int i = 0//int i;"; - QTest::newRow("case 10") << states << sequences << text; - - sequences.clear(); - sequences << seqj; - text = "int i = 0//"; - QTest::newRow("case 11") << states << sequences << text; - - sequences.clear(); - sequences << seqk << seqk; - text = "bla\nbla"; - QTest::newRow("case 12") << createlDefaultStatesList(2) << sequences << text; - - sequences.clear(); - sequences << seql << seqm; - text = "int\ni;"; - QTest::newRow("case 13") << createlDefaultStatesList(2) << sequences << text; - - sequences.clear(); - sequences << seqn << seqm; - text = "//int i;\ni;"; - QTest::newRow("case 14") << createlDefaultStatesList(2) << sequences << text; - - // Even when a matching rule does not take to another context, iteration over the rules - // should start over from the first rule in the current context. - sequences.clear(); - sequences << seqo; - text = "$?"; - QTest::newRow("case 15") << createlDefaultStatesList(2) << sequences << text; -} - -void tst_HighlighterEngine::testLineContinue() -{ - test(); -} - -void tst_HighlighterEngine::testLineContinue_data() -{ - createColumns(); - - QList<int> states; - QList<HighlightSequence> sequences; - QString lines; - - HighlightSequence seqa(0, 12, Formats::instance().othersFormat()); - HighlightSequence seqb(0, 7, Formats::instance().othersFormat()); - HighlightSequence seqc(0, 8, Formats::instance().othersFormat()); - HighlightSequence seqd(0, 3, Formats::instance().othersFormat()); - HighlightSequence seqe(0, 3, Formats::instance().keywordFormat()); - seqe.add(3, 8); - seqe.add(8, 9, Formats::instance().baseNFormat()); - seqe.add(9, 10); - HighlightSequence seqf(0, 9, Formats::instance().commentFormat()); - seqf.add(9, 18, Formats::instance().errorFormat()); - HighlightSequence seqg(0, 7, Formats::instance().commentFormat()); - HighlightSequence seqh(0, 5, Formats::instance().commentFormat()); - HighlightSequence seqi(0, 5, Formats::instance().errorFormat()); - seqi.add(5, 8, Formats::instance().commentFormat()); - - states << 1 << 2; - sequences << seqa << seqb; - lines = "#define max\\\n 100"; - QTest::newRow("case 0") << states << sequences << lines; - - clear(&states, &sequences); - states << 1 << 1; - sequences << seqa << seqc; - lines = "#define max\\\n 100\\"; - QTest::newRow("case 1") << states << sequences << lines; - - clear(&states, &sequences); - states << 1 << 1 << 2; - sequences << seqa << seqc << seqd; - lines = "#define max\\\n 100\\\n000"; - QTest::newRow("case 2") << states << sequences << lines; - - clear(&states, &sequences); - states << 1 << 1 << 2 << 0; - sequences << seqa << seqc << seqd << seqe; - lines = "#define max\\\n 100\\\n000\nint i = 0;"; - QTest::newRow("case 3") << states << sequences << lines; - - clear(&states, &sequences); - states << 4 << 1 << 1 << 2 << 3 << 0 << 1; - sequences << seqf << seqg << seqh << seqh << seqi << seqh; - lines = "/*int i; /# int j;\n##foo \\\nbar \\\nbaz \nxxx#/yyy\nzzz*/"; - QTest::newRow("case 4") << states << sequences << lines; -} - -void tst_HighlighterEngine::setupForEditingLineContinue() -{ - init(); - m_highlighterMock->startNoTestCalls(); - m_text.setPlainText("#define max\\\n xxx\\\nzzz"); - m_highlighterMock->endNoTestCalls(); -} - -void tst_HighlighterEngine::testEditingLineContinue0() -{ - setupForEditingLineContinue(); - - QList<HighlightSequence> sequences; - HighlightSequence seqa(0, 11, Formats::instance().othersFormat()); - HighlightSequence seqb(0, 8); - HighlightSequence seqc(0, 3); - sequences << seqa << seqb << seqc; - setExpectedData(createlDefaultStatesList(3), sequences); - - removeLastCharacters(m_text.document()->firstBlock(), 1); -} - -void tst_HighlighterEngine::testEditingLineContinue1() -{ - setupForEditingLineContinue(); - - setExpectedData(1, HighlightSequence(0, 6, Formats::instance().othersFormat())); - - // In this case highlighting should be triggered only for the modified line. - removeFirstCharacters(m_text.document()->firstBlock().next(), 2); -} - -void tst_HighlighterEngine::testEditingLineContinue2() -{ - setupForEditingLineContinue(); - - QList<HighlightSequence> sequences; - HighlightSequence seqa(0, 17, Formats::instance().othersFormat()); - HighlightSequence seqb(0, 8); - HighlightSequence seqc(0, 3); - sequences << seqa << seqb << seqc; - setExpectedData(createlDefaultStatesList(3), sequences); - - addCharactersToEnd(m_text.document()->firstBlock(), "ixum"); -} - -void tst_HighlighterEngine::testEditingLineContinue3() -{ - setupForEditingLineContinue(); - - setExpectedData(1, HighlightSequence(0, 12, Formats::instance().othersFormat())); - - // In this case highlighting should be triggered only for the modified line. - addCharactersToBegin(m_text.document()->firstBlock().next(), "ixum"); -} - -void tst_HighlighterEngine::testEditingLineContinue4() -{ - setupForEditingLineContinue(); - - QList<int> states; - states << 2 << 0 << 0; - QList<HighlightSequence> sequences; - HighlightSequence seqa(0, 0); - HighlightSequence seqb(0, 8); - HighlightSequence seqc(0, 3); - sequences << seqa << seqb << seqc; - setExpectedData(states, sequences); - - m_highlighterMock->considerEmptyLines(); - addCharactersToBegin(m_text.document()->firstBlock().next(), "\n"); -} - -void tst_HighlighterEngine::testEditingLineContinue5() -{ - setupForEditingLineContinue(); - - QList<int> states; - states << 2 << 0; - QList<HighlightSequence> sequences; - HighlightSequence seqa(0, 9, Formats::instance().othersFormat()); - HighlightSequence seqb(0, 3); - sequences << seqa << seqb; - setExpectedData(states, sequences); - - addCharactersToEnd(m_text.document()->firstBlock().next(), "x"); -} - -void tst_HighlighterEngine::testPersistentStates() -{ - test(); -} - -void tst_HighlighterEngine::testPersistentStates_data() -{ - createColumns(); - - QList<int> states; - QList<HighlightSequence> sequences; - QString text; - - HighlightSequence seqa(0, 3, Formats::instance().keywordFormat()); - seqa.add(3, 6); - seqa.add(6, 15, Formats::instance().commentFormat()); - seqa.add(15, 16); - HighlightSequence seqb(0, 8, Formats::instance().commentFormat()); - HighlightSequence seqc(0, 2, Formats::instance().commentFormat()); - HighlightSequence seqd(0, 9, Formats::instance().commentFormat()); - seqd.add(9, 18, Formats::instance().errorFormat()); - HighlightSequence seqe(0, 5, Formats::instance().errorFormat()); - seqe.add(5, 8, Formats::instance().commentFormat()); - HighlightSequence seqf(0, 2, Formats::instance().commentFormat()); - seqf.add(2, 6); - HighlightSequence seqg(0, 1); - seqg.add(1, 7, Formats::instance().commentFormat()); - seqg.add(7, 8, Formats::instance().regionMarketFormat()); - seqg.add(8, 15, Formats::instance().errorFormat()); - seqg.add(15, 16, Formats::instance().regionMarketFormat()); - seqg.add(16, 21, Formats::instance().dataTypeFormat()); - seqg.add(21, 22, Formats::instance().regionMarketFormat()); - HighlightSequence seqh(seqc); - seqh.add(2, 3); - HighlightSequence seqi(seqc); - seqi.add(2, 3, Formats::instance().charFormat()); - seqi.add(3, 4, Formats::instance().stringFormat()); - HighlightSequence seqj(seqc); - seqj.add(2, 3, Formats::instance().charFormat()); - seqj.add(3, 4, Formats::instance().floatFormat()); - HighlightSequence seqk(seqc); - seqk.add(2, 3, Formats::instance().charFormat()); - seqk.add(3, 5, Formats::instance().errorFormat()); - seqk.add(5, 6, Formats::instance().floatFormat()); - HighlightSequence seql(seqk); - seql.add(6, 7, Formats::instance().stringFormat()); - - states << 0; - sequences << seqa; - text = "int i /* 000 */;"; - QTest::newRow("case 0") << states << sequences << text; - - clear(&states, &sequences); - states << 3 << 3; - sequences << seqb << seqc; - text = "/*int i;\ni;"; - QTest::newRow("case 1") << states << sequences << text; - - clear(&states, &sequences); - states << 3 << 3 << 3; - sequences << seqb << seqc << seqb; - text = "/*int i;\ni;\nint abc;"; - QTest::newRow("case 2") << states << sequences << text; - - clear(&states, &sequences); - states << 3 << 3 << 0; - sequences << seqb << seqc << seqc; - text = "/*int i;\ni;\n*/"; - QTest::newRow("case 3") << states << sequences << text; - - clear(&states, &sequences); - states << 4 << 3 << 0; - sequences << seqd << seqe << seqf; - text = "/*int i; /# int j;\nfoo#/bar\n*/f();"; - QTest::newRow("case 4") << states << sequences << text; - - clear(&states, &sequences); - states << 3; - sequences << seqg; - text = "i/*bla @/#foo#/ dummy "; - QTest::newRow("case 5") << states << sequences << text; - - clear(&states, &sequences); - states << 3 << 3; - sequences << seqg << seqc; - text = "i/*bla @/#foo#/ dummy \ni;"; - QTest::newRow("case 6") << states << sequences << text; - - clear(&states, &sequences); - states << 3 << 3 << 0; - sequences << seqg << seqc << seqc; - text = "i/*bla @/#foo#/ dummy \ni;\n*/"; - QTest::newRow("case 7") << states << sequences << text; - - clear(&states, &sequences); - states << 3 << 3 << 0; - sequences << seqg << seqc << seqh; - text = "i/*bla @/#foo#/ dummy \ni;\n*/a"; - QTest::newRow("case 8") << states << sequences << text; - - clear(&states, &sequences); - states << 3; - sequences << seqi; - text = "/*+-"; - QTest::newRow("case 9") << states << sequences << text; - - clear(&states, &sequences); - states << 0; - sequences << seqj; - text = "/*+="; - QTest::newRow("case 10") << states << sequences << text; - - clear(&states, &sequences); - states << 3; - sequences << seqk; - text = "/*+/#="; - QTest::newRow("case 11") << states << sequences << text; - - clear(&states, &sequences); - states << 4; - sequences << seql; - text = "/*+/#=-"; - QTest::newRow("case 12") << states << sequences << text; -} - -void tst_HighlighterEngine::testEditingPersistentStates0() -{ - m_highlighterMock->startNoTestCalls(); - m_text.setPlainText("a b c /\ninside\n*/\na b c"); - m_highlighterMock->endNoTestCalls(); - - QList<int> states; - states << 3 << 3 << 0 << 0; - QList<HighlightSequence> sequences; - HighlightSequence seqa(0, 6); - seqa.add(6, 8, Formats::instance().commentFormat()); - HighlightSequence seqb(0, 6, Formats::instance().commentFormat()); - HighlightSequence seqc(0, 2, Formats::instance().commentFormat()); - HighlightSequence seqd(0, 5); - sequences << seqa << seqb << seqc << seqd; - setExpectedData(states, sequences); - - addCharactersToEnd(m_text.document()->firstBlock(), "*"); -} - -void tst_HighlighterEngine::testEditingPersistentStates1() -{ - m_highlighterMock->startNoTestCalls(); - m_text.setPlainText("/*abc\n/\nnesting\nnesting\n#/\n*/xyz"); - m_highlighterMock->endNoTestCalls(); - - QList<int> states; - states << 4 << 4 << 4 << 3 << 0; - QList<HighlightSequence> sequences; - HighlightSequence seqa(0, 2, Formats::instance().errorFormat()); - HighlightSequence seqb(0, 7, Formats::instance().errorFormat()); - HighlightSequence seqc(seqb); - HighlightSequence seqd(0, 2, Formats::instance().errorFormat()); - HighlightSequence seqe(0, 2, Formats::instance().commentFormat()); - seqe.add(2, 5); - sequences << seqa << seqb << seqc << seqd << seqe; - setExpectedData(states, sequences); - - addCharactersToEnd(m_text.document()->firstBlock().next(), "#"); -} - -void tst_HighlighterEngine::testEditingPersistentStates2() -{ - m_highlighterMock->startNoTestCalls(); - m_text.setPlainText("/*abc\n/\nnesting\nnesting\n*/\n#/xyz"); - m_highlighterMock->endNoTestCalls(); - - QList<int> states; - states << 4 << 4 << 4 << 4 << 3; - QList<HighlightSequence> sequences; - HighlightSequence seqa(0, 2, Formats::instance().errorFormat()); - HighlightSequence seqb(0, 7, Formats::instance().errorFormat()); - HighlightSequence seqc(seqb); - HighlightSequence seqd(0, 2, Formats::instance().errorFormat()); - HighlightSequence seqe(seqd); - seqe.add(2, 5, Formats::instance().commentFormat()); - sequences << seqa << seqb << seqc << seqd << seqe; - setExpectedData(states, sequences); - - addCharactersToEnd(m_text.document()->firstBlock().next(), "#"); -} - -void tst_HighlighterEngine::testDynamicContexts() -{ - test(); -} - -void tst_HighlighterEngine::testDynamicContexts_data() -{ - createColumns(); - - QList<int> states; - QList<HighlightSequence> sequences; - QString text; - - HighlightSequence seqa(0, 2); - seqa.add(2, 15, Formats::instance().dataTypeFormat()); - seqa.add(15, 16, Formats::instance().othersFormat()); - seqa.add(16, 17, Formats::instance().regionMarketFormat()); - HighlightSequence seqb(seqa); - seqb.add(17, 31, Formats::instance().errorFormat()); - - states << 0; - sequences << seqa; - text = "a ---abcddeeff a "; - QTest::newRow("case 0") << states << sequences << text; - - sequences.clear(); - sequences << seqb; - text = "a ---abcddeeff a beginddeeffend"; - QTest::newRow("case 1") << states << sequences << text; -} - -void tst_HighlighterEngine::testFirstNonSpace() -{ - test(); -} - -void tst_HighlighterEngine::testFirstNonSpace_data() -{ - createColumns(); - - QList<int> states; - QList<HighlightSequence> sequences; - QString text; - - HighlightSequence seqa(0, 1, Formats::instance().errorFormat()); - HighlightSequence seqb(0, 3); - seqb.add(3, 4, Formats::instance().errorFormat()); - HighlightSequence seqc(0, 1); - seqc.add(1, 2, Formats::instance().errorFormat()); - HighlightSequence seqd(0, 2); - - states << 0; - sequences << seqa; - text = "|"; - QTest::newRow("case 0") << states << sequences << text; - - sequences.clear(); - sequences << seqb; - text = " |"; - QTest::newRow("case 1") << states << sequences << text; - - sequences.clear(); - sequences << seqc; - text = "\t|"; - QTest::newRow("case 2") << states << sequences << text; - - sequences.clear(); - sequences << seqd; - text = "a|"; - QTest::newRow("case 3") << states << sequences << text; -} - -QTEST_MAIN(tst_HighlighterEngine) -#include "tst_highlighterengine.moc" - diff --git a/tests/auto/generichighlighter/specificrules/specificrules.pro b/tests/auto/generichighlighter/specificrules/specificrules.pro deleted file mode 100644 index 6c15e34bc9..0000000000 --- a/tests/auto/generichighlighter/specificrules/specificrules.pro +++ /dev/null @@ -1,14 +0,0 @@ -include(../../qttest.pri) - -PLUGINSDIR = $$IDE_SOURCE_TREE/src/plugins -GENERICHIGHLIGHTERDIR = $$PLUGINSDIR/texteditor/generichighlighter - -SOURCES += tst_specificrules.cpp \ - $$GENERICHIGHLIGHTERDIR/context.cpp \ - $$GENERICHIGHLIGHTERDIR/dynamicrule.cpp \ - $$GENERICHIGHLIGHTERDIR/rule.cpp \ - $$GENERICHIGHLIGHTERDIR/specificrules.cpp \ - $$GENERICHIGHLIGHTERDIR/progressdata.cpp \ - $$GENERICHIGHLIGHTERDIR/highlightdefinition.cpp \ - $$GENERICHIGHLIGHTERDIR/keywordlist.cpp \ - $$GENERICHIGHLIGHTERDIR/itemdata.cpp diff --git a/tests/auto/generichighlighter/specificrules/specificrules.qbs b/tests/auto/generichighlighter/specificrules/specificrules.qbs deleted file mode 100644 index 9548bf0668..0000000000 --- a/tests/auto/generichighlighter/specificrules/specificrules.qbs +++ /dev/null @@ -1,26 +0,0 @@ -import qbs - -QtcAutotest { - name: "Generic highlighter specific rules autotest" - Depends { name: "Qt.widgets" } - Group { - name: "Sources from TextEditor plugin" - prefix: project.genericHighlighterDir + '/' - files: [ - "context.cpp", - "dynamicrule.cpp", - "highlightdefinition.cpp", - "itemdata.cpp", - "keywordlist.cpp", - "progressdata.cpp", - "rule.cpp", - "specificrules.cpp", - ] - } - Group { - name: "Test sources" - files: "tst_specificrules.cpp" - } - - cpp.includePaths: base.concat([project.genericHighlighterDir + "/../.."]) -} diff --git a/tests/auto/generichighlighter/specificrules/tst_specificrules.cpp b/tests/auto/generichighlighter/specificrules/tst_specificrules.cpp deleted file mode 100644 index 30cd9d552a..0000000000 --- a/tests/auto/generichighlighter/specificrules/tst_specificrules.cpp +++ /dev/null @@ -1,781 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 <texteditor/generichighlighter/highlightdefinition.h> -#include <texteditor/generichighlighter/keywordlist.h> -#include <texteditor/generichighlighter/specificrules.h> -#include <texteditor/generichighlighter/progressdata.h> - -#include <QtTest> - -//TESTED_COMPONENT=src/plugins/texteditor/generichighlighter -using namespace TextEditor; -using namespace Internal; - -class tst_SpecificRules : public QObject -{ - Q_OBJECT -public: - tst_SpecificRules() : m_definition(new HighlightDefinition) {} - -private slots: - void initTestCase(); - - void testDetectChar(); - void testDetectChar_data(); - - void testDetect2Char(); - void testDetect2Char_data(); - - void testAnyChar(); - void testAnyChar_data(); - - void testStringDetect(); - void testStringDetect_data(); - - void testRegExpr(); - void testRegExpr_data(); - void testRegExprOffsetIncremented(); - void testRegExprOffsetIncremented_data(); - - void testKeywordGlobalSensitiveLocalSensitive(); - void testKeywordGlobalSensitiveLocalSensitive_data(); - void testKeywordGlobalSensitiveLocalInsensitive(); - void testKeywordGlobalSensitiveLocalInsensitive_data(); - void testKeywordGlobalInsensitiveLocalInsensitive(); - void testKeywordGlobalInsensitiveLocalInsensitive_data(); - void testKeywordGlobalInsensitiveLocalSensitive(); - void testKeywordGlobalInsensitiveLocalSensitive_data(); - - void testInt(); - void testInt_data(); - - void testFloat(); - void testFloat_data(); - - void testCOctal(); - void testCOctal_data(); - - void testCHex(); - void testCHex_data(); - - void testCString(); - void testCString_data(); - - void testCChar(); - void testCChar_data(); - - void testRangeDetect(); - void testRangeDetect_data(); - - void testLineContinue(); - void testLineContinue_data(); - - void testDetectSpaces(); - void testDetectSpaces_data(); - - void testDetectIdentifier(); - void testDetectIdentifier_data(); - -private: - void addCommonColumns() const; - void testMatch(Rule *rule); - void testMatch(Rule *rule, ProgressData *progress); - - void noMatchForInt() const; - void noMatchForFloat() const; - void noMatchForCOctal() const; - void noMatchForCHex() const; - void noMatchForNumber() const; - - void commonCasesForKeywords() const; - - QSharedPointer<HighlightDefinition> m_definition; -}; - -void tst_SpecificRules::initTestCase() -{ - QSharedPointer<KeywordList> list = m_definition->createKeywordList("keywords"); - list->addKeyword("for"); - list->addKeyword("while"); - list->addKeyword("BEGIN"); - list->addKeyword("END"); - list->addKeyword("WeIrD"); -} - -void tst_SpecificRules::addCommonColumns() const -{ - QTest::addColumn<QString>("s"); - QTest::addColumn<bool>("match"); - QTest::addColumn<int>("offset"); - QTest::addColumn<bool>("only spaces"); - QTest::addColumn<bool>("will continue"); -} - -void tst_SpecificRules::testMatch(Rule *rule) -{ - ProgressData progress; - testMatch(rule, &progress); -} - -void tst_SpecificRules::testMatch(Rule *rule, ProgressData *progress) -{ - QFETCH(QString, s); - - QTEST(rule->matchSucceed(s, s.length(), progress), "match"); - QTEST(progress->offset(), "offset"); - QTEST(progress->isOnlySpacesSoFar(), "only spaces"); - QTEST(progress->isWillContinueLine(), "will continue"); -} - -void tst_SpecificRules::testDetectChar() -{ - QFETCH(QString, c); - DetectCharRule rule; - rule.setChar(c); - - testMatch(&rule); -} - -void tst_SpecificRules::testDetectChar_data() -{ - QTest::addColumn<QString>("c"); - addCommonColumns(); - - QTest::newRow("[#] against [#]") << "#" << "#" << true << 1 << false << false; - QTest::newRow("[#] against [##]") << "#" << "##" << true << 1 << false << false; - QTest::newRow("[#] against [ ]") << "#" << " " << false << 0 << true << false; - QTest::newRow("[#] against [a]") << "#" << "a" << false << 0 << true << false; - QTest::newRow("[#] against [abc]") << "#" << "abc" << false << 0 << true << false; - QTest::newRow("[#] against [x#]") << "#" << "x#" << false << 0 << true << false; - QTest::newRow("[ ] against [a]") << " " << "a" << false << 0 << true << false; - //QTest::newRow("[ ] against [ ]") << " " << " " << true << 1 << true << false; -} - -void tst_SpecificRules::testDetect2Char() -{ - QFETCH(QString, c); - QFETCH(QString, c1); - Detect2CharsRule rule; - rule.setChar(c); - rule.setChar1(c1); - - testMatch(&rule); -} - -void tst_SpecificRules::testDetect2Char_data() -{ - QTest::addColumn<QString>("c"); - QTest::addColumn<QString>("c1"); - addCommonColumns(); - - QTest::newRow("[//] against [//]") << "/" << "/" << "//" << true << 2 << false << false; - QTest::newRow("[//] against [///]") << "/" << "/" << "///" << true << 2 << false << false; - QTest::newRow("[//] against [// ]") << "/" << "/" << "// " << true << 2 << false << false; - QTest::newRow("[//] against [ //]") << "/" << "/" << " //" << false << 0 << true << false; - QTest::newRow("[//] against [a]") << "/" << "/" << "a" << false << 0 << true << false; - QTest::newRow("[//] against [ a]") << "/" << "/" << " a" << false << 0 << true << false; - QTest::newRow("[//] against [abc]") << "/" << "/" << "abc" << false << 0 << true << false; - QTest::newRow("[//] against [/a]") << "/" << "/" << "/a" << false << 0 << true << false; - QTest::newRow("[//] against [a/]") << "/" << "/" << "a/" << false << 0 << true << false; - QTest::newRow("[ ] against [xx]") << " " << " " << "xx" << false << 0 << true << false; - //QTest::newRow("[ ] against [ ]") << " " << " " << " " << true << 3 << true << false; -} - -void tst_SpecificRules::testAnyChar() -{ - QFETCH(QString, chars); - AnyCharRule rule; - rule.setCharacterSet(chars); - - testMatch(&rule); -} - -void tst_SpecificRules::testAnyChar_data() -{ - QTest::addColumn<QString>("chars"); - addCommonColumns(); - - QTest::newRow("[:!<>?] against [:]") << ":!<>?" << ":" << true << 1 << false << false; - QTest::newRow("[:!<>?] against [!]") << ":!<>?" << "!" << true << 1 << false << false; - QTest::newRow("[:!<>?] against [<]") << ":!<>?" << "<" << true << 1 << false << false; - QTest::newRow("[:!<>?] against [>]") << ":!<>?" << ">" << true << 1 << false << false; - QTest::newRow("[:!<>?] against [?]") << ":!<>?" << "?" << true << 1 << false << false; - QTest::newRow("[:!<>?] against [:]") << ":!<>?" << ":" << true << 1 << false << false; - QTest::newRow("[:!<>?] against [ ]") << ":!<>?" << " " << false << 0 << true << false; - QTest::newRow("[:!<>?] against [#]") << ":!<>?" << "#" << false << 0 << true << false; - QTest::newRow("[:!<>?] against [!#]") << ":!<>?" << "!#" << true << 1 << false << false; - QTest::newRow("[:!<>?] against [#!]") << ":!<>?" << "#!" << false << 0 << true << false; - QTest::newRow("[:] against [:]") << ":" << ":" << true << 1 << false << false; - QTest::newRow("[:] against [#]") << ":" << "#" << false << 0 << true << false; - //QTest::newRow("[ ] against [ ]") << " " << " " << true << 1 << true << false; -} - -void tst_SpecificRules::testStringDetect() -{ - QFETCH(QString, referenceString); - QFETCH(QString, insensitive); - StringDetectRule rule; - rule.setString(referenceString); - rule.setInsensitive(insensitive); - - testMatch(&rule); -} - -void tst_SpecificRules::testStringDetect_data() -{ - QTest::addColumn<QString>("referenceString"); - QTest::addColumn<QString>("insensitive"); - addCommonColumns(); - - QTest::newRow("[LL] against [LL]") << "LL" << "0" << "LL" << true << 2 << false << false; - QTest::newRow("[LL] against [ll]") << "LL" << "0" << "ll" << false << 0 << true << false; - QTest::newRow("[LL] against [ll] i") << "LL" << "1" << "ll" << true << 2 << false << false; - QTest::newRow("[ll] against [ll] i") << "LL" << "1" << "LL" << true << 2 << false << false; - QTest::newRow("[LL] against [5LL]") << "LL" << "0" << "5LL" << false << 0 << true << false; - QTest::newRow("[LL] against [L]") << "LL" << "0" << "L" << false << 0 << true << false; - QTest::newRow("[LL] against [LLL]") << "LL" << "0" << "LLL" << true << 2 << false << false; - QTest::newRow("[LL] against [ ]") << "LL" << "0" << " " << false << 0 << true << false; - QTest::newRow("[LL] against [xLLx]") << "LL" << "0" << "xLLx" << false << 0 << true << false; - QTest::newRow("[\"\"\"] against [\"\"\"]") << "\"\"\"" << "0" << "\"\"\"" << true << 3 - << false << false; -} - -void tst_SpecificRules::testRegExpr() -{ - QFETCH(QString, pattern); - QFETCH(QString, insensitive); - QFETCH(QString, minimal); - RegExprRule rule; - rule.setPattern(pattern); - rule.setInsensitive(insensitive); - rule.setMinimal(minimal); - - testMatch(&rule); -} - -void tst_SpecificRules::testRegExpr_data() -{ - QTest::addColumn<QString>("pattern"); - QTest::addColumn<QString>("insensitive"); - QTest::addColumn<QString>("minimal"); - addCommonColumns(); - - QTest::newRow("[#[a-z]+\\s+\\d] against [#as 9]") << "#[a-z]+\\s+\\d" << "0" << "0" - << "#as 9" << true << 5 << false << false; - QTest::newRow("[#[a-z]+\\s+\\d] against [#As 9]") << "#[a-z]+\\s+\\d" << "0" << "0" - << "#As 9" << false << 0 << true << false; - QTest::newRow("[#[a-z]+\\s+\\d] against [#As 9] i") << "#[a-z]+\\s+\\d" << "1" << "0" - << "#As 9" << true << 5 << false << false; - QTest::newRow("[#[a-z]+\\s+\\d] against [as 9]") << "#[a-z]+\\s+\\d" << "0" << "0" - << "as 9" << false << 0 << true << false; - QTest::newRow("[#[a-z]+\\s+\\d] against [w#as 9]") << "#[a-z]+\\s+\\d" << "0" << "0" - << "w#as 9" << false << 0 << true << false; - QTest::newRow("[^\\s+[a-z]] against [x]") << "^\\s+[a-z]" << "0" << "0" - << "x" << false << 0 << true << false; - QTest::newRow("[^\\s+[a-z]] against [ x]") << "^\\s+[a-z]" << "0" << "0" - << " x" << true << 3 << false << false; - QTest::newRow("[0+] against [1001]") << "0+" << "0" << "0" - << "1001" << false << 0 << true << false; - QTest::newRow("[0+] against [001]") << "0+" << "0" << "0" - << "001" << true << 2 << false << false; - QTest::newRow("[0+] against [001]") << "0+" << "0" << "1" - << "001" << true << 1 << false << false; - QTest::newRow("[\\s*] against []") << "\\s*" << "0" << "0" - << "" << false << 0 << true << false; - //QTest::newRow("[\\s*] against []") << "\\s*" << "0" << "0" - // << " " << true << 1 << true << false; -} - -void tst_SpecificRules::testRegExprOffsetIncremented() -{ - QFETCH(QString, pattern); - RegExprRule rule; - rule.setPattern(pattern); - - ProgressData progress; - progress.setOffset(1); - - testMatch(&rule, &progress); -} - -void tst_SpecificRules::testRegExprOffsetIncremented_data() -{ - QTest::addColumn<QString>("pattern"); - addCommonColumns(); - - // To make sure that QRegExp::CaretAtZero is set. - QTest::newRow("[^\\s+[a-z]] against [ x]") << "^\\s+[a-z]" << " x" << false << 1 - << true << false; -} - -void tst_SpecificRules::commonCasesForKeywords() const -{ - QTest::newRow("[for]") << "for" << true << 3 << false << false; - QTest::newRow("[while]") << "while" << true << 5 << false << false; - QTest::newRow("[BEGIN]") << "BEGIN" << true << 5 << false << false; - QTest::newRow("[END]") << "END" << true << 3 << false << false; - QTest::newRow("[WeIrD]") << "WeIrD" << true << 5 << false << false; - QTest::newRow("[forr]") << "forr" << false << 0 << true << false; - QTest::newRow("[for#]") << "for#" << false << 0 << true << false; - QTest::newRow("[abc]") << "abc" << false << 0 << true << false; - QTest::newRow("[ ]") << " " << false << 0 << true << false; - QTest::newRow("[foe]") << "foe" << false << 0 << true << false; - QTest::newRow("[sor]") << "sor" << false << 0 << true << false; - QTest::newRow("[ffor]") << "ffor" << false << 0 << true << false; - - // Valid default delimiters. - QTest::newRow("[for ]") << "for " << true << 3 << false << false; - QTest::newRow("[for.for]") << "for.for" << true << 3 << false << false; - QTest::newRow("[for(]") << "for(" << true << 3 << false << false; - QTest::newRow("[for)]") << "for)" << true << 3 << false << false; - QTest::newRow("[for:]") << "for:" << true << 3 << false << false; - QTest::newRow("[for!]") << "for!" << true << 3 << false << false; - QTest::newRow("[for+]") << "for+" << true << 3 << false << false; - QTest::newRow("[for,]") << "for," << true << 3 << false << false; - QTest::newRow("[for-]") << "for-" << true << 3 << false << false; - QTest::newRow("[for<]") << "for>" << true << 3 << false << false; - QTest::newRow("[for=]") << "for=" << true << 3 << false << false; - QTest::newRow("[for>]") << "for>" << true << 3 << false << false; - QTest::newRow("[for%]") << "for%" << true << 3 << false << false; - QTest::newRow("[for&]") << "for&" << true << 3 << false << false; - QTest::newRow("[for/]") << "for/" << true << 3 << false << false; - QTest::newRow("[for;]") << "for;" << true << 3 << false << false; - QTest::newRow("[for?]") << "for?" << true << 3 << false << false; - QTest::newRow("[for[]") << "for[" << true << 3 << false << false; - QTest::newRow("[for]]") << "for]" << true << 3 << false << false; - QTest::newRow("[for^]") << "for^" << true << 3 << false << false; - QTest::newRow("[for{]") << "for{" << true << 3 << false << false; - QTest::newRow("[for|]") << "for|" << true << 3 << false << false; - QTest::newRow("[for}]") << "for}" << true << 3 << false << false; - QTest::newRow("[for~]") << "for~" << true << 3 << false << false; - QTest::newRow("[for\\]") << "for\\" << true << 3 << false << false; - QTest::newRow("[for*]") << "for*" << true << 3 << false << false; - QTest::newRow("[for,for]") << "for,for" << true << 3 << false << false; - QTest::newRow("[for\t]") << "for\t" << true << 3 << false << false; -} - -void tst_SpecificRules::testKeywordGlobalSensitiveLocalSensitive() -{ - m_definition->setKeywordsSensitive("true"); - KeywordRule rule(m_definition); - rule.setInsensitive("false"); - rule.setList("keywords"); - - testMatch(&rule); -} - -void tst_SpecificRules::testKeywordGlobalSensitiveLocalSensitive_data() -{ - addCommonColumns(); - - commonCasesForKeywords(); - QTest::newRow("[fOr]") << "fOr" << false << 0 << true << false; - QTest::newRow("[whilE") << "whilE" << false << 0 << true << false; - QTest::newRow("[bEGIN]") << "bEGIN" << false << 0 << true << false; - QTest::newRow("[end]") << "end" << false << 0 << true << false; - QTest::newRow("[weird]") << "weird" << false << 0 << true << false; -} - -void tst_SpecificRules::testKeywordGlobalSensitiveLocalInsensitive() -{ - m_definition->setKeywordsSensitive("true"); - KeywordRule rule(m_definition); - rule.setInsensitive("true"); - rule.setList("keywords"); - - testMatch(&rule); -} - -void tst_SpecificRules::testKeywordGlobalSensitiveLocalInsensitive_data() -{ - addCommonColumns(); - - commonCasesForKeywords(); - QTest::newRow("[fOr]") << "fOr" << true << 3 << false << false; - QTest::newRow("[whilE") << "whilE" << true << 5 << false << false; - QTest::newRow("[bEGIN]") << "bEGIN" << true << 5 << false << false; - QTest::newRow("[end]") << "end" << true << 3 << false << false; - QTest::newRow("[weird]") << "weird" << true << 5 << false << false; -} - -void tst_SpecificRules::testKeywordGlobalInsensitiveLocalInsensitive() -{ - m_definition->setKeywordsSensitive("false"); - KeywordRule rule(m_definition); - rule.setInsensitive("true"); - rule.setList("keywords"); - - testMatch(&rule); -} - -void tst_SpecificRules::testKeywordGlobalInsensitiveLocalInsensitive_data() -{ - testKeywordGlobalSensitiveLocalInsensitive_data(); -} - -void tst_SpecificRules::testKeywordGlobalInsensitiveLocalSensitive() -{ - m_definition->setKeywordsSensitive("false"); - KeywordRule rule(m_definition); - rule.setInsensitive("false"); - rule.setList("keywords"); - - testMatch(&rule); -} - -void tst_SpecificRules::testKeywordGlobalInsensitiveLocalSensitive_data() -{ - testKeywordGlobalSensitiveLocalSensitive_data(); -} - -void tst_SpecificRules::noMatchForInt() const -{ - QTest::newRow("[1]") << "1" << false << 0 << true << false; - QTest::newRow("[1299]") << "1299" << false << 0 << true << false; - QTest::newRow("[10]") << "10" << false << 0 << true << false; - QTest::newRow("[9]") << "9" << false << 0 << true << false; -} - -void tst_SpecificRules::noMatchForFloat() const -{ - QTest::newRow("[4e-11]") << "4e-11" << false << 0 << true << false; - QTest::newRow("[1e+5]") << "1e+5" << false << 0 << true << false; - QTest::newRow("[7.321E-3]") << "7.321E-3" << false << 0 << true << false; - QTest::newRow("[3.2E+4]") << "3.2E+4" << false << 0 << true << false; - QTest::newRow("[0.5e-6]") << "0.5e-6" << false << 0 << true << false; - QTest::newRow("[0.45]") << "0.45" << false << 0 << true << false; - QTest::newRow("[6.e10]") << "6.e10" << false << 0 << true << false; - QTest::newRow("[.2e23]") << ".2e23" << false << 0 << true << false; - QTest::newRow("[23.]") << "23." << false << 0 << true << false; - QTest::newRow("[2.e23]") << "2.e23" << false << 0 << true << false; - QTest::newRow("[23e2]") << "23e2" << false << 0 << true << false; - QTest::newRow("[4.3e]") << "4.3e" << false << 0 << true << false; - QTest::newRow("[4.3ef]") << "4.3ef" << false << 0 << true << false; -} - -void tst_SpecificRules::noMatchForCOctal() const -{ - QTest::newRow("[0]") << "0" << false << 0 << true << false; - QTest::newRow("[07]") << "07" << false << 0 << true << false; - QTest::newRow("[01234567]") << "01234567" << false << 0 << true << false; -} - -void tst_SpecificRules::noMatchForCHex() const -{ - QTest::newRow("[0X934AF]") << "0X934AF" << false << 0 << true << false; - QTest::newRow("[0x934af]") << "0x934af" << false << 0 << true << false; -} - -void tst_SpecificRules::noMatchForNumber() const -{ - QTest::newRow("[a]") << "a" << false << 0 << true << false; - QTest::newRow("[#]") << "#" << false << 0 << true << false; - QTest::newRow("[ ]") << " " << false << 0 << true << false; - QTest::newRow("[a1]") << "a1" << false << 0 << true << false; - QTest::newRow("[.e23]") << ".e23" << false << 0 << true << false; - QTest::newRow("[.e23]") << ".e23" << false << 0 << true << false; - - // + and - are not directly matched by number rules. - QTest::newRow("[+1]") << "+1" << false << 0 << true << false; - QTest::newRow("[-1]") << "-1" << false << 0 << true << false; -} - -void tst_SpecificRules::testInt() -{ - IntRule rule; - testMatch(&rule); -} - -void tst_SpecificRules::testInt_data() -{ - addCommonColumns(); - - noMatchForCOctal(); - noMatchForCHex(); - noMatchForNumber(); - - QTest::newRow("[1]") << "1" << true << 1 << false << false; - QTest::newRow("[1299]") << "1299" << true << 4 << false << false; - QTest::newRow("[10]") << "10" << true << 2 << false << false; - QTest::newRow("[9]") << "9" << true << 1 << false << false; - - // LL, U, and others are matched through child rules. - QTest::newRow("[234U]") << "234U" << true << 3 << false << false; - QTest::newRow("[234LL]") << "234LL" << true << 3 << false << false; -} - -void tst_SpecificRules::testFloat() -{ - FloatRule rule; - testMatch(&rule); -} - -void tst_SpecificRules::testFloat_data() -{ - addCommonColumns(); - - noMatchForInt(); - noMatchForCOctal(); - noMatchForCHex(); - noMatchForNumber(); - - QTest::newRow("[4e-11]") << "4e-11" << true << 5 << false << false; - QTest::newRow("[1e+5]") << "1e+5" << true << 4 << false << false; - QTest::newRow("[7.321E-3]") << "7.321E-3" << true << 8 << false << false; - QTest::newRow("[3.2E+4]") << "3.2E+4" << true << 6 << false << false; - QTest::newRow("[0.5e-6]") << "0.5e-6" << true << 6 << false << false; - QTest::newRow("[0.45]") << "0.45" << true << 4 << false << false; - QTest::newRow("[6.e10]") << "6.e10" << true << 5 << false << false; - QTest::newRow("[.2e23]") << ".2e23" << true << 5 << false << false; - QTest::newRow("[23.]") << "23." << true << 3 << false << false; - QTest::newRow("[2.e23]") << "2.e23" << true << 5 << false << false; - QTest::newRow("[23e2]") << "23e2" << true << 4 << false << false; - - // F, L, and others are matched through child rules. - QTest::newRow("[6.e10f]") << "6.e10f" << true << 5 << false << false; - QTest::newRow("[0.5e-6F]") << "0.5e-6F" << true << 6 << false << false; - QTest::newRow("[23.f]") << "23.f" << true << 3 << false << false; - QTest::newRow("[.2L]") << ".2L" << true << 2 << false << false; -} - -void tst_SpecificRules::testCOctal() -{ - HlCOctRule rule; - testMatch(&rule); -} - -void tst_SpecificRules::testCOctal_data() -{ - addCommonColumns(); - - noMatchForInt(); - noMatchForCHex(); - noMatchForNumber(); - - QTest::newRow("[0]") << "0" << true << 1 << false << false; - QTest::newRow("[07]") << "07" << true << 2 << false << false; - QTest::newRow("[01234567]") << "01234567" << true << 8 << false << false; - QTest::newRow("[012345678]") << "012345678" << true << 8 << false << false; - QTest::newRow("[0888]") << "0888" << true << 1 << false << false; -} - -void tst_SpecificRules::testCHex() -{ - HlCHexRule rule; - testMatch(&rule); -} - -void tst_SpecificRules::testCHex_data() -{ - addCommonColumns(); - - noMatchForInt(); - noMatchForFloat(); - noMatchForCOctal(); - noMatchForNumber(); - - QTest::newRow("[0X934AF]") << "0X934AF" << true << 7 << false << false; - QTest::newRow("[0x934af]") << "0x934af" << true << 7 << false << false; - QTest::newRow("[0x2ik]") << "0x2ik" << true << 3 << false << false; -} - -void tst_SpecificRules::testCString() -{ - HlCStringCharRule rule; - testMatch(&rule); -} - -void tst_SpecificRules::testCString_data() -{ - addCommonColumns(); - - // Escape sequences - QTest::newRow("[\\a]") << "\\a" << true << 2 << false << false; - QTest::newRow("[\\b]") << "\\b" << true << 2 << false << false; - QTest::newRow("[\\e]") << "\\e" << true << 2 << false << false; - QTest::newRow("[\\f]") << "\\f" << true << 2 << false << false; - QTest::newRow("[\\n]") << "\\n" << true << 2 << false << false; - QTest::newRow("[\\r]") << "\\r" << true << 2 << false << false; - QTest::newRow("[\\t]") << "\\t" << true << 2 << false << false; - QTest::newRow("[\\v]") << "\\v" << true << 2 << false << false; - QTest::newRow("[\\?]") << "\\?" << true << 2 << false << false; - QTest::newRow("[\\']") << "\\'" << true << 2 << false << false; - QTest::newRow("[\\\"]") << "\\\"" << true << 2 << false << false; - QTest::newRow("[\\\\]") << "\\\\" << true << 2 << false << false; - QTest::newRow("[\\c]") << "\\c" << false << 0 << true << false; - QTest::newRow("[x]") << "x" << false << 0 << true << false; - QTest::newRow("[ ]") << " " << false << 0 << true << false; - QTest::newRow("[a]") << "x" << false << 0 << true << false; - QTest::newRow("[r]") << "r" << false << 0 << true << false; - QTest::newRow("[//]") << "//" << false << 0 << true << false; - - // Octal values - QTest::newRow("[\\1]") << "\\1" << true << 2 << false << false; - QTest::newRow("[\\12]") << "\\12" << true << 3 << false << false; - QTest::newRow("[\\123]") << "\\123" << true << 4 << false << false; - QTest::newRow("[\\1234]") << "\\1234" << true << 4 << false << false; - QTest::newRow("[\\123x]") << "\\123x" << true << 4 << false << false; - - // Hex values - QTest::newRow("[\\xa]") << "\\xa" << true << 3 << false << false; - QTest::newRow("[\\xA]") << "\\xA" << true << 3 << false << false; - QTest::newRow("[\\Xa]") << "\\Xa" << false << 0 << true << false; - QTest::newRow("[\\xA10]") << "\\xA10" << true << 5 << false << false; - QTest::newRow("[\\xA0123456789]") << "\\xA0123456789" << true << 13 << false << false; - QTest::newRow("[\\xABCDEF]") << "\\xABCDEF" << true << 8 << false << false; - QTest::newRow("[\\xABCDEFGHI]") << "\\xABCDEFGHI" << true << 8 << false << false; -} - -void tst_SpecificRules::testCChar() -{ - HlCCharRule rule; - testMatch(&rule); -} - -void tst_SpecificRules::testCChar_data() -{ - addCommonColumns(); - - // Escape sequences - QTest::newRow("[\'\\a\']") << "\'\\a\'" << true << 4 << false << false; - QTest::newRow("[\'\\b\']") << "\'\\b\'" << true << 4 << false << false; - QTest::newRow("[\'\\e\']") << "\'\\e\'" << true << 4 << false << false; - QTest::newRow("[\'\\f\']") << "\'\\f\'" << true << 4 << false << false; - QTest::newRow("[\'\\n\']") << "\'\\n\'" << true << 4 << false << false; - QTest::newRow("[\'\\r\']") << "\'\\r\'" << true << 4 << false << false; - QTest::newRow("[\'\\t\']") << "\'\\t\'" << true << 4 << false << false; - QTest::newRow("[\'\\v\']") << "\'\\v\'" << true << 4 << false << false; - QTest::newRow("[\'\\?\']") << "\'\\?\'" << true << 4 << false << false; - QTest::newRow("[\'\\'\']") << "\'\\'\'" << true << 4 << false << false; - QTest::newRow("[\'\\\"\']") << "\'\\\"\'" << true << 4 << false << false; - QTest::newRow("[\'\\\\\']") << "\'\\\\\'" << true << 4 << false << false; - QTest::newRow("[\'\\c\']") << "\'\\c\'" << false << 0 << true << false; - QTest::newRow("[x]") << "x" << false << 0 << true << false; - QTest::newRow("[ ]") << " " << false << 0 << true << false; - QTest::newRow("[a]") << "x" << false << 0 << true << false; - QTest::newRow("[r]") << "r" << false << 0 << true << false; - QTest::newRow("[//]") << "//" << false << 0 << true << false; -} - -void tst_SpecificRules::testRangeDetect() -{ - QFETCH(QString, c); - QFETCH(QString, c1); - RangeDetectRule rule; - rule.setChar(c); - rule.setChar1(c1); - - testMatch(&rule); -} - -void tst_SpecificRules::testRangeDetect_data() -{ - QTest::addColumn<QString>("c"); - QTest::addColumn<QString>("c1"); - addCommonColumns(); - - QTest::newRow("[<>] against [<QString>]") << "<" << ">" << "<QString>" - << true << 9 << false << false; - QTest::newRow("[<>] against <x>") << "<" << ">" << "<x>" << true << 3 << false << false; - QTest::newRow("[<>] against < >") << "<" << ">" << "< >" << true << 5 << false << false; - QTest::newRow("[<>] against <x>abc") << "<" << ">" << "<x>abc" << true << 3 << false << false; - QTest::newRow("[<>] against <x> ") << "<" << ">" << "<x> " << true << 3 << false << false; - QTest::newRow("[<>] against abc") << "<" << ">" << "abc" << false << 0 << true << false; - QTest::newRow("[<>] against <abc") << "<" << ">" << "<abc" << false << 0 << true << false; - QTest::newRow("[<>] against abc<") << "<" << ">" << "abc<" << false << 0 << true << false; - QTest::newRow("[<>] against a<bc") << "<" << ">" << "a<bc" << false << 0 << true << false; - QTest::newRow("[<>] against abc<") << "<" << ">" << "abc<" << false << 0 << true << false; - QTest::newRow("[\"\"] against \"test.h\"") << "\"" << "\"" << "\"test.h\"" - << true << 8 << false << false; -} - -void tst_SpecificRules::testLineContinue() -{ - LineContinueRule rule; - testMatch(&rule); -} - -void tst_SpecificRules::testLineContinue_data() -{ - addCommonColumns(); - - QTest::newRow("\\") << "\\" << true << 1 << false << true; - QTest::newRow("\\\\") << "\\\\" << false << 0 << true << false; - QTest::newRow("\\x") << "\\x" << false << 0 << true << false; - QTest::newRow("x\\") << "x\\" << false << 0 << true << false; - QTest::newRow("x") << "x" << false << 0 << true << false; - QTest::newRow("/") << "/" << false << 0 << true << false; -} - -void tst_SpecificRules::testDetectSpaces() -{ - DetectSpacesRule rule; - testMatch(&rule); -} - -void tst_SpecificRules::testDetectSpaces_data() -{ - addCommonColumns(); - - QTest::newRow(" ") << " " << true << 1 << true << false; - QTest::newRow(" ") << " " << true << 4 << true << false; - QTest::newRow("\t") << "\t" << true << 1 << true << false; - QTest::newRow("x") << "x" << false << 0 << true << false; - QTest::newRow("#") << "#" << false << 0 << true << false; -} - -void tst_SpecificRules::testDetectIdentifier() -{ - DetectIdentifierRule rule; - testMatch(&rule); -} - -void tst_SpecificRules::testDetectIdentifier_data() -{ - addCommonColumns(); - - QTest::newRow("name") << "name" << true << 4 << false << false; - QTest::newRow("x") << "x" << true << 1 << false << false; - QTest::newRow("x1") << "x1" << true << 2 << false << false; - QTest::newRow("1x") << "1x" << false << 0 << true << false; - QTest::newRow("_x") << "_x" << true << 2 << false << false; - QTest::newRow("___x") << "___x" << true << 4 << false << false; - QTest::newRow("-x") << "-x" << false << 0 << true << false; - QTest::newRow("@x") << "@x" << false << 0 << true << false; - QTest::newRow("+x") << "+x" << false << 0 << true << false; - QTest::newRow("#x") << "#x" << false << 0 << true << false; - QTest::newRow("x_x") << "x_x" << true << 3 << false << false; - QTest::newRow("x1x") << "x1x" << true << 3 << false << false; - QTest::newRow("x#x") << "x#x" << true << 1 << false << false; - QTest::newRow("x-x") << "x-x" << true << 1 << false << false; - QTest::newRow("abc_") << "abc_" << true << 4 << false << false; - QTest::newRow("abc____") << "abc____" << true << 7 << false << false; - QTest::newRow("abc-") << "abc-" << true << 3 << false << false; - QTest::newRow("abc$") << "abc$" << true << 3 << false << false; -} - -QTEST_MAIN(tst_SpecificRules) -#include "tst_specificrules.moc" diff --git a/tests/auto/qml/qmleditor/qmlcodeformatter/qmlcodeformatter.qbs b/tests/auto/qml/qmleditor/qmlcodeformatter/qmlcodeformatter.qbs index 3cccb75c16..c0ad2eff3a 100644 --- a/tests/auto/qml/qmleditor/qmlcodeformatter/qmlcodeformatter.qbs +++ b/tests/auto/qml/qmleditor/qmlcodeformatter/qmlcodeformatter.qbs @@ -4,6 +4,7 @@ QtcAutotest { name: "QML code formatter autotest" Depends { name: "QmlJS" } Depends { name: "QmlJSTools" } + Depends { name: "TextEditor" } Depends { name: "Qt.widgets" } files: "tst_qmlcodeformatter.cpp" } |