diff options
Diffstat (limited to 'src/libs')
26 files changed, 595 insertions, 152 deletions
diff --git a/src/libs/3rdparty/syntax-highlighting/.gitignore b/src/libs/3rdparty/syntax-highlighting/.gitignore index 02ba11c78a..52f10e28a5 100644 --- a/src/libs/3rdparty/syntax-highlighting/.gitignore +++ b/src/libs/3rdparty/syntax-highlighting/.gitignore @@ -7,3 +7,6 @@ CMakeLists.txt.user callgrind.* heaptrack.* +/build*/ +*.unc-backup* + diff --git a/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt.kde b/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt.kde index 49923fb26e..4f88fcf84a 100644 --- a/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt.kde +++ b/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt.kde @@ -1,9 +1,9 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.5) -set(KF5_VERSION "5.52.0") +set(KF5_VERSION "5.59.0") project(KSyntaxHighlighting VERSION ${KF5_VERSION}) -find_package(ECM 5.51.0 REQUIRED NO_MODULE) +find_package(ECM 5.59.0 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) if(POLICY CMP0063) cmake_policy(SET CMP0063 NEW) @@ -22,6 +22,7 @@ include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(KDECMakeSettings) include(ECMMarkNonGuiExecutable) include(ECMAddQch) +include(ECMOptionalAddSubdirectory) ecm_setup_version(PROJECT @@ -33,15 +34,16 @@ ecm_setup_version(PROJECT # # Dependencies # -set(REQUIRED_QT_VERSION 5.8.0) +set(REQUIRED_QT_VERSION 5.10.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) +find_package(Qt5 ${REQUIRED_QT_VERSION} NO_MODULE QUIET OPTIONAL_COMPONENTS PrintSupport Widgets XmlPatterns) set_package_properties(Qt5 PROPERTIES URL "http://qt-project.org/") set_package_properties(Qt5Widgets PROPERTIES PURPOSE "Example application.") +set_package_properties(Qt5PrintSupport PROPERTIES PURPOSE "Example application.") set_package_properties(Qt5XmlPatterns PROPERTIES PURPOSE "Compile-time validation of syntax definition files.") find_package(Perl REQUIRED) @@ -81,6 +83,7 @@ endif() if (NO_STANDARD_PATHS) add_definitions(-DNO_STANDARD_PATHS) endif() +add_definitions(-DQT_NO_FOREACH) # # Actually build the stuff @@ -90,6 +93,9 @@ add_subdirectory(data) add_subdirectory(src) if(TARGET Qt5::Gui) add_subdirectory(examples) + if (BUILD_TESTING) + add_subdirectory(autotests) + endif() endif() # diff --git a/src/libs/3rdparty/syntax-highlighting/README.md b/src/libs/3rdparty/syntax-highlighting/README.md index 1eedc0af7f..c1b82c63d1 100644 --- a/src/libs/3rdparty/syntax-highlighting/README.md +++ b/src/libs/3rdparty/syntax-highlighting/README.md @@ -30,3 +30,20 @@ out of scope: * management of text buffers or documents If you need any of this, check out [KTextEditor](https://api.kde.org/frameworks/ktexteditor/html/). + +## Adding unit tests for a syntax definition + +* add an input file into the autotests/input/ folder, lets call it test.<language-extension> + +* if the file extension is not sufficient to trigger the right syntax definition, you can add an + second file testname.<language-extension>.syntax that contains the syntax definition name + to enforce the use of the right extension + +* do "make && make test" + +* inspect the outputs found in your binary directory autotests/folding.out, autotests/html.output and autotests/output + +* if ok, run in the binary folder "./autotests/update-reference-data.sh" to copy the results to the right location + +* add the result references after the copying to the git + diff --git a/src/libs/3rdparty/syntax-highlighting/autogenerated/ksyntaxhighlighting_version.h b/src/libs/3rdparty/syntax-highlighting/autogenerated/ksyntaxhighlighting_version.h index bd31a4d407..70795908d6 100644 --- a/src/libs/3rdparty/syntax-highlighting/autogenerated/ksyntaxhighlighting_version.h +++ b/src/libs/3rdparty/syntax-highlighting/autogenerated/ksyntaxhighlighting_version.h @@ -3,10 +3,10 @@ #ifndef SyntaxHighlighting_VERSION_H #define SyntaxHighlighting_VERSION_H -#define SyntaxHighlighting_VERSION_STRING "5.52.0" +#define SyntaxHighlighting_VERSION_STRING "5.59.0" #define SyntaxHighlighting_VERSION_MAJOR 5 -#define SyntaxHighlighting_VERSION_MINOR 52 +#define SyntaxHighlighting_VERSION_MINOR 59 #define SyntaxHighlighting_VERSION_PATCH 0 -#define SyntaxHighlighting_VERSION ((5<<16)|(52<<8)|(0)) +#define SyntaxHighlighting_VERSION ((5<<16)|(59<<8)|(0)) #endif diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/cmake.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/cmake.xml index 2a9088b46c..6d170e4eaa 100644 --- a/src/libs/3rdparty/syntax-highlighting/data/syntax/cmake.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/cmake.xml @@ -31,7 +31,7 @@ <language name="CMake" - version="11" + version="12" kateversion="2.4" section="Other" extensions="CMakeLists.txt;*.cmake;*.cmake.in" @@ -317,6 +317,7 @@ <item>PATTERN</item> <item>PERMISSIONS</item> <item>READ</item> + <item>READ_SYMLINK</item> <item>REGEX</item> <item>RELATIVE</item> <item>RELATIVE_PATH</item> @@ -335,6 +336,7 @@ <item>SHA3_512</item> <item>SHA512</item> <item>SHOW_PROGRESS</item> + <item>SIZE</item> <item>STATUS</item> <item>STRINGS</item> <item>TIMEOUT</item> @@ -484,8 +486,10 @@ <item>CACHE</item> <item>DIRECTORY</item> <item>EXT</item> + <item>LAST_EXT</item> <item>NAME</item> <item>NAME_WE</item> + <item>NAME_WLE</item> <item>PATH</item> <item>PROGRAM</item> <item>PROGRAM_ARGS</item> @@ -1054,6 +1058,7 @@ <item>COPY_FILE</item> <item>COPY_FILE_ERROR</item> <item>LINK_LIBRARIES</item> + <item>LINK_OPTIONS</item> <item>OUTPUT_VARIABLE</item> <item>RESULT_VAR</item> <item>SOURCES</item> @@ -1065,6 +1070,7 @@ <item>COMPILE_OUTPUT_VARIABLE</item> <item>COMPILE_RESULT_VAR</item> <item>LINK_LIBRARIES</item> + <item>LINK_OPTIONS</item> <item>OUTPUT_VARIABLE</item> <item>RUN_OUTPUT_VARIABLE</item> <item>RUN_RESULT_VAR</item> @@ -1209,6 +1215,7 @@ <item>CMAKE_ARCHIVE_OUTPUT_DIRECTORY</item> <item>CMAKE_ARGC</item> <item>CMAKE_ARGV0</item> + <item>CMAKE_AUTOGEN_ORIGIN_DEPENDS</item> <item>CMAKE_AUTOGEN_PARALLEL</item> <item>CMAKE_AUTOGEN_VERBOSE</item> <item>CMAKE_AUTOMOC</item> @@ -1223,6 +1230,7 @@ <item>CMAKE_BACKWARDS_COMPATIBILITY</item> <item>CMAKE_BINARY_DIR</item> <item>CMAKE_BUILD_RPATH</item> + <item>CMAKE_BUILD_RPATH_USE_ORIGIN</item> <item>CMAKE_BUILD_TOOL</item> <item>CMAKE_BUILD_TYPE</item> <item>CMAKE_BUILD_WITH_INSTALL_NAME_DIR</item> @@ -1297,6 +1305,7 @@ <item>CMAKE_FIND_PACKAGE_NAME</item> <item>CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY</item> <item>CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY</item> + <item>CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS</item> <item>CMAKE_FIND_PACKAGE_SORT_DIRECTION</item> <item>CMAKE_FIND_PACKAGE_SORT_ORDER</item> <item>CMAKE_FIND_PACKAGE_WARN_NO_MODULE</item> @@ -1316,6 +1325,10 @@ <item>CMAKE_GENERATOR_INSTANCE</item> <item>CMAKE_GENERATOR_PLATFORM</item> <item>CMAKE_GENERATOR_TOOLSET</item> + <item>CMAKE_GLOBAL_AUTOGEN_TARGET</item> + <item>CMAKE_GLOBAL_AUTOGEN_TARGET_NAME</item> + <item>CMAKE_GLOBAL_AUTORCC_TARGET</item> + <item>CMAKE_GLOBAL_AUTORCC_TARGET_NAME</item> <item>CMAKE_GNUtoMS</item> <item>CMAKE_HAS_ANSI_STRING_STREAM</item> <item>CMAKE_HOME_DIRECTORY</item> @@ -1412,6 +1425,7 @@ <item>CMAKE_MAJOR_VERSION</item> <item>CMAKE_MAKE_PROGRAM</item> <item>CMAKE_MATCH_COUNT</item> + <item>CMAKE_MAXIMUM_RECURSION_DEPTH</item> <item>CMAKE_MFC_FLAG</item> <item>CMAKE_MINIMUM_REQUIRED_VERSION</item> <item>CMAKE_MINOR_VERSION</item> @@ -1884,6 +1898,7 @@ <item>CTEST_SCP_COMMAND</item> <item>CTEST_SITE</item> <item>CTEST_SOURCE_DIRECTORY</item> + <item>CTEST_SUBMIT_URL</item> <item>CTEST_SVN_COMMAND</item> <item>CTEST_SVN_OPTIONS</item> <item>CTEST_SVN_UPDATE_OPTIONS</item> @@ -1964,6 +1979,8 @@ <item>PROJECT_VERSION_PATCH</item> <item>PROJECT_VERSION_TWEAK</item> <item>QTIFWDIR</item> + <item>SWIG_OUTFILE_DIR</item> + <item>SWIG_SOURCE_FILE_EXTENSIONS</item> <item>THREADS_PREFER_PTHREAD_FLAG</item> <item>UNIX</item> <item>WIN32</item> @@ -1982,6 +1999,7 @@ <item>AUTORCC_SOURCE_GROUP</item> <item>CMAKE_CXX_KNOWN_FEATURES</item> <item>CMAKE_C_KNOWN_FEATURES</item> + <item>CMAKE_ROLE</item> <item>DEBUG_CONFIGURATIONS</item> <item>DISABLED_FEATURES</item> <item>ECLIPSE_EXTRA_NATURES</item> @@ -2067,17 +2085,24 @@ <item>ARCHIVE_OUTPUT_DIRECTORY</item> <item>ARCHIVE_OUTPUT_NAME</item> <item>AUTOGEN_BUILD_DIR</item> + <item>AUTOGEN_ORIGIN_DEPENDS</item> <item>AUTOGEN_TARGET_DEPENDS</item> <item>AUTOMOC</item> + <item>AUTOMOC_COMPILER_PREDEFINES</item> <item>AUTOMOC_DEPEND_FILTERS</item> + <item>AUTOMOC_EXECUTABLE</item> + <item>AUTOMOC_MACRO_NAMES</item> <item>AUTOMOC_MOC_OPTIONS</item> <item>AUTORCC</item> + <item>AUTORCC_EXECUTABLE</item> <item>AUTORCC_OPTIONS</item> <item>AUTOUIC</item> + <item>AUTOUIC_EXECUTABLE</item> <item>AUTOUIC_OPTIONS</item> <item>AUTOUIC_SEARCH_PATHS</item> <item>BINARY_DIR</item> <item>BUILD_RPATH</item> + <item>BUILD_RPATH_USE_ORIGIN</item> <item>BUILD_WITH_INSTALL_NAME_DIR</item> <item>BUILD_WITH_INSTALL_RPATH</item> <item>BUNDLE</item> diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/doxygen.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/doxygen.xml index 99b1d79c02..a6abda9204 100644 --- a/src/libs/3rdparty/syntax-highlighting/data/syntax/doxygen.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/doxygen.xml @@ -4,7 +4,7 @@ <!ENTITY wordsep "([][,?;()]|\.$|\.?\s)"> <!-- things that end a TagWord --> ]> <language name="Doxygen" - version="5" + version="6" kateversion="5.0" section="Markup" extensions="*.dox;*.doxygen" @@ -463,7 +463,7 @@ <itemData name="Tags" defStyleNum="dsAnnotation" bold="1" /> <itemData name="Custom Tags" defStyleNum="dsAnnotation" /> <itemData name="Word" defStyleNum="dsCommentVar" bold="1" italic="0" /> - <itemData name="HTML Tag" defStyleNum="dsKeyword" color="#000000" bold="1" italic="0" /> + <itemData name="HTML Tag" defStyleNum="dsKeyword" bold="1" italic="0" /> <itemData name="Entities" defStyleNum="dsOthers" color="#4086C0" bold="1" italic="1" /> <itemData name="Description" defStyleNum="dsDocumentation" /> <itemData name="Comment" defStyleNum="dsComment" /> diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/html.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/html.xml index 4f9eb962d7..107e1067da 100644 --- a/src/libs/3rdparty/syntax-highlighting/data/syntax/html.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/html.xml @@ -5,7 +5,7 @@ <!ENTITY attributeName "[A-Za-z_:*#\(\[][\)\]\w.:_-]*"> <!ENTITY entref "&(#[0-9]+|#[xX][0-9A-Fa-f]+|&name;);"> ]> -<language name="HTML" version="5" kateversion="3.4" section="Markup" extensions="*.htm;*.html;*.shtml;*.shtm" mimetype="text/html" author="Wilbert Berendsen (wilbert@kde.nl)" license="LGPL" priority="10"> +<language name="HTML" version="7" kateversion="3.4" section="Markup" extensions="*.htm;*.html;*.shtml;*.shtm" mimetype="text/html" author="Wilbert Berendsen (wilbert@kde.nl)" license="LGPL" priority="10"> <highlighting> <contexts> @@ -163,16 +163,23 @@ </context> <context name="JS" attribute="Other Text" lineEndContext="#stay"> - <Detect2Chars attribute="Element" context="#pop" char="/" char1=">" endRegion="script" /> + <RegExpr attribute="Attribute" context="Script-Type" String="(\s+|^)type(?=\=|\s|$)" insensitive="true"/> <DetectChar attribute="Element" context="JS content" char=">" /> + <IncludeRules context="DefaultJS" /> + </context> + <context name="DefaultJS" attribute="Other Text" lineEndContext="#stay"> + <Detect2Chars attribute="Element" context="#pop" char="/" char1=">" endRegion="script" /> <IncludeRules context="FindAttributes" /> <RegExpr attribute="Error" context="#stay" String="\S" /> </context> <context name="JS content" attribute="Other Text" lineEndContext="#stay"> + <IncludeRules context="Default JS content"/> + <IncludeRules context="Normal##JavaScript" includeAttrib="true"/> + </context> + <context name="Default JS content" attribute="Other Text" lineEndContext="#stay"> <RegExpr attribute="Element" context="El Close 2" String="</script\b" insensitive="true" endRegion="script" /> <RegExpr attribute="Comment" context="JS comment close" String="//(?=.*</script\b)" insensitive="true" /> - <IncludeRules context="Normal##JavaScript" includeAttrib="true"/> </context> <context name="JS comment close" attribute="Comment" lineEndContext="#pop"> @@ -202,6 +209,79 @@ <IncludeRules context="FindEntityRefs" /> </context> + <!-- Read content from the "type" attribute to change the language to + highlight in the <script> tag. The default language is JavaScript. --> + + <context name="Script-Type" attribute="Other Text" lineEndContext="#stay" fallthrough="true" fallthroughContext="#pop"> + <DetectSpaces /> + <DetectChar attribute="Attribute" context="#pop!Script-Type Value" char="=" /> + </context> + <context name="Script-Type Value" attribute="Other Text" lineEndContext="#stay" fallthrough="true" fallthroughContext="#pop!Value"> + <DetectSpaces /> + <!-- TypeScript --> + <StringDetect attribute="Value" context="#pop#pop!TypeScript" String=""text/typescript""/> + <StringDetect attribute="Value" context="#pop#pop!TypeScript" String="'text/typescript'"/> + <!-- JSX (JavaScript React) --> + <StringDetect attribute="Value" context="#pop#pop!JSX" String=""text/jsx""/> + <StringDetect attribute="Value" context="#pop#pop!JSX" String="'text/jsx'"/> + <StringDetect attribute="Value" context="#pop#pop!JSX" String=""text/babel""/> + <StringDetect attribute="Value" context="#pop#pop!JSX" String="'text/babel'"/> + <!-- MustacheJS / HandlebarsJS / RactiveJS --> + <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String=""x-tmpl-mustache""/> + <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String="'x-tmpl-mustache'"/> + <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String=""text/mustache""/> + <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String="'text/mustache'"/> + <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String=""text/x-mustache-template""/> + <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String="'text/x-mustache-template'"/> + <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String=""text/x-handlebars-template""/> + <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String="'text/x-handlebars-template'"/> + <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String=""text/ractive""/> + <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String="'text/ractive'"/> + <!-- HTML templates --> + <StringDetect attribute="Value" context="#pop#pop!Script HTML template" String=""text/html""/> + <StringDetect attribute="Value" context="#pop#pop!Script HTML template" String="'text/html'"/> + </context> + + <context name="JSX" attribute="Other Text" lineEndContext="#stay"> + <DetectChar attribute="Element" context="JSX content" char=">" /> + <IncludeRules context="DefaultJS" /> + </context> + <context name="JSX content" attribute="Other Text" lineEndContext="#stay"> + <IncludeRules context="Default JS content"/> + <IncludeRules context="Normal##JavaScript React" includeAttrib="true"/> + </context> + + <context name="TypeScript" attribute="Other Text" lineEndContext="#stay"> + <DetectChar attribute="Element" context="TypeScript content" char=">" /> + <IncludeRules context="DefaultJS" /> + </context> + <context name="TypeScript content" attribute="Other Text" lineEndContext="#stay"> + <IncludeRules context="Default JS content"/> + <IncludeRules context="Normal##TypeScript" includeAttrib="true"/> + </context> + + <context name="MustacheJS" attribute="Other Text" lineEndContext="#stay"> + <DetectChar attribute="Element" context="MustacheJS content" char=">" /> + <IncludeRules context="DefaultJS" /> + </context> + <context name="MustacheJS content" attribute="Other Text" lineEndContext="#stay"> + <RegExpr attribute="Element" context="El Close 2" String="</script\b" insensitive="true" endRegion="script" /> + <StringDetect attribute="Error" context="#stay" String="<script>" insensitive="true" /> + <RegExpr attribute="Error" context="#stay" String="<script\b" insensitive="true" /> + <IncludeRules context="Base##Mustache/Handlebars (HTML)" includeAttrib="true"/> + </context> + + <context name="Script HTML template" attribute="Other Text" lineEndContext="#stay"> + <DetectChar attribute="Element" context="Script HTML template content" char=">" /> + <IncludeRules context="DefaultJS" /> + </context> + <context name="Script HTML template content" attribute="Other Text" lineEndContext="#stay"> + <RegExpr attribute="Element" context="El Close 2" String="</script\b" insensitive="true" endRegion="script" /> + <StringDetect attribute="Error" context="#stay" String="<script>" insensitive="true" /> + <RegExpr attribute="Error" context="#stay" String="<script\b" insensitive="true" /> + <IncludeRules context="FindHTML" /> + </context> + </contexts> <itemDatas> <itemData name="Normal Text" defStyleNum="dsNormal" /> diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/ini.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/ini.xml index 465422f0b0..ce300fff47 100644 --- a/src/libs/3rdparty/syntax-highlighting/data/syntax/ini.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/ini.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE language SYSTEM "language.dtd"> -<language name="INI Files" section="Configuration" extensions="*.ini;*.pls;*.kcfgc;*.conf" mimetype="" version="4" kateversion="2.4" author="Jan Janssen (medhefgo@web.de)" license="LGPL"> +<language name="INI Files" section="Configuration" extensions="*.ini;*.pls;*.kcfgc" mimetype="" version="5" kateversion="2.4" author="Jan Janssen (medhefgo@web.de)" license="LGPL"> <highlighting> <list name="keywords"> diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/markdown.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/markdown.xml index 39ffaf77af..f88848729f 100644 --- a/src/libs/3rdparty/syntax-highlighting/data/syntax/markdown.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/markdown.xml @@ -35,7 +35,7 @@ <!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"> +<language name="Markdown" version="6" kateversion="5.0" 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"> @@ -74,13 +74,57 @@ <context attribute="comment" lineEndContext="#stay" name="comment"> <RegExpr String="-->" attribute="comment" context="#pop" endRegion="comment"/> </context> + <context attribute="code" lineEndContext="#stay" name="bash-code"> + <WordDetect attribute="code" context="#pop" String="```"/> + <IncludeRules context="##Bash" includeAttrib="true"/> + </context> + <context attribute="code" lineEndContext="#stay" name="cmake-code"> + <WordDetect attribute="code" context="#pop" String="```"/> + <IncludeRules context="##CMake" includeAttrib="true"/> + </context> + <context attribute="code" lineEndContext="#stay" name="cpp-code"> + <WordDetect attribute="code" context="#pop" String="```"/> + <IncludeRules context="##C++" includeAttrib="true"/> + </context> + <context attribute="code" lineEndContext="#stay" name="css-code"> + <WordDetect attribute="code" context="#pop" String="```"/> + <IncludeRules context="##CSS" includeAttrib="true"/> + </context> + <context attribute="code" lineEndContext="#stay" name="email-code"> + <WordDetect attribute="code" context="#pop" String="```"/> + <IncludeRules context="##Email" includeAttrib="true"/> + </context> + <context attribute="code" lineEndContext="#stay" name="haskell-code"> + <WordDetect attribute="code" context="#pop" String="```"/> + <IncludeRules context="##Haskell" includeAttrib="true"/> + </context> + <context attribute="code" lineEndContext="#stay" name="html-code"> + <WordDetect attribute="code" context="#pop" String="```"/> + <IncludeRules context="##HTML" includeAttrib="true"/> + </context> + <context attribute="code" lineEndContext="#stay" name="json-code"> + <WordDetect attribute="code" context="#pop" String="```"/> + <IncludeRules context="##JSON" includeAttrib="true"/> + </context> <context attribute="code" lineEndContext="#stay" name="php-code"> <WordDetect attribute="code" context="#pop" String="```"/> - <IncludeRules context="phpsource##PHP/PHP"/> + <IncludeRules context="phpsource##PHP/PHP" includeAttrib="true"/> </context> <context attribute="code" lineEndContext="#stay" name="python-code"> <WordDetect attribute="code" context="#pop" String="```"/> - <IncludeRules context="##Python"/> + <IncludeRules context="##Python" includeAttrib="true"/> + </context> + <context attribute="code" lineEndContext="#stay" name="qml-code"> + <WordDetect attribute="code" context="#pop" String="```"/> + <IncludeRules context="##QML" includeAttrib="true"/> + </context> + <context attribute="code" lineEndContext="#stay" name="rust-code"> + <WordDetect attribute="code" context="#pop" String="```"/> + <IncludeRules context="##Rust" includeAttrib="true"/> + </context> + <context attribute="code" lineEndContext="#stay" name="xml-code"> + <WordDetect attribute="code" context="#pop" String="```"/> + <IncludeRules context="##XML" includeAttrib="true"/> </context> <context attribute="code" lineEndContext="#stay" name="code"> <WordDetect attribute="code" context="#pop" String="```"/> @@ -98,8 +142,19 @@ <RegExpr attribute="mailtolink" String="&mailtolinkregex;"/> <RegExpr attribute="strikeout" minimal="true" String="&strikeoutregex;"/> <RegExpr attribute="linebreak" minimal="true" String="&linebreakregex;"/> + <WordDetect attribute="code" context="bash-code" String="```bash"/> + <WordDetect attribute="code" context="cmake-code" String="```cmake"/> + <WordDetect attribute="code" context="cpp-code" String="```cpp"/> + <WordDetect attribute="code" context="css-code" String="```css"/> + <WordDetect attribute="code" context="email-code" String="```email"/> + <WordDetect attribute="code" context="haskell-code" String="```haskell"/> + <WordDetect attribute="code" context="html-code" String="```html"/> + <WordDetect attribute="code" context="json-code" String="```json"/> <WordDetect attribute="code" context="php-code" String="```php"/> <WordDetect attribute="code" context="python-code" String="```python"/> + <WordDetect attribute="code" context="qml-code" String="```qml"/> + <WordDetect attribute="code" context="rust-code" String="```rust"/> + <WordDetect attribute="code" context="xml-code" String="```xml"/> <StringDetect attribute="code" context="code" String="```"/> </context> </contexts> @@ -121,12 +176,12 @@ <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="bullet" defStyleNum="dsString"/> + <itemData name="bl-emphasis" defStyleNum="dsString" italic="true"/> + <itemData name="bl-strong" defStyleNum="dsString" bold="true"/> + <itemData name="numlist" defStyleNum="dsString"/> + <itemData name="nl-emphasis" defStyleNum="dsString" italic="true"/> + <itemData name="nl-strong" defStyleNum="dsString" bold="true"/> <itemData name="comment" defStyleNum="dsComment"/> <itemData name="code" defStyleNum="dsBaseN"/> <itemData name="reflink" defStyleNum="dsOthers" underline="true"/> diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/perl.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/perl.xml index cd3d3ce65c..0d1931649c 100644 --- a/src/libs/3rdparty/syntax-highlighting/data/syntax/perl.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/perl.xml @@ -39,7 +39,7 @@ Enhance tr/// and y/// support. --> -<language name="Perl" version="7" kateversion="2.4" section="Scripts" extensions="*.pl;*.PL;*.pm;*.pl6;*.PL6;*.p6;*.pm6;" mimetype="application/x-perl;text/x-perl" priority="5" author="Anders Lund (anders@alweb.dk)" license="LGPLv2"> +<language name="Perl" version="8" kateversion="2.4" section="Scripts" extensions="*.pl;*.PL;*.pm;*.pl6;*.PL6;*.p6;*.pm6;" mimetype="application/x-perl;text/x-perl" priority="5" author="Anders Lund (anders@alweb.dk)" license="LGPLv2"> <highlighting> <list name="keywords"> <item>if</item> @@ -383,8 +383,11 @@ <RegExpr attribute="Operator" context="find_pattern" String="\b(?:m|qr)(?=\s*[^\w\s\]})])" /> - <RegExpr attribute="Normal Text" context="#stay" String="[\w_]+\s*/" /> - <RegExpr attribute="Normal Text" context="#stay" String="[<>"':]/" /> + <RegExpr attribute="Normal Text" context="#stay" String="[\w_]+\s*//?\=?" /> + <RegExpr attribute="Normal Text" context="#stay" String="[<>"':]//?\=?" /> + <!-- Avoid conflicts between operators / and // --> + <StringDetect attribute="Normal Text" context="#stay" String="//=" /> + <Detect2Chars attribute="Normal Text" context="#stay" char="/" char1="/" /> <DetectChar attribute="Operator" context="pattern_slash" char="/" beginRegion="Pattern" /> <RegExpr attribute="Operator" context="#stay" String="-[rwxoRWXOeszfdlpSbctugkTBMAC]\b" /> diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/ruby.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/ruby.xml index 754dfdc5fe..a451e1442f 100644 --- a/src/libs/3rdparty/syntax-highlighting/data/syntax/ruby.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/ruby.xml @@ -31,7 +31,7 @@ <!-- Hold the "language" opening tag on a single line, as mentioned in "language.dtd". --> <language name="Ruby" section="Scripts" - version="9" kateversion="3.3" + version="10" kateversion="3.3" extensions="*.rb;*.rjs;*.rxml;*.xml.erb;*.js.erb;*.rake;Rakefile;Gemfile;*.gemspec;Vagrantfile" mimetype="application/x-ruby" style="ruby" indenter="ruby" @@ -179,11 +179,11 @@ <item>warn</item> </list> - <list name="mixin-methods"> - <item>extend</item> - <item>include</item> - <item>prepend</item> - </list> + <list name="mixin-methods"> + <item>extend</item> + <item>include</item> + <item>prepend</item> + </list> <contexts> <context name="Normal" attribute="Normal Text" lineEndContext="#stay"> @@ -204,7 +204,7 @@ <RegExpr attribute="Keyword" String="\;\s*(while|until)\b(?!.*\bdo\b)" context="#stay" beginRegion="def block"/> <RegExpr attribute="Keyword" String="(if|unless)\b" context="#stay" beginRegion="def block" firstNonSpace="true"/> <RegExpr attribute="Keyword" String="\;\s*(if|unless)\b" context="#stay" beginRegion="def block"/> - <WordDetect attribute="Keyword" String="class" context="#stay" beginRegion="def block"/> + <WordDetect attribute="Keyword" String="class" context="no_heredoc" beginRegion="def block"/> <WordDetect attribute="Keyword" String="module" context="#stay" beginRegion="def block"/> <WordDetect attribute="Keyword" String="begin" context="#stay" beginRegion="def block"/> <RegExpr attribute="Keyword" String="\bfor\b(?!.*\bdo\b)" context="#stay" beginRegion="def block"/> @@ -231,7 +231,7 @@ <keyword attribute="Pseudo variable" String="pseudo-variables" context="check_div_1"/> <keyword attribute="Default globals" String="default-globals" context="check_div_2"/> <keyword attribute="Kernel methods" String="kernel-methods" context="check_div_2"/> - <keyword attribute="Module mixin methods" String="mixin-methods" context="check_div_2"/> + <keyword attribute="Module mixin methods" String="mixin-methods" context="check_div_2"/> <!-- (global) vars starting with $ Match them before $_. @@ -263,8 +263,8 @@ push operator '<<' than requiring to put space between the operator and the string. --> - <RegExpr attribute="Operator" context="find_indented_heredoc" String="\s*<<-(?=\w+|["'])" beginRegion="HereDocument" /> - <RegExpr attribute="Operator" context="find_heredoc" String="\s*<<(?=\w+|["'])" beginRegion="HereDocument" /> + <RegExpr attribute="Operator" context="find_indented_heredoc" String="\s*<<[-~](?=\w+|["'`])" beginRegion="HereDocument" /> + <RegExpr attribute="Operator" context="find_heredoc" String="\s*<<(?=\w+|["'`])" beginRegion="HereDocument" /> <DetectChar attribute="Operator" char="." context="#stay"/> <Detect2Chars attribute="Operator" char="&" char1="&" context="#stay"/> @@ -280,8 +280,10 @@ <RegExpr attribute="Symbol" String=":(@{1,2}|\$)?[a-zA-Z_][a-zA-Z0-9_]*[=?!]?" context="check_div_1"/> <RegExpr attribute="Symbol" String=":\[\]=?" context="check_div_1"/> - <RegExpr attribute="Symbol" String="(@{1,2}|\$)?[a-zA-Z_][a-zA-Z0-9_]*[=?!]?: " context="check_div_1"/> - <RegExpr attribute="Symbol" String="\[\]=?: " context="check_div_1"/> + <!-- Do not send to "check_div_1" context!: + after detecting these rules (": ") there can be a regular expression (see bug: #361875) --> + <RegExpr attribute="Symbol" String="(@{1,2}|\$)?[a-zA-Z_][a-zA-Z0-9_]*[=?!]?: " context="#stay"/> + <RegExpr attribute="Symbol" String="\[\]=?: " context="#stay"/> <DetectChar attribute="String" char=""" context="Quoted String"/> <DetectChar attribute="Raw String" char="'" context="Apostrophed String"/> @@ -436,13 +438,17 @@ The contexts below support both normal and indented heredocs --> <!-- here we markup the heredoc markers --> - <context name="find_heredoc" attribute="Normal Text" lineEndContext="#pop" > + <context name="find_heredoc" attribute="Normal Text" lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop"> <RegExpr attribute="Keyword" context="apostrophed_normal_heredoc" String="'(\w+)'" /> - <RegExpr attribute="Keyword" context="normal_heredoc" String=""?(\w+)"?" /> + <RegExpr attribute="Keyword" context="normal_heredoc" String="(\w+)" /> + <RegExpr attribute="Keyword" context="normal_heredoc" String=""(\w+)"" /> + <RegExpr attribute="Keyword" context="normal_heredoc" String="`(\w+)`" /> </context> - <context name="find_indented_heredoc" attribute="Normal Text" lineEndContext="#pop" > + <context name="find_indented_heredoc" attribute="Normal Text" lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop"> <RegExpr attribute="Keyword" context="apostrophed_indented_heredoc" String="'(\w+)'" /> - <RegExpr attribute="Keyword" context="indented_heredoc" String=""?(\w+)"?" /> + <RegExpr attribute="Keyword" context="indented_heredoc" String="(\w+)" /> + <RegExpr attribute="Keyword" context="indented_heredoc" String=""(\w+)"" /> + <RegExpr attribute="Keyword" context="indented_heredoc" String="`(\w+)`" /> </context> <!-- these are the real heredoc contexts --> <context name="indented_heredoc" attribute="Here Document" lineEndContext="#stay" dynamic="true"> @@ -467,6 +473,16 @@ <Detect2Chars attribute="Substitution" char="#" char1="{" context="Subst"/> </context> + <!-- avoid highlighting heredoc markers, for example, in singleton class definition (see bug: #358273) --> + <context name="no_heredoc" attribute="Normal Text" lineEndContext="#stay" fallthrough="true" fallthroughContext="#pop"> + <DetectSpaces /> + <Detect2Chars attribute="Operator" char="<" char1="<" context="#pop"/> + <!-- comments --> + <RegExpr attribute="Comment" String="#\s*BEGIN.*$" context="#stay" beginRegion="marker" column="0"/> + <RegExpr attribute="Comment" String="#\s*END.*$" context="#stay" endRegion="marker" column="0"/> + <DetectChar attribute="Comment" char="#" context="General Comment"/> + </context> + <!-- General delimited input support The contexts below handle the various gdl formats --> @@ -892,7 +908,7 @@ <itemData name="Constant" defStyleNum="dsDataType"/> <itemData name="Constant Value" defStyleNum="dsDataType" color="#bb1188"/> <itemData name="Kernel methods" defStyleNum="dsNormal" color="#000080" selColor="#ffffff"/> <!-- #CC0E86 --> - <itemData name="Module mixin methods" defStyleNum="dsNormal" color="#000080" selColor="#ffffff"/> <!-- #CC0E86 --> + <itemData name="Module mixin methods" defStyleNum="dsNormal" color="#000080" selColor="#ffffff"/> <!-- #CC0E86 --> <itemData name="Member" defStyleNum="dsNormal"/> <itemData name="Instance Variable" defStyleNum="dsOthers"/> <itemData name="Class Variable" defStyleNum="dsOthers"/> @@ -913,3 +929,5 @@ <keywords casesensitive="1" weakDeliminator="!?"/> </general> </language> + +<!-- kate: replace-tabs off; --> diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/yacc.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/yacc.xml index 6936c7a2de..06d6492ff1 100644 --- a/src/libs/3rdparty/syntax-highlighting/data/syntax/yacc.xml +++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/yacc.xml @@ -32,7 +32,7 @@ This code is released under the LGPL as part of kdelibs/kate. ======================================================================== --> -<language name="Yacc/Bison" version="4" kateversion="2.4" section="Sources" extensions="*.y;*.yy;*.ypp;*.y++" mimetype="text/x-yacc;text/x-bison" priority="5" author="Jan Villat (jan.villat@net2000.ch)" license="LGPL"> +<language name="Yacc/Bison" version="5" kateversion="5.0" section="Sources" extensions="*.y;*.yy;*.ypp;*.y++" mimetype="text/x-yacc;text/x-bison" priority="5" author="Jan Villat (jan.villat@net2000.ch)" license="LGPL"> <highlighting> <contexts> @@ -200,9 +200,12 @@ This code is released under the LGPL as part of kdelibs/kate. </context> <context name="CommentStar" attribute="Comment" lineEndContext="#stay"> <Detect2Chars attribute="Comment" context="#pop" char="*" char1="/" /> + <IncludeRules context="##Alerts" /> + <IncludeRules context="##Modelines" /> </context> - <context name="CommentSlash" attribute="Comment" lineEndContext="#stay"> - <RegExpr attribute="Comment" context="#pop" String="[^\\]$" /> + <context name="CommentSlash" attribute="Comment" lineEndContext="#pop"> + <IncludeRules context="##Alerts" /> + <IncludeRules context="##Modelines" /> </context> <context name="StringOrChar" attribute="Normal Text" lineEndContext="#stay"> 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 index 80a15d2589..8334dd32e9 100644 --- a/src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp +++ b/src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp @@ -92,14 +92,14 @@ int main(int argc, char **argv) Repository repo; if (parser.isSet(listDefs)) { - foreach (const auto &def, repo.definitions()) { + for (const auto &def : repo.definitions()) { std::cout << qPrintable(def.name()) << std::endl; } return 0; } if (parser.isSet(listThemes)) { - foreach (const auto &theme, repo.themes()) + for (const auto &theme : repo.themes()) std::cout << qPrintable(theme.name()) << std::endl; return 0; } diff --git a/src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp b/src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp index 489fbec160..3534cfde90 100644 --- a/src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp +++ b/src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp @@ -194,6 +194,82 @@ bool checkLookAhead(const QString &hlFilename, QXmlStreamReader &xml) } /** + * Helper class to search for non-existing keyword include. + */ +class KeywordIncludeChecker +{ +public: + void processElement(const QString &hlFilename, const QString &hlName, QXmlStreamReader &xml) + { + if (xml.name() == QLatin1String("list")) { + auto &keywords = m_keywordMap[hlName]; + keywords.filename = hlFilename; + auto name = xml.attributes().value(QLatin1String("name")).toString(); + m_currentIncludes = &keywords.includes[name]; + } + else if (xml.name() == QLatin1String("include")) { + if (!m_currentIncludes) { + qWarning() << hlFilename << "line" << xml.lineNumber() << "<include> tag ouside <list>"; + m_success = false; + } else { + m_currentIncludes->push_back({xml.lineNumber(), xml.readElementText()}); + } + } + } + + bool check() const + { + bool success = m_success; + for (auto &keywords : m_keywordMap) { + QMapIterator<QString, QVector<Keywords::Include>> includes(keywords.includes); + while (includes.hasNext()) { + includes.next(); + for (auto &include : includes.value()) { + bool containsKeywordName = true; + int const idx = include.name.indexOf(QStringLiteral("##")); + if (idx == -1) { + auto &keywordName = includes.key(); + containsKeywordName = keywords.includes.contains(keywordName); + } + else { + auto defName = include.name.mid(idx + 2); + auto listName = include.name.left(idx); + auto it = m_keywordMap.find(defName); + if (it == m_keywordMap.end()) { + qWarning() << keywords.filename << "line" << include.line << "unknown definition in" << include.name; + success = false; + } else { + containsKeywordName = it->includes.contains(listName); + } + } + + if (!containsKeywordName) { + qWarning() << keywords.filename << "line" << include.line << "unknown keyword name in" << include.name; + success = false; + } + } + } + } + return success; + } + +private: + struct Keywords + { + QString filename; + struct Include + { + qint64 line; + QString name; + }; + QMap<QString, QVector<Include>> includes; + }; + QHash<QString, Keywords> m_keywordMap; + QVector<Keywords::Include> *m_currentIncludes = nullptr; + bool m_success = true; +}; + +/** * Helper class to search for non-existing or unreferenced keyword lists. */ class KeywordChecker @@ -296,6 +372,7 @@ public: const auto unusedNames = language.existingContextNames - language.usedContextNames; if (!unusedNames.isEmpty()) { qWarning() << language.hlFilename << "Unused contexts:" << unusedNames; + success = false; } } @@ -457,9 +534,10 @@ int main(int argc, char *argv[]) // index all given highlightings ContextChecker contextChecker; + KeywordIncludeChecker keywordIncludeChecker; QVariantMap hls; int anyError = 0; - foreach (const QString &hlFilename, hlFilenames) { + for (const QString &hlFilename : qAsConst(hlFilenames)) { QFile hlFile(hlFilename); if (!hlFile.open(QIODevice::ReadOnly)) { qWarning ("Failed to open %s", qPrintable(hlFilename)); @@ -493,7 +571,7 @@ int main(int argc, char *argv[]) QVariantMap hl; // transfer text attributes - Q_FOREACH (const QString &attribute, textAttributes) { + for (const QString &attribute : qAsConst(textAttributes)) { hl[attribute] = xml.attributes().value(attribute).toString(); } @@ -528,6 +606,9 @@ int main(int argc, char *argv[]) // search for used/existing contexts if applicable contextChecker.processElement(hlFilename, hlName, xml); + // search for existing keyword includes + keywordIncludeChecker.processElement(hlFilename, hlName, xml); + // search for used/existing attributes if applicable attributeChecker.processElement(xml); @@ -571,6 +652,9 @@ int main(int argc, char *argv[]) if (!contextChecker.check()) anyError = 7; + if (!keywordIncludeChecker.check()) + anyError = 7; + // bail out if any problem was seen if (anyError) diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt b/src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt index bf729fca71..95bf4c349e 100644 --- a/src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt @@ -40,6 +40,7 @@ ecm_generate_headers(SyntaxHighlighting_HEADERS HEADER_NAMES AbstractHighlighter Definition + DefinitionDownloader FoldingRegion Format Repository diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp index f69944debd..c4ef86a771 100644 --- a/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp @@ -53,7 +53,7 @@ void AbstractHighlighterPrivate::ensureDefinitionLoaded() defData = DefinitionData::get(m_definition); } - if (Q_UNLIKELY(!defData->repo && !defData->name.isEmpty())) + if (Q_UNLIKELY(!defData->repo && !defData->fileName.isEmpty())) qCCritical(Log) << "Repository got deleted while a highlighter is still active!"; if (m_definition.isValid()) @@ -118,13 +118,13 @@ State AbstractHighlighter::highlightLine(const QString& text, const State &state // verify definition, deal with no highlighting being enabled d->ensureDefinitionLoaded(); - if (!d->m_definition.isValid()) { + const auto defData = DefinitionData::get(d->m_definition); + if (!d->m_definition.isValid() || !defData->isLoaded()) { 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); @@ -139,9 +139,37 @@ State AbstractHighlighter::highlightLine(const QString& text, const State &state // process empty lines if (text.isEmpty()) { - while (!stateData->topContext()->lineEmptyContext().isStay()) { - if (!d->switchContext(stateData, stateData->topContext()->lineEmptyContext(), QStringList())) + /** + * handle line empty context switches + * guard against endless loops + * see https://phabricator.kde.org/D18509 + */ + int endlessLoopingCounter = 0; + while (!stateData->topContext()->lineEmptyContext().isStay() || (stateData->topContext()->lineEmptyContext().isStay() && !stateData->topContext()->lineEndContext().isStay())) { + /** + * line empty context switches + */ + if (!stateData->topContext()->lineEmptyContext().isStay()) { + if (!d->switchContext(stateData, stateData->topContext()->lineEmptyContext(), QStringList())) { + /** + * end when trying to #pop the main context + */ + break; + } + /** + * line end context switches only when lineEmptyContext is #stay. This avoids + * skipping empty lines after a line continuation character (see bug 405903) + */ + } else if (!stateData->topContext()->lineEndContext().isStay() && + !d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList())) break; + + // guard against endless loops + ++endlessLoopingCounter; + if (endlessLoopingCounter > 1024) { + qCDebug(Log) << "Endless switch context transitions for line empty context, aborting highlighting of line."; + break; + } } auto context = stateData->topContext(); applyFormat(0, 0, context->attributeFormat()); @@ -238,11 +266,18 @@ State AbstractHighlighter::highlightLine(const QString& text, const State &state if (newOffset <= offset) continue; - // apply folding - if (rule->endRegion().isValid()) - applyFolding(offset, newOffset - offset, rule->endRegion()); + /** + * apply folding. + * special cases: + * - rule with endRegion + beginRegion: in endRegion, the length is 0 + * - rule with lookAhead: length is 0 + */ + if (rule->endRegion().isValid() && rule->beginRegion().isValid()) + applyFolding(offset, 0, rule->endRegion()); + else if (rule->endRegion().isValid()) + applyFolding(offset, rule->isLookAhead() ? 0 : newOffset - offset, rule->endRegion()); if (rule->beginRegion().isValid()) - applyFolding(offset, newOffset - offset, rule->beginRegion()); + applyFolding(offset, rule->isLookAhead() ? 0 : newOffset - offset, rule->beginRegion()); if (rule->isLookAhead()) { Q_ASSERT(!rule->context().isStay()); @@ -293,12 +328,30 @@ State AbstractHighlighter::highlightLine(const QString& text, const State &state } while (offset < text.size()); + /** + * apply format for remaining text, if any + */ if (beginOffset < offset) applyFormat(beginOffset, text.size() - beginOffset, *currentFormat); - while (!stateData->topContext()->lineEndContext().isStay() && !lineContinuation) { - if (!d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList())) - break; + /** + * handle line end context switches + * guard against endless loops + * see https://phabricator.kde.org/D18509 + */ + { + int endlessLoopingCounter = 0; + while (!stateData->topContext()->lineEndContext().isStay() && !lineContinuation) { + if (!d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList())) + break; + + // guard against endless loops + ++endlessLoopingCounter; + if (endlessLoopingCounter > 1024) { + qCDebug(Log) << "Endless switch context transitions for line end context, aborting highlighting of line."; + break; + } + } } return newState; diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp index c03d23dc48..ae95a6b235 100644 --- a/src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp @@ -31,6 +31,7 @@ #include "context_p.h" #include "format.h" #include "format_p.h" +#include "repository.h" #include "repository_p.h" #include "rule_p.h" #include "ksyntaxhighlighting_logging.h" @@ -222,13 +223,13 @@ QStringList Definition::foldingIgnoreList() const QStringList Definition::keywordLists() const { - d->load(); + d->load(DefinitionData::OnlyKeywords(true)); return d->keywordLists.keys(); } QStringList Definition::keywordList(const QString& name) const { - d->load(); + d->load(DefinitionData::OnlyKeywords(true)); const auto list = d->keywordList(name); return list ? list->keywords() : QStringList(); } @@ -323,18 +324,18 @@ Context* DefinitionData::initialContext() const return contexts.first(); } -Context* DefinitionData::contextByName(const QString& name) const +Context* DefinitionData::contextByName(const QString& wantedName) const { - foreach (auto context, contexts) { - if (context->name() == name) + for (const auto context : contexts) { + if (context->name() == wantedName) return context; } return nullptr; } -KeywordList *DefinitionData::keywordList(const QString& name) +KeywordList *DefinitionData::keywordList(const QString& wantedName) { - auto it = keywordLists.find(name); + auto it = keywordLists.find(wantedName); return (it == keywordLists.end()) ? nullptr : &it.value(); } @@ -343,9 +344,9 @@ bool DefinitionData::isWordDelimiter(QChar c) const return std::binary_search(wordDelimiters.constBegin(), wordDelimiters.constEnd(), c); } -Format DefinitionData::formatByName(const QString& name) const +Format DefinitionData::formatByName(const QString& wantedName) const { - const auto it = formats.constFind(name); + const auto it = formats.constFind(wantedName); if (it != formats.constEnd()) return it.value(); @@ -357,7 +358,7 @@ bool DefinitionData::isLoaded() const return !contexts.isEmpty(); } -bool DefinitionData::load() +bool DefinitionData::load(OnlyKeywords onlyKeywords) { if (fileName.isEmpty()) return false; @@ -365,6 +366,9 @@ bool DefinitionData::load() if (isLoaded()) return true; + if (bool(onlyKeywords) && keywordIsLoaded) + return true; + QFile file(fileName); if (!file.open(QFile::ReadOnly)) return false; @@ -375,17 +379,22 @@ bool DefinitionData::load() if (token != QXmlStreamReader::StartElement) continue; - if (reader.name() == QLatin1String("highlighting")) - loadHighlighting(reader); + if (reader.name() == QLatin1String("highlighting")) { + loadHighlighting(reader, onlyKeywords); + if (bool(onlyKeywords)) { + return true; + } + } else if (reader.name() == QLatin1String("general")) loadGeneral(reader); } - for (auto it = keywordLists.begin(); it != keywordLists.end(); ++it) - (*it).setCaseSensitivity(caseSensitive); + for (auto it = keywordLists.begin(); it != keywordLists.end(); ++it) { + it->setCaseSensitivity(caseSensitive); + } - foreach (auto context, contexts) { + for (const auto context : qAsConst(contexts)) { context->resolveContexts(); context->resolveIncludes(); context->resolveAttributeFormat(); @@ -454,10 +463,10 @@ bool DefinitionData::loadMetaData(const QString &file, const QJsonObject &obj) fileName = file; const auto exts = obj.value(QLatin1String("extensions")).toString(); - foreach (const auto &ext, exts.split(QLatin1Char(';'), QString::SkipEmptyParts)) + for (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)) + for (const auto &mt : mts.split(QLatin1Char(';'), QString::SkipEmptyParts)) mimetypes.push_back(mt); return true; @@ -482,29 +491,42 @@ bool DefinitionData::loadLanguage(QXmlStreamReader &reader) 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)) + for (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)) + for (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) +void DefinitionData::loadHighlighting(QXmlStreamReader& reader, OnlyKeywords onlyKeywords) { Q_ASSERT(reader.name() == QLatin1String("highlighting")); Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement); + // skip highlighting + reader.readNext(); + while (!reader.atEnd()) { switch (reader.tokenType()) { case QXmlStreamReader::StartElement: if (reader.name() == QLatin1String("list")) { - KeywordList keywords; - keywords.load(reader); - keywordLists.insert(keywords.name(), keywords); + if (!keywordIsLoaded) { + KeywordList keywords; + keywords.load(reader); + keywordLists.insert(keywords.name(), keywords); + } + else { + reader.skipCurrentElement(); + reader.readNext(); // Skip </list> + } + } else if (bool(onlyKeywords)) { + resolveIncludeKeywords(); + return; } else if (reader.name() == QLatin1String("contexts")) { + resolveIncludeKeywords(); loadContexts(reader); reader.readNext(); } else if (reader.name() == QLatin1String("itemDatas")) { @@ -522,6 +544,19 @@ void DefinitionData::loadHighlighting(QXmlStreamReader& reader) } } +void DefinitionData::resolveIncludeKeywords() +{ + if (keywordIsLoaded) { + return; + } + + keywordIsLoaded = true; + + for (auto it = keywordLists.begin(); it != keywordLists.end(); ++it) { + it->resolveIncludeKeywords(*this); + } +} + void DefinitionData::loadContexts(QXmlStreamReader& reader) { Q_ASSERT(reader.name() == QLatin1String("contexts")); @@ -598,7 +633,7 @@ void DefinitionData::loadGeneral(QXmlStreamReader& reader) 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"))) + for (const auto c : reader.attributes().value(QLatin1String("weakDeliminator"))) wordDelimiters.remove(c); // adaptWordWrapDelimiters, and sort diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/definition_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/definition_p.h index ab95a9552c..9bbf59691c 100644 --- a/src/libs/3rdparty/syntax-highlighting/src/lib/definition_p.h +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/definition_p.h @@ -46,6 +46,9 @@ public: DefinitionData(); ~DefinitionData(); + DefinitionData(const DefinitionData &) = delete; + DefinitionData &operator=(const DefinitionData &) = delete; + static DefinitionData* get(const Definition &def); bool isLoaded() const; @@ -54,9 +57,11 @@ public: void clear(); - bool load(); + enum class OnlyKeywords : bool; + + bool load(OnlyKeywords onlyKeywords = OnlyKeywords(false)); bool loadLanguage(QXmlStreamReader &reader); - void loadHighlighting(QXmlStreamReader &reader); + void loadHighlighting(QXmlStreamReader &reader, OnlyKeywords onlyKeywords); void loadContexts(QXmlStreamReader &reader); void loadItemData(QXmlStreamReader &reader); void loadGeneral(QXmlStreamReader &reader); @@ -65,6 +70,8 @@ public: void loadSpellchecking(QXmlStreamReader &reader); bool checkKateVersion(const QStringRef &verStr); + void resolveIncludeKeywords(); + KeywordList *keywordList(const QString &name); bool isWordDelimiter(QChar c) const; @@ -83,6 +90,7 @@ public: QHash<QString, Format> formats; QString wordDelimiters; QString wordWrapDelimiters; + bool keywordIsLoaded = false; bool hasFoldingRegions = false; bool indentationBasedFolding = false; QStringList foldingIgnoreList; diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp index 397da6d700..d1808cafef 100644 --- a/src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp @@ -213,52 +213,52 @@ 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(); + QStringRef attribute = reader.attributes().value(QStringLiteral("color")); + if (!attribute.isEmpty()) { + style.textColor = QColor(attribute.toString()).rgba(); } - ref = reader.attributes().value(QStringLiteral("selColor")); - if (!ref.isEmpty()) { - style.selectedTextColor = QColor(ref.toString()).rgba(); + attribute = reader.attributes().value(QStringLiteral("selColor")); + if (!attribute.isEmpty()) { + style.selectedTextColor = QColor(attribute.toString()).rgba(); } - ref = reader.attributes().value(QStringLiteral("backgroundColor")); - if (!ref.isEmpty()) { - style.backgroundColor = QColor(ref.toString()).rgba(); + attribute = reader.attributes().value(QStringLiteral("backgroundColor")); + if (!attribute.isEmpty()) { + style.backgroundColor = QColor(attribute.toString()).rgba(); } - ref = reader.attributes().value(QStringLiteral("selBackgroundColor")); - if (!ref.isEmpty()) { - style.selectedBackgroundColor = QColor(ref.toString()).rgba(); + attribute = reader.attributes().value(QStringLiteral("selBackgroundColor")); + if (!attribute.isEmpty()) { + style.selectedBackgroundColor = QColor(attribute.toString()).rgba(); } - ref = reader.attributes().value(QStringLiteral("italic")); - if (!ref.isEmpty()) { + attribute = reader.attributes().value(QStringLiteral("italic")); + if (!attribute.isEmpty()) { style.hasItalic = true; - style.italic = Xml::attrToBool(ref); + style.italic = Xml::attrToBool(attribute); } - ref = reader.attributes().value(QStringLiteral("bold")); - if (!ref.isEmpty()) { + attribute = reader.attributes().value(QStringLiteral("bold")); + if (!attribute.isEmpty()) { style.hasBold = true; - style.bold = Xml::attrToBool(ref); + style.bold = Xml::attrToBool(attribute); } - ref = reader.attributes().value(QStringLiteral("underline")); - if (!ref.isEmpty()) { + attribute = reader.attributes().value(QStringLiteral("underline")); + if (!attribute.isEmpty()) { style.hasUnderline = true; - style.underline = Xml::attrToBool(ref); + style.underline = Xml::attrToBool(attribute); } - ref = reader.attributes().value(QStringLiteral("strikeOut")); - if (!ref.isEmpty()) { + attribute = reader.attributes().value(QStringLiteral("strikeOut")); + if (!attribute.isEmpty()) { style.hasStrikeThrough = true; - style.strikeThrough = Xml::attrToBool(ref); + style.strikeThrough = Xml::attrToBool(attribute); } - ref = reader.attributes().value(QStringLiteral("spellChecking")); - if (!ref.isEmpty()) { - spellCheck = Xml::attrToBool(ref); + attribute = reader.attributes().value(QStringLiteral("spellChecking")); + if (!attribute.isEmpty()) { + spellCheck = Xml::attrToBool(attribute); } } diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp index fe5f77586a..f042baac27 100644 --- a/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp @@ -22,6 +22,9 @@ */ #include "keywordlist_p.h" +#include "repository.h" +#include "definition_p.h" +#include "ksyntaxhighlighting_logging.h" #include <QDebug> #include <QXmlStreamReader> @@ -58,6 +61,11 @@ void KeywordList::load(QXmlStreamReader& reader) reader.readNextStartElement(); break; } + else if (reader.name() == QLatin1String("include")) { + m_includes.append(reader.readElementText().trimmed()); + reader.readNextStartElement(); + break; + } reader.readNext(); break; case QXmlStreamReader::EndElement: @@ -102,3 +110,40 @@ void KeywordList::initLookupForCaseSensitivity(Qt::CaseSensitivity caseSensitive */ std::sort(vectorToSort.begin(), vectorToSort.end(), [caseSensitive] (const QStringRef &a, const QStringRef &b) { return a.compare(b, caseSensitive) < 0; }); } + +void KeywordList::resolveIncludeKeywords(DefinitionData &def) +{ + while (!m_includes.isEmpty()) { + const auto kw_include = std::move(m_includes.back()); + m_includes.pop_back(); + + const auto idx = kw_include.indexOf(QLatin1String("##")); + KeywordList *keywords = nullptr; + + if (idx >= 0) { + auto listName = kw_include.left(idx); + auto defName = kw_include.mid(idx + 2); + auto includeDef = def.repo->definitionForName(defName); + if (includeDef.isValid()) { + auto defData = DefinitionData::get(includeDef); + defData->load(DefinitionData::OnlyKeywords(true)); + keywords = defData->keywordList(listName); + } + else { + qCWarning(Log) << "Unable to resolve external include keyword for definition" << defName << "in" << def.name; + } + } else { + keywords = def.keywordList(kw_include); + } + + if (keywords) { + if (this != keywords) { + keywords->resolveIncludeKeywords(def); + } + m_keywords += keywords->m_keywords; + } + else { + qCWarning(Log) << "Unresolved include keyword" << kw_include << "in" << def.name; + } + } +} diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist_p.h index 8c41aabe0c..25d0022dbe 100644 --- a/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist_p.h +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist_p.h @@ -36,6 +36,9 @@ QT_END_NAMESPACE namespace KSyntaxHighlighting { +class Repository; +class DefinitionData; + class KeywordList { public: @@ -69,6 +72,7 @@ public: void load(QXmlStreamReader &reader); void setCaseSensitivity(Qt::CaseSensitivity caseSensitive); void initLookupForCaseSensitivity(Qt::CaseSensitivity caseSensitive); + void resolveIncludeKeywords(DefinitionData &def); private: /** @@ -82,6 +86,11 @@ private: QStringList m_keywords; /** + * raw list of include keywords, as seen in XML (but trimmed) + */ + QStringList m_includes; + + /** * default case-sensitivity setting */ Qt::CaseSensitivity m_caseSensitive = Qt::CaseSensitive; diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp index 922225a7e1..aaba9616dc 100644 --- a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp @@ -69,7 +69,7 @@ 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) + for (const auto &def : qAsConst(d->m_sortedDefs)) DefinitionData::get(def)->repo = nullptr; } @@ -78,21 +78,16 @@ Definition Repository::definitionForName(const QString& defName) const return d->m_defs.value(defName); } -static Definition bestCandidate(QVector<Definition> &&candidates) +static void sortDefinitions(QVector<Definition> &definitions) { - if (candidates.isEmpty()) - return Definition(); - - std::partial_sort(candidates.begin(), candidates.begin() + 1, candidates.end(), [](const Definition &lhs, const Definition &rhs) { + std::stable_sort(definitions.begin(), definitions.end(), [](const Definition &lhs, const Definition &rhs) { return lhs.priority() > rhs.priority(); }); - - return candidates.at(0); } Definition Repository::definitionForFileName(const QString& fileName) const { - return bestCandidate(definitionsForFileName(fileName)); + return definitionsForFileName(fileName).value(0); } QVector<Definition> Repository::definitionsForFileName(const QString &fileName) const @@ -101,9 +96,8 @@ QVector<Definition> Repository::definitionsForFileName(const QString &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()) { + for (const Definition &def : qAsConst(d->m_sortedDefs)) { + for (const auto &pattern : def.extensions()) { if (WildcardMatcher::exactMatch(name, pattern)) { candidates.push_back(def); break; @@ -111,26 +105,28 @@ QVector<Definition> Repository::definitionsForFileName(const QString &fileName) } } + sortDefinitions(candidates); return candidates; } Definition Repository::definitionForMimeType(const QString& mimeType) const { - return bestCandidate(definitionsForMimeType(mimeType)); + return definitionsForMimeType(mimeType).value(0); } QVector<Definition> Repository::definitionsForMimeType(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()) { + for (const Definition &def : qAsConst(d->m_sortedDefs)) { + for (const auto &matchType : def.mimeTypes()) { if (mimeType == matchType) { candidates.push_back(def); break; } } } + + sortDefinitions(candidates); return candidates; } @@ -169,11 +165,11 @@ void RepositoryPrivate::load(Repository *repo) // 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)) + for (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)) + for (const auto &dir : QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("katepart5/syntax"), QStandardPaths::LocateDirectory)) loadSyntaxFolder(repo, dir); #endif @@ -181,7 +177,7 @@ void RepositoryPrivate::load(Repository *repo) loadSyntaxFolder(repo, QStringLiteral(":/org.kde.syntax-highlighting/syntax")); // user given extra paths - foreach (const auto &path, m_customSearchPaths) + for (const auto &path : qAsConst(m_customSearchPaths)) loadSyntaxFolder(repo, path + QStringLiteral("/syntax")); m_sortedDefs.reserve(m_defs.size()); @@ -198,7 +194,7 @@ void RepositoryPrivate::load(Repository *repo) // 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)) + for (const auto &dir : QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("org.kde.syntax-highlighting/themes"), QStandardPaths::LocateDirectory)) loadThemeFolder(dir); #endif @@ -206,7 +202,7 @@ void RepositoryPrivate::load(Repository *repo) loadThemeFolder(QStringLiteral(":/org.kde.syntax-highlighting/themes")); // user given extra paths - foreach (const auto &path, m_customSearchPaths) + for (const auto &path : qAsConst(m_customSearchPaths)) loadThemeFolder(path + QStringLiteral("/themes")); } @@ -307,7 +303,7 @@ quint16 RepositoryPrivate::nextFormatId() void Repository::reload() { qCDebug(Log) << "Reloading syntax definitions!"; - foreach (const auto &def, d->m_sortedDefs) + for (const auto &def : qAsConst(d->m_sortedDefs)) DefinitionData::get(def)->clear(); d->m_defs.clear(); d->m_sortedDefs.clear(); diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h index e4e9bed69f..2bc66965cf 100644 --- a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h @@ -167,9 +167,11 @@ public: Definition definitionForFileName(const QString &fileName) const; /** - * Returns all Definition%s for the file named @p fileName. + * Returns all Definition%s for the file named @p fileName sorted by priority. * The match is performed based on the \e extensions and @e mimetype of * the definition files. + * + * @since 5.56 */ QVector<Definition> definitionsForFileName(const QString &fileName) const; @@ -184,7 +186,9 @@ public: Definition definitionForMimeType(const QString &mimeType) const; /** - * Returns all Definition%s to the type named @p mimeType + * Returns all Definition%s to the type named @p mimeType sorted by priority + * + * @since 5.56 */ QVector<Definition> definitionsForMimeType(const QString &mimeType) const; diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp index c48753bf0c..d9cf5eb211 100644 --- a/src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp @@ -59,7 +59,8 @@ static int matchEscapedChar(const QString &text, int offset) if (controlChars.contains(c)) return offset + 2; - if (c == QLatin1Char('x')) { // hex encoded character + // hex encoded character + if (c == QLatin1Char('x')) { auto newOffset = offset + 2; for (int i = 0; i < 2 && newOffset + i < text.size(); ++i, ++newOffset) { if (!isHexChar(text.at(newOffset))) @@ -70,14 +71,13 @@ static int matchEscapedChar(const QString &text, int offset) return newOffset; } - if (isOctalChar(c)) { // octal encoding + // octal encoding, simple \0 is OK, too, unlike simple \x above + if (isOctalChar(c)) { 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; } diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp index 2bb61a7ae6..4987dc95f0 100644 --- a/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp +++ b/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp @@ -156,15 +156,15 @@ void SyntaxHighlighter::highlightBlock(const QString& text) void SyntaxHighlighter::applyFormat(int offset, int length, const KSyntaxHighlighting::Format& format) { - if (format.isDefaultTextStyle(theme()) || length == 0) + if (length == 0) return; QTextCharFormat tf; - if (format.hasTextColor(theme())) - tf.setForeground(format.textColor(theme())); + // always set the foreground color to avoid palette issues + 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())) diff --git a/src/libs/qmleditorwidgets/colorbox.cpp b/src/libs/qmleditorwidgets/colorbox.cpp index ad8109c27d..b0da2642e2 100644 --- a/src/libs/qmleditorwidgets/colorbox.cpp +++ b/src/libs/qmleditorwidgets/colorbox.cpp @@ -29,12 +29,10 @@ static inline QString properName(const QColor &color) { - QString s; if (color.alpha() == 255) - s.sprintf("#%02x%02x%02x", color.red(), color.green(), color.blue()); + return QString::asprintf("#%02x%02x%02x", color.red(), color.green(), color.blue()); else - s.sprintf("#%02x%02x%02x%02x", color.alpha(), color.red(), color.green(), color.blue()); - return s; + return QString::asprintf("#%02x%02x%02x%02x", color.alpha(), color.red(), color.green(), color.blue()); } static inline QColor properColor(const QString &str) |