Editor: update ksyntaxhighlighting engine to v5.87.0

Change-Id: If9dab8b321799f0ce908c831e812c20301a714e1
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
David Schulz
2021-10-19 09:46:07 +02:00
parent e77e57420a
commit fc11797218
78 changed files with 2607 additions and 805 deletions

View File

@@ -0,0 +1,4 @@
# clang-format
56ed6f3f5f505eb0dbffc630729d67c3fb510546
#clang-tidy
0960472cc3f57831a97697a4ae0cd139e2cc5551

View File

@@ -9,6 +9,11 @@ callgrind.*
heaptrack.*
/build*/
*.unc-backup*
.clang-format
.cmake/
*.code-workspace
/.clang-format
/.cmake/
/*.code-workspace
/compile_commands.json
.clangd
.idea
/cmake-build*
.cache

View File

@@ -0,0 +1,5 @@
# SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
# SPDX-License-Identifier: CC0-1.0
include:
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux.yml

View File

@@ -0,0 +1,7 @@
Dependencies:
- 'on': ['@all']
'require':
'frameworks/extra-cmake-modules': '@same'
Options:
test-before-installing: True

View File

@@ -10,11 +10,12 @@ add_qtc_library(KSyntaxHighlighting SHARED
PUBLIC_INCLUDES
src/lib
autogenerated/src/lib
DEFINES KSYNTAXHIGHLIGHTING_LIBRARY
DEFINES KF5SyntaxHighlighting_EXPORTS
DEPENDS Qt5::Network Qt5::Widgets
SOURCES
autogenerated/src/lib/ksyntaxhighlighting_logging.cpp autogenerated/src/lib/ksyntaxhighlighting_logging.h
autogenerated/ksyntaxhighlighting_version.h
autogenerated/src/lib/ksyntaxhighlighting_export.h
data/themes/theme-data.qrc
@@ -29,7 +30,6 @@ add_qtc_library(KSyntaxHighlighting SHARED
src/lib/format.cpp src/lib/format.h src/lib/format_p.h
src/lib/htmlhighlighter.cpp src/lib/htmlhighlighter.h
src/lib/keywordlist.cpp src/lib/keywordlist_p.h
src/lib/ksyntaxhighlighting_export.h
src/lib/matchresult_p.h
src/lib/repository.cpp src/lib/repository.h src/lib/repository_p.h
src/lib/rule.cpp src/lib/rule_p.h

View File

@@ -23,6 +23,8 @@ It's meant as a building block for text editors as well as for simple highlighte
text rendering (e.g. as HTML), supporting both integration with a custom editor
as well as a ready-to-use QSyntaxHighlighter sub-class.
Besides a C++ API, a [QML API](@ref qml_api) is also provided.
## Out of scope
To not turn this into yet another text editor, the following things are considered
@@ -46,7 +48,7 @@ in **data/syntax/** and have the **.xml** extension. Additional ones are
picked up from the file system if present, so you can easily extend this
by application-specific syntax definitions for example.
To install or test a syntax definiton file locally, place it in
To install or test a syntax definition file locally, place it in
**org.kde.syntax-highlighting/syntax/**, which is located in your user directory.
Usually it is:
@@ -56,47 +58,56 @@ Usually it is:
<td>$HOME/.local/share/org.kde.syntax-highlighting/syntax/</td>
</tr>
<tr>
<td>For <a href="https://flathub.org/apps/details/org.kde.kate">Kate's Flatpak package</a></td>
<td>$HOME/.var/app/org.kde.kate/data/org.kde.syntax-highlighting/syntax/</td>
<td>For Flatpak packages</td>
<td>$HOME/.var/app/<em>package-name</em>/data/org.kde.syntax-highlighting/syntax/</td>
</tr>
<tr>
<td>For <a href="https://snapcraft.io/kate">Kate's Snap package</a></td>
<td>$HOME/snap/kate/current/.local/share/org.kde.syntax-highlighting/syntax/</td>
<td>For Snap packages</a></td>
<td>$HOME/snap/<em>package-name</em>/current/.local/share/org.kde.syntax-highlighting/syntax/</td>
</tr>
<tr>
<td>On Windows®</td>
<td>&#37;USERPROFILE&#37;&#92;AppData&#92;Local&#92;org.kde.syntax-highlighting&#92;syntax&#92;</td>
</tr>
<tr>
<td>On macOS®</td>
<td>$HOME/Library/Application Support/org.kde.syntax-highlighting/syntax/</td>
</tr>
</table>
For more details, see ["The Highlight Definition XML Format" (Working with Syntax Highlighting, KDE Documentation)](https://docs.kde.org/?application=katepart&branch=trunk5&path=highlight.html#katehighlight-xml-format).
Also, in **data/schema/** there is a script to validate the syntax definiton XML
Also, in **data/schema/** there is a script to validate the syntax definition XML
files. Use the command `validatehl.sh mySyntax.xml`.
## Color theme files
This library includes the color themes, the theme files use the **JSON**
format and are located in **data/themes/** with the **.theme** extension.
This library includes the color themes, which are documented
[here](https://docs.kde.org/?application=katepart&branch=trunk5&path=color-themes.html).
The color theme files use the JSON format and are located in **data/themes/**
with the **.theme** extension.
Additional ones are also picked up from the file system if present,
in the **org.kde.syntax-highlighting/themes/** folder of your user directory,
allowing you to easily add custom color theme files.
The location of **org.kde.syntax-highlighting/themes/** is the same
allowing you to easily add custom color theme files. This location is the same
as shown in the table of the [previous section](#syntax-definition-files),
replacing the **syntax** folder with **themes**.
For more details, see ["The Color Themes JSON Format" (Working with Color Themes, KDE Documentation)](https://docs.kde.org/?application=katepart&branch=trunk5&path=color-themes.html#color-themes-json).
The [KTextEditor](https://api.kde.org/frameworks/ktexteditor/html/) library
(used by Kate, Kile and KDevelop, for example) provides
a user interface for editing and creating KSyntaxHighlighting color themes, including
(used by Kate, Kile and KDevelop, for example) provides a
[user interface](https://docs.kde.org/?application=katepart&branch=trunk5&path=color-themes.html#color-themes-gui)
for editing and creating KSyntaxHighlighting color themes, including
a tool for exporting and importing the JSON theme files.
Note that in KDE text editors, the KSyntaxHighlighting color themes are used
[since KDE Frameworks 5.75](https://kate-editor.org/post/2020/2020-09-13-kate-color-themes-5.75/),
released on October 10, 2020. Previously, Kate's color schemes
(KConfig based schema config) were used and are now deprecated.
The tool **utils/schema-converter/** and the script **utils/kateschema_to_theme_converter.py**
convert the old Kate schemas to KSyntaxHighlighting themes.
For more information, see:
* [Kate - Color Themes with Frameworks 5.75 (Kate Editor Website)](https://kate-editor.org/post/2020/2020-09-13-kate-color-themes-5.75/)
* [Submit a KSyntaxHighlighting Color Theme (Kate Editor Website)](https://kate-editor.org/post/2020/2020-09-18-submit-a-ksyntaxhighlighting-color-theme/)
Also see ["Submit a KSyntaxHighlighting Color Theme" (Kate Editor Website)](https://kate-editor.org/post/2020/2020-09-18-submit-a-ksyntaxhighlighting-color-theme/).
## Build it

View File

@@ -6,4 +6,5 @@ SOURCES += \
HEADERS += \
$$PWD/ksyntaxhighlighting_version.h \
$$PWD/src/lib/ksyntaxhighlighting_logging.h
$$PWD/src/lib/ksyntaxhighlighting_logging.h \
$$PWD/src/lib/ksyntaxhighlighting_export.h

View File

@@ -3,10 +3,10 @@
#ifndef SyntaxHighlighting_VERSION_H
#define SyntaxHighlighting_VERSION_H
#define SyntaxHighlighting_VERSION_STRING "5.80.0"
#define SyntaxHighlighting_VERSION_STRING "5.87.0"
#define SyntaxHighlighting_VERSION_MAJOR 5
#define SyntaxHighlighting_VERSION_MINOR 80
#define SyntaxHighlighting_VERSION_MINOR 87
#define SyntaxHighlighting_VERSION_PATCH 0
#define SyntaxHighlighting_VERSION ((5<<16)|(80<<8)|(0))
#define SyntaxHighlighting_VERSION ((5<<16)|(87<<8)|(0))
#endif

View File

@@ -0,0 +1 @@
#include "wildcardmatcher.h"

View File

@@ -0,0 +1,218 @@
#ifndef KSYNTAXHIGHLIGHTING_EXPORT_H
#define KSYNTAXHIGHLIGHTING_EXPORT_H
#include <QtGlobal>
#ifdef KSYNTAXHIGHLIGHTING_STATIC_DEFINE
# define KSYNTAXHIGHLIGHTING_EXPORT
# define KSYNTAXHIGHLIGHTING_NO_EXPORT
#else
# ifndef KSYNTAXHIGHLIGHTING_EXPORT
# ifdef KF5SyntaxHighlighting_EXPORTS
/* We are building this library */
# define KSYNTAXHIGHLIGHTING_EXPORT Q_DECL_EXPORT
# else
/* We are using this library */
# define KSYNTAXHIGHLIGHTING_EXPORT Q_DECL_IMPORT
# endif
# endif
# ifndef KSYNTAXHIGHLIGHTING_NO_EXPORT
# define KSYNTAXHIGHLIGHTING_NO_EXPORT
# endif
#endif
#ifndef KSYNTAXHIGHLIGHTING_DECL_DEPRECATED
# define KSYNTAXHIGHLIGHTING_DECL_DEPRECATED __declspec(deprecated)
#endif
#ifndef KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_EXPORT
# define KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_EXPORT KSYNTAXHIGHLIGHTING_EXPORT KSYNTAXHIGHLIGHTING_DECL_DEPRECATED
#endif
#ifndef KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_NO_EXPORT
# define KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_NO_EXPORT KSYNTAXHIGHLIGHTING_NO_EXPORT KSYNTAXHIGHLIGHTING_DECL_DEPRECATED
#endif
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef KSYNTAXHIGHLIGHTING_NO_DEPRECATED
# define KSYNTAXHIGHLIGHTING_NO_DEPRECATED
# endif
#endif
#define KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_TEXT(text) __declspec(deprecated(text))
#define ECM_GENERATEEXPORTHEADER_VERSION_VALUE(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
/* Take any defaults from group settings */
#if !defined(KSYNTAXHIGHLIGHTING_NO_DEPRECATED) && !defined(KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT)
# ifdef KF_NO_DEPRECATED
# define KSYNTAXHIGHLIGHTING_NO_DEPRECATED
# elif defined(KF_DISABLE_DEPRECATED_BEFORE_AND_AT)
# define KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT KF_DISABLE_DEPRECATED_BEFORE_AND_AT
# endif
#endif
#if !defined(KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT) && defined(KF_DISABLE_DEPRECATED_BEFORE_AND_AT)
# define KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT KF_DISABLE_DEPRECATED_BEFORE_AND_AT
#endif
#if !defined(KSYNTAXHIGHLIGHTING_NO_DEPRECATED_WARNINGS) && !defined(KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE)
# ifdef KF_NO_DEPRECATED_WARNINGS
# define KSYNTAXHIGHLIGHTING_NO_DEPRECATED_WARNINGS
# elif defined(KF_DEPRECATED_WARNINGS_SINCE)
# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE KF_DEPRECATED_WARNINGS_SINCE
# endif
#endif
#if !defined(KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE) && defined(KF_DEPRECATED_WARNINGS_SINCE)
# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE KF_DEPRECATED_WARNINGS_SINCE
#endif
#if defined(KSYNTAXHIGHLIGHTING_NO_DEPRECATED)
# undef KSYNTAXHIGHLIGHTING_DEPRECATED
# define KSYNTAXHIGHLIGHTING_DEPRECATED_EXPORT KSYNTAXHIGHLIGHTING_EXPORT
# define KSYNTAXHIGHLIGHTING_DEPRECATED_NO_EXPORT KSYNTAXHIGHLIGHTING_NO_EXPORT
#elif defined(KSYNTAXHIGHLIGHTING_NO_DEPRECATED_WARNINGS)
# define KSYNTAXHIGHLIGHTING_DEPRECATED
# define KSYNTAXHIGHLIGHTING_DEPRECATED_EXPORT KSYNTAXHIGHLIGHTING_EXPORT
# define KSYNTAXHIGHLIGHTING_DEPRECATED_NO_EXPORT KSYNTAXHIGHLIGHTING_NO_EXPORT
#else
# define KSYNTAXHIGHLIGHTING_DEPRECATED KSYNTAXHIGHLIGHTING_DECL_DEPRECATED
# define KSYNTAXHIGHLIGHTING_DEPRECATED_EXPORT KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_EXPORT
# define KSYNTAXHIGHLIGHTING_DEPRECATED_NO_EXPORT KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_NO_EXPORT
#endif
/* No deprecated API had been removed from build */
#define KSYNTAXHIGHLIGHTING_EXCLUDE_DEPRECATED_BEFORE_AND_AT 0
#define KSYNTAXHIGHLIGHTING_BUILD_DEPRECATED_SINCE(major, minor) 1
#ifdef KSYNTAXHIGHLIGHTING_NO_DEPRECATED
# define KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT 0x55700
#endif
#ifdef KSYNTAXHIGHLIGHTING_NO_DEPRECATED_WARNINGS
# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE 0
#endif
#ifndef KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE
# ifdef KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT
# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT
# else
# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE 0x55700
# endif
#endif
#ifndef KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT
# define KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT 0
#endif
#ifdef KSYNTAXHIGHLIGHTING_DEPRECATED
# define KSYNTAXHIGHLIGHTING_ENABLE_DEPRECATED_SINCE(major, minor) (ECM_GENERATEEXPORTHEADER_VERSION_VALUE(major, minor, 0) > KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT)
#else
# define KSYNTAXHIGHLIGHTING_ENABLE_DEPRECATED_SINCE(major, minor) 0
#endif
#if KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE >= 0x55700
# define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_5_87(text) KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_TEXT(text)
#else
# define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_5_87(text)
#endif
#define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_5(minor, text) KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_5_##minor(text)
#define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION(major, minor, text) KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_##major(minor, "Since "#major"."#minor". " text)
#define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_BELATED(major, minor, textmajor, textminor, text) KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_##major(minor, "Since "#textmajor"."#textminor". " text)
// Not yet implemented for MSVC
#define KSYNTAXHIGHLIGHTING_ENUMERATOR_DEPRECATED_VERSION(major, minor, text)
#define KSYNTAXHIGHLIGHTING_ENUMERATOR_DEPRECATED_VERSION_BELATED(major, minor, textmajor, textminor, text)
#endif /* KSYNTAXHIGHLIGHTING_EXPORT_H */
#ifndef ECM_GENERATEEXPORTHEADER_KSYNTAXHIGHLIGHTING_EXPORT_H
#define ECM_GENERATEEXPORTHEADER_KSYNTAXHIGHLIGHTING_EXPORT_H
#define KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_TEXT(text) __declspec(deprecated(text))
#define ECM_GENERATEEXPORTHEADER_VERSION_VALUE(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
/* Take any defaults from group settings */
#if !defined(KSYNTAXHIGHLIGHTING_NO_DEPRECATED) && !defined(KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT)
# ifdef KF_NO_DEPRECATED
# define KSYNTAXHIGHLIGHTING_NO_DEPRECATED
# elif defined(KF_DISABLE_DEPRECATED_BEFORE_AND_AT)
# define KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT KF_DISABLE_DEPRECATED_BEFORE_AND_AT
# endif
#endif
#if !defined(KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT) && defined(KF_DISABLE_DEPRECATED_BEFORE_AND_AT)
# define KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT KF_DISABLE_DEPRECATED_BEFORE_AND_AT
#endif
#if !defined(KSYNTAXHIGHLIGHTING_NO_DEPRECATED_WARNINGS) && !defined(KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE)
# ifdef KF_NO_DEPRECATED_WARNINGS
# define KSYNTAXHIGHLIGHTING_NO_DEPRECATED_WARNINGS
# elif defined(KF_DEPRECATED_WARNINGS_SINCE)
# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE KF_DEPRECATED_WARNINGS_SINCE
# endif
#endif
#if !defined(KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE) && defined(KF_DEPRECATED_WARNINGS_SINCE)
# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE KF_DEPRECATED_WARNINGS_SINCE
#endif
#if defined(KSYNTAXHIGHLIGHTING_NO_DEPRECATED)
# undef KSYNTAXHIGHLIGHTING_DEPRECATED
# define KSYNTAXHIGHLIGHTING_DEPRECATED_EXPORT KSYNTAXHIGHLIGHTING_EXPORT
# define KSYNTAXHIGHLIGHTING_DEPRECATED_NO_EXPORT KSYNTAXHIGHLIGHTING_NO_EXPORT
#elif defined(KSYNTAXHIGHLIGHTING_NO_DEPRECATED_WARNINGS)
# define KSYNTAXHIGHLIGHTING_DEPRECATED
# define KSYNTAXHIGHLIGHTING_DEPRECATED_EXPORT KSYNTAXHIGHLIGHTING_EXPORT
# define KSYNTAXHIGHLIGHTING_DEPRECATED_NO_EXPORT KSYNTAXHIGHLIGHTING_NO_EXPORT
#else
# define KSYNTAXHIGHLIGHTING_DEPRECATED KSYNTAXHIGHLIGHTING_DECL_DEPRECATED
# define KSYNTAXHIGHLIGHTING_DEPRECATED_EXPORT KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_EXPORT
# define KSYNTAXHIGHLIGHTING_DEPRECATED_NO_EXPORT KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_NO_EXPORT
#endif
/* No deprecated API had been removed from build */
#define KSYNTAXHIGHLIGHTING_EXCLUDE_DEPRECATED_BEFORE_AND_AT 0
#define KSYNTAXHIGHLIGHTING_BUILD_DEPRECATED_SINCE(major, minor) 1
#ifdef KSYNTAXHIGHLIGHTING_NO_DEPRECATED
# define KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT 0x55700
#endif
#ifdef KSYNTAXHIGHLIGHTING_NO_DEPRECATED_WARNINGS
# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE 0
#endif
#ifndef KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE
# ifdef KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT
# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT
# else
# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE 0x55700
# endif
#endif
#ifndef KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT
# define KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT 0
#endif
#ifdef KSYNTAXHIGHLIGHTING_DEPRECATED
# define KSYNTAXHIGHLIGHTING_ENABLE_DEPRECATED_SINCE(major, minor) (ECM_GENERATEEXPORTHEADER_VERSION_VALUE(major, minor, 0) > KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT)
#else
# define KSYNTAXHIGHLIGHTING_ENABLE_DEPRECATED_SINCE(major, minor) 0
#endif
#if KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE >= 0x55700
# define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_5_87(text) KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_TEXT(text)
#else
# define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_5_87(text)
#endif
#define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_5(minor, text) KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_5_##minor(text)
#define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION(major, minor, text) KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_##major(minor, "Since "#major"."#minor". " text)
#define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_BELATED(major, minor, textmajor, textminor, text) KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_##major(minor, "Since "#textmajor"."#textminor". " text)
// Not yet implemented for MSVC
#define KSYNTAXHIGHLIGHTING_ENUMERATOR_DEPRECATED_VERSION(major, minor, text)
#define KSYNTAXHIGHLIGHTING_ENUMERATOR_DEPRECATED_VERSION_BELATED(major, minor, textmajor, textminor, text)
#endif /* ECM_GENERATEEXPORTHEADER_KSYNTAXHIGHLIGHTING_EXPORT_H */

View File

@@ -38,8 +38,11 @@ generate_syntax_definition(generate-doxygenlua.pl doxygenlua.xml doxygen.xml)
file(GLOB src_defs "${CMAKE_CURRENT_SOURCE_DIR}/syntax/*.xml")
set(defs ${src_defs} ${gen_defs})
# object library to make cross-folder dependencies work
add_library(SyntaxHighlightingData OBJECT)
# theme data resource
qt5_add_resources(themes_QRC ${CMAKE_CURRENT_SOURCE_DIR}/themes/theme-data.qrc)
target_sources(SyntaxHighlightingData PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/themes/theme-data.qrc)
# do we want syntax files bundled in the library?
if (QRC_SYNTAX)
@@ -66,14 +69,10 @@ if (QRC_SYNTAX)
)
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)
target_sources(SyntaxHighlightingData PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/qrc_syntax-data.cpp)
else()
# install the syntax files as normal files into the prefix
install (FILES ${defs} DESTINATION ${KDE_INSTALL_DATADIR}/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

View File

@@ -22,7 +22,7 @@
<language
name="CMake"
version="31"
version="<!--{version}-->"
kateversion="5.0"
section="Other"
extensions="CMakeLists.txt;*.cmake;*.cmake.in"

View File

@@ -1,3 +1,5 @@
version: 34
global-properties:
- ALLOW_DUPLICATE_CUSTOM_TARGETS
- AUTOGEN_SOURCE_GROUP
@@ -56,6 +58,7 @@ directory-properties:
- DEFINITIONS
- EXCLUDE_FROM_ALL
- IMPLICIT_DEPENDS_INCLUDE_TRANSFORM
- IMPORTED_TARGETS # Since 3.21
- INCLUDE_DIRECTORIES
- INCLUDE_REGULAR_EXPRESSION
- INTERPROCEDURAL_OPTIMIZATION_<CONFIG>
@@ -172,6 +175,7 @@ target-properties:
- EXCLUDE_FROM_ALL
- EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG>
- EXCLUDE_FROM_DEFAULT_BUILD
- EXPORT_COMPILE_COMMANDS # Since 3.20
- EXPORT_NAME
- EXPORT_PROPERTIES # Since 3.12
- FOLDER
@@ -243,6 +247,7 @@ target-properties:
- <LANG>_CPPCHECK # Since 3.10
- <LANG>_CPPLINT
- <LANG>_INCLUDE_WHAT_YOU_USE
- <LANG>_LINKER_LAUNCHER # Sine 3.21
- <LANG>_VISIBILITY_PRESET
- LIBRARY_OUTPUT_DIRECTORY_<CONFIG>
- LIBRARY_OUTPUT_DIRECTORY
@@ -284,7 +289,6 @@ target-properties:
- OBJCXX_STANDARD # Since 3.16
- OBJCXX_STANDARD_REQUIRED # Since 3.16
- OPTIMIZE_DEPENDENCIES # Since 3.19
- OBJC_STANDARD
- OSX_ARCHITECTURES_<CONFIG>
- OSX_ARCHITECTURES
- OSX_CURRENT_VERSION # Since 3.17
@@ -329,6 +333,7 @@ target-properties:
- UNITY_BUILD_CODE_AFTER_INCLUDE # Since 3.16
- UNITY_BUILD_CODE_BEFORE_INCLUDE # Since 3.16
- UNITY_BUILD_MODE # Since 3.18
- UNITY_BUILD_UNIQUE_ID # Since 3.20
- VERSION
- VISIBILITY_INLINES_HIDDEN
- VS_CONFIGURATION_TYPE
@@ -372,6 +377,10 @@ target-properties:
- WIN32_EXECUTABLE
- WINDOWS_EXPORT_ALL_SYMBOLS
- XCODE_ATTRIBUTE_<an-attribute>
- XCODE_EMBED_<type>_CODE_SIGN_ON_COPY # Since 3.20
- XCODE_EMBED_<type>_PATH # Since 3.20
- XCODE_EMBED_<type>_REMOVE_HEADERS_ON_COPY # Since 3.20
- XCODE_EMBED_<type> # Since 3.20
- XCODE_EXPLICIT_FILE_TYPE
- XCODE_GENERATE_SCHEME # Since 3.15
- XCODE_LINK_BUILD_PHASE_MODE # Since 3.19
@@ -572,6 +581,7 @@ generator-expressions:
- TARGET_BUNDLE_DIR
- TARGET_BUNDLE_CONTENT_DIR
- TARGET_PROPERTY
- TARGET_RUNTIME_DLLS # Since 3.21
- INSTALL_PREFIX
# Output-Related Expressions
- TARGET_NAME
@@ -581,6 +591,8 @@ generator-expressions:
- MAKE_C_IDENTIFIER
- TARGET_OBJECTS
- SHELL_PATH
- OUTPUT_CONFIG # Since 3.20
- COMMAND_CONFIG # Since 3.20
variables:
# Variables that Provide Information
@@ -687,6 +699,7 @@ variables:
- CMAKE_XCODE_PLATFORM_TOOLSET
- <PROJECT-NAME>_BINARY_DIR
- <PROJECT-NAME>_DESCRIPTION # Since 3.12
- <PROJECT-NAME>_IS_TOP_LEVEL # Since 3.21
- <PROJECT-NAME>_HOMEPAGE_URL # Since 3.12
- <PROJECT-NAME>_SOURCE_DIR
- <PROJECT-NAME>_VERSION
@@ -696,6 +709,7 @@ variables:
- <PROJECT-NAME>_VERSION_TWEAK
- PROJECT_BINARY_DIR
- PROJECT_DESCRIPTION # Since 3.9
- PROJECT_IS_TOP_LEVEL # Since 3.21
- PROJECT_HOMEPAGE_URL # Since 3.12
- PROJECT_NAME
- PROJECT_SOURCE_DIR
@@ -819,6 +833,7 @@ variables:
- ANDROID
- APPLE
- BORLAND
- CMAKE_ANDROID_NDK_VERSION # Since 3.20
- CMAKE_CL_64
- CMAKE_COMPILER_2005
- CMAKE_HOST_APPLE
@@ -949,6 +964,9 @@ variables:
- CMAKE_<LANG>_CPPCHECK # Since 3.10
- CMAKE_<LANG>_CPPLINT
- CMAKE_<LANG>_INCLUDE_WHAT_YOU_USE
- CMAKE_<LANG>_LINKER_LAUNCHER # Sine 3.21
- CMAKE_<LANG>_LINK_LIBRARY_FILE_FLAG # Sine 3.16
- CMAKE_<LANG>_LINK_LIBRARY_FLAG # Sine 3.16
- CMAKE_<LANG>_VISIBILITY_PRESET
- CMAKE_LIBRARY_OUTPUT_DIRECTORY
- CMAKE_LIBRARY_OUTPUT_DIRECTORY_<CONFIG>
@@ -1046,6 +1064,7 @@ variables:
- CMAKE_<LANG>_ARCHIVE_APPEND
- CMAKE_<LANG>_ARCHIVE_CREATE
- CMAKE_<LANG>_ARCHIVE_FINISH
- CMAKE_<LANG>_BYTE_ORDER # Since 3.20
- CMAKE_<LANG>_COMPILER
- CMAKE_<LANG>_COMPILER_EXTERNAL_TOOLCHAIN
- CMAKE_<LANG>_COMPILER_ID
@@ -1173,6 +1192,7 @@ variables:
# Variables for CPack
- CPACK_ABSOLUTE_DESTINATION_FILES
- CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY
- CPACK_CUSTOM_INSTALL_VARIABLES # Since 3.21
- CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
- CPACK_INCLUDE_TOPLEVEL_DIRECTORY
- CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS # Since 3.11
@@ -1182,32 +1202,57 @@ variables:
- 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
# NOTE <SMTH>_VERSION and components already defined above, so skipped here
- PACKAGE_FIND_VERSION_COUNT
- PACKAGE_FIND_VERSION_RANGE
- PACKAGE_FIND_VERSION_RANGE_MIN
- PACKAGE_FIND_VERSION_RANGE_MAX
- PACKAGE_FIND_VERSION_MIN
- PACKAGE_FIND_VERSION_MIN_MAJOR
- PACKAGE_FIND_VERSION_MIN_MINOR
- PACKAGE_FIND_VERSION_MIN_PATCH
- PACKAGE_FIND_VERSION_MIN_TWEAK
- PACKAGE_FIND_VERSION_MIN_COUNT
- PACKAGE_FIND_VERSION_MAX
- PACKAGE_FIND_VERSION_MAX_MAJOR
- PACKAGE_FIND_VERSION_MAX_MINOR
- PACKAGE_FIND_VERSION_MAX_PATCH
- PACKAGE_FIND_VERSION_MAX_TWEAK
- PACKAGE_FIND_VERSION_MAX_COUNT
- PACKAGE_FIND_VERSION_COMPLETE
- PACKAGE_VERSION
- PACKAGE_VERSION_EXACT
- PACKAGE_VERSION_COMPATIBLE
- PACKAGE_VERSION_UNSUITABLE
# NOTE <SMTH>_VERSION and components already defined above, so skipped here
# Package File Interface Variables
- <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
- <package>_VERSION_COUNT
# NOTE <SMTH>_VERSION and components already defined above, so skipped here
- <PackageName>_FIND_VERSION_COUNT
- <PackageName>_FIND_VERSION_EXACT
- <PackageName>_FIND_COMPONENTS
- <PackageName>_FIND_REQUIRED_<c>
- <PackageName>_FIND_VERSION_RANGE
- <PackageName>_FIND_VERSION_RANGE_MIN
- <PackageName>_FIND_VERSION_RANGE_MAX
- <PackageName>_FIND_VERSION_MIN
- <PackageName>_FIND_VERSION_MIN_MAJOR
- <PackageName>_FIND_VERSION_MIN_MINOR
- <PackageName>_FIND_VERSION_MIN_PATCH
- <PackageName>_FIND_VERSION_MIN_TWEAK
- <PackageName>_FIND_VERSION_MIN_COUNT
- <PackageName>_FIND_VERSION_MAX
- <PackageName>_FIND_VERSION_MAX_MAJOR
- <PackageName>_FIND_VERSION_MAX_MINOR
- <PackageName>_FIND_VERSION_MAX_PATCH
- <PackageName>_FIND_VERSION_MAX_TWEAK
- <PackageName>_FIND_VERSION_MAX_COUNT
- <PackageName>_FIND_VERSION_COMPLETE
- <PackageName>_CONFIG
- <PackageName>_CONSIDERED_CONFIGS
- <PackageName>_CONSIDERED_VERSIONS
- <PackageName>_ROOT # Since 3.12
# Other standard variables/patterns
# - `try_run`
@@ -1220,6 +1265,10 @@ variables:
# - `cmake_parse_arguments`
- <pfx>_UNPARSED_ARGUMENTS
- <pfx>_KEYWORDS_MISSING_VALUES
# Variables that control `file(GET_RUNTIME_DEPENDENCIES)` behavior
- CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM
- CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL
- CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND
# Well known CMake's official module's variables
# - CheckCompilerFlag
# - CheckCCompilerFlag
@@ -1327,6 +1376,7 @@ variables:
- CPACK_DEBIAN_PACKAGE_HOMEPAGE
- CPACK_DEBIAN_PACKAGE_SHLIBDEPS
- CPACK_DEBIAN_<COMPONENT>_PACKAGE_SHLIBDEPS
- CPACK_DEBIAN_PACKAGE_SHLIBDEPS_PRIVATE_DIRS # Since 3.20
- CPACK_DEBIAN_PACKAGE_DEBUG
- CPACK_DEBIAN_PACKAGE_PREDEPENDS
- CPACK_DEBIAN_<COMPONENT>_PACKAGE_PREDEPENDS
@@ -1364,6 +1414,7 @@ variables:
- CPACK_DMG_SLA_DIR
- CPACK_DMG_SLA_LANGUAGES
- CPACK_DMG_<component>_FILE_NAME # Since 3.17
- CPACK_DMG_FILESYSTEM # Since 3.21
- CPACK_COMMAND_HDIUTIL
- CPACK_COMMAND_SETFILE
- CPACK_COMMAND_REZ
@@ -1389,6 +1440,7 @@ variables:
- CPACK_IFW_PACKAGE_STYLE_SHEET # Since 3.15
- CPACK_IFW_PACKAGE_WIZARD_DEFAULT_WIDTH
- CPACK_IFW_PACKAGE_WIZARD_DEFAULT_HEIGHT
- CPACK_IFW_PACKAGE_WIZARD_SHOW_PAGE_LIST # Since 3.20
- CPACK_IFW_PACKAGE_TITLE_COLOR
- CPACK_IFW_PACKAGE_START_MENU_DIRECTORY
- CPACK_IFW_TARGET_DIRECTORY
@@ -1443,6 +1495,9 @@ variables:
- CPACK_NSIS_FINISH_TITLE_3LINES # Since 3.17
- CPACK_NSIS_MUI_HEADERIMAGE # Since 3.17
- CPACK_NSIS_MANIFEST_DPI_AWARE # Since 3.18
- CPACK_NSIS_BRANDING_TEXT # Since 3.20
- CPACK_NSIS_BRANDING_TEXT_TRIM_POSITION # Since 3.20
- CPACK_NSIS_EXECUTABLE # Since 3.21
# - CPackNuGet (since 3.12)
- CPACK_NUGET_COMPONENT_INSTALL
- CPACK_NUGET_PACKAGE_NAME
@@ -1461,14 +1516,22 @@ variables:
- CPACK_NUGET_<compName>_PACKAGE_HOMEPAGE_URL
- CPACK_NUGET_PACKAGE_LICENSEURL
- CPACK_NUGET_<compName>_PACKAGE_LICENSEURL
- CPACK_NUGET_PACKAGE_LICENSE_EXPRESSION # Since 3.20
- CPACK_NUGET_<compName>_PACKAGE_LICENSE_EXPRESSION # Since 3.20
- CPACK_NUGET_PACKAGE_LICENSE_FILE_NAME # Since 3.20
- CPACK_NUGET_<compName>_PACKAGE_LICENSE_FILE_NAME # Since 3.20
- CPACK_NUGET_PACKAGE_ICONURL
- CPACK_NUGET_<compName>_PACKAGE_ICONURL
- CPACK_NUGET_PACKAGE_ICON # Since 3.20
- CPACK_NUGET_<compName>_PACKAGE_ICON # Since 3.20
- 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_LANGUAGE # Since 3.20
- CPACK_NUGET_<compName>_PACKAGE_LANGUAGE # Since 3.20
- CPACK_NUGET_PACKAGE_TAGS
- CPACK_NUGET_<compName>_PACKAGE_TAGS
- CPACK_NUGET_PACKAGE_DEPENDENCIES
@@ -1617,6 +1680,7 @@ variables:
- CPACK_PACKAGE_EXECUTABLES
- CPACK_STRIP_FILES
- CPACK_VERBATIM_VARIABLES
- CPACK_THREADS # Since 3.20
- CPACK_SOURCE_PACKAGE_FILE_NAME
- CPACK_SOURCE_STRIP_FILES
- CPACK_SOURCE_GENERATOR
@@ -1754,12 +1818,19 @@ variables:
- CMAKE_NO_ANSI_STRING_STREAM
# - TestForSTDNamespace
- CMAKE_NO_STD_NAMESPACE
# - UseJava
- CMAKE_JAVA_COMPILE_FLAGS
- CMAKE_JAVA_INCLUDE_PATH
- CMAKE_JNI_TARGET
- CMAKE_JAR_CLASSES_PREFIX
# - UseSWIG
- UseSWIG_MODULE_VERSION # Since 3.12
- CMAKE_SWIG_FLAGS
- CMAKE_SWIG_OUTDIR
- SWIG_OUTFILE_DIR
- SWIG_MODULE_<name>_EXTRA_DEPS
- SWIG_SOURCE_FILE_EXTENSIONS # Since 3.14
- SWIG_USE_SWIG_DEPENDENCIES # Since 3.20
deprecated-or-internal-variables:
- CMAKE_HOME_DIRECTORY
@@ -1784,6 +1855,10 @@ deprecated-or-internal-variables:
- CPACK_TEMPORARY_DIRECTORY
- CPACK_TOPLEVEL_DIRECTORY
- CPACK_INSTALL_PREFIX
# Mentioned in `file(GET_RUNTIME_DEPENDENCIES)` docs
- CMAKE_OBJDUMP
# Mentioned in "Deprecated and Removed Features" of release notes 3.21
- CMAKE_SYSTEM_ARCH
# https://cmake.org/cmake/help/latest/manual/cmake-env-variables.7.html
# NOTE Added to syntax file version 14 at 3.15.0 version of CMake
@@ -1801,6 +1876,7 @@ environment-variables:
- CMAKE_MSVCIDE_RUN_PATH
- CMAKE_NO_VERBOSE
- CMAKE_OSX_ARCHITECTURES
- CMAKE_TOOLCHAIN_FILE # Since 3.21
- DESTDIR
- LDFLAGS
- MACOSX_DEPLOYMENT_TARGET
@@ -1812,6 +1888,7 @@ environment-variables:
- CC
- CFLAGS
- CSFLAGS
- CUDAARCHS # Since 3.20
- CUDACXX
- CUDAFLAGS
- CUDAHOSTCXX
@@ -1896,6 +1973,55 @@ scripting-commands:
-
name: cmake_parse_arguments
named-args: [PARSE_ARGV]
-
name: cmake_path # Since 3.20
named-args: [
# Decomposition
GET
, ROOT_NAME
, ROOT_DIRECTORY
, ROOT_PATH
, FILENAME
, EXTENSION
, LAST_ONLY
, STEM
, RELATIVE_PART
, PARENT_PATH
# Query
, HAS_ROOT_NAME
, HAS_ROOT_DIRECTORY
, HAS_ROOT_PATH
, HAS_FILENAME
, HAS_EXTENSION
, HAS_STEM
, HAS_RELATIVE_PART
, HAS_PARENT_PATH
, IS_ABSOLUTE
, IS_RELATIVE
, IS_PREFIX
, NORMALIZE
# Modification
, SET
, APPEND
, OUTPUT_VARIABLE
, APPEND_STRING
, REMOVE_FILENAME
, REPLACE_FILENAME
, REMOVE_EXTENSION
, REPLACE_EXTENSION
# Generation
, NORMAL_PATH
, RELATIVE_PATH
, BASE_DIRECTORY
, ABSOLUTE_PATH
# Native Conversion
, NATIVE_PATH
, CONVERT
, TO_CMAKE_PATH_LIST
, TO_NATIVE_PATH_LIST
# Hashing
, HASH
]
-
name: cmake_policy
named-args: [GET, SET, PUSH, POP, VERSION]
@@ -1908,6 +2034,8 @@ scripting-commands:
, NO_SOURCE_PERMISSIONS # Since 3.19
, "@ONLY"
, NEWLINE_STYLE
, USE_SOURCE_PERMISSIONS # Since 3.20
, FILE_PERMISSIONS # Since 3.20
]
special-args: [UNIX, DOS, WIN32, LF, CRLF]
-
@@ -2098,6 +2226,19 @@ scripting-commands:
, SIZE
# New sub-options since 3.16
, GET_RUNTIME_DEPENDENCIES
, RESOLVED_DEPENDENCIES_VAR
, UNRESOLVED_DEPENDENCIES_VAR
, EXECUTABLES
, LIBRARIES
, MODULES
, DIRECTORIES
, BUNDLE_EXECUTABLE
, PRE_INCLUDE_REGEXES
, PRE_EXCLUDE_REGEXES
, POST_INCLUDE_REGEXES
, POST_EXCLUDE_REGEXES
, POST_INCLUDE_FILES # Since 3.21
, POST_EXCLUDE_FILES # Since 3.21
# New sub-options since 3.18
, ARCHIVE_CREATE
, FILES
@@ -2112,10 +2253,17 @@ scripting-commands:
, ESCAPE_QUOTES
, "@ONLY"
, NEWLINE_STYLE
, CHMOD # Since 3.19
, CHMOD_RECURSE # Since 3.19
, REAL_PATH # Since 3.19
, BASE_DIRECTORY # Since 3.19
# New sub-options since 3.19
, CHMOD
, CHMOD_RECURSE
, REAL_PATH
, BASE_DIRECTORY
# New sub-options since 3.21
, COPY_FILE
, RESULT
, ONLY_IF_DIFFERENT
, EXPAND_TILDE
, NO_REPLACE
]
special-args: [
UTF-8
@@ -2169,6 +2317,7 @@ scripting-commands:
, PATHS
, PATH_SUFFIXES
, DOC
, NO_CACHE # Since 3.21
, REQUIRED # Since 3.18
, NO_DEFAULT_PATH
, NO_PACKAGE_ROOT_PATH
@@ -2189,6 +2338,7 @@ scripting-commands:
, PATHS
, PATH_SUFFIXES
, DOC
, NO_CACHE # Since 3.21
, REQUIRED # Since 3.18
, NO_DEFAULT_PATH
, NO_PACKAGE_ROOT_PATH
@@ -2595,7 +2745,11 @@ project-commands:
name: aux_source_directory
-
name: build_command
named-args: [CONFIGURATION, TARGET]
named-args: [
CONFIGURATION
, PARALLEL_LEVEL # Since 3.21
, TARGET
]
-
name: create_test_sourcelist
named-args: [EXTRA_INCLUDE, FUNCTION]
@@ -2615,6 +2769,7 @@ project-commands:
, CSharp
, CXX
, CUDA
, HIP # Since 3.21
, ISPC # Since 3.19
, Java
, OBJC # Since 3.16
@@ -2664,6 +2819,7 @@ project-commands:
, EXCLUDE_FROM_ALL
, RENAME
, OPTIONAL
, TYPE # Since 3.20
# Installing Targets
, TARGETS
, EXPORT
@@ -2679,6 +2835,7 @@ project-commands:
, INCLUDES
, NAMELINK_ONLY
, NAMELINK_SKIP
, RUNTIME_DEPENDENCIES # Since 3.21
# Installing Files
, FILES
, PROGRAMS
@@ -2700,6 +2857,17 @@ project-commands:
, FILE
, EXPORT_ANDROID_MK
, EXPORT_LINK_INTERFACE_LIBRARIES
# Installing Imported Runtime Artifacts (since 3.21)
, IMPORTED_RUNTIME_ARTIFACTS
, RUNTIME_DEPENDENCY_SET
# Installing Runtime Dependencies (since 3.21)
, PRE_INCLUDE_REGEXES
, PRE_EXCLUDE_REGEXES
, POST_INCLUDE_REGEXES
, POST_EXCLUDE_REGEXES
, POST_INCLUDE_FILES
, POST_EXCLUDE_FILES
, DIRECTORIES
]
special-args: &valid_permissions [
OWNER_READ
@@ -2740,6 +2908,7 @@ project-commands:
, CSharp
, CXX
, CUDA
, HIP # Since 3.21
, ISPC # Since 3.19
, Java
, OBJC # Since 3.16
@@ -2787,6 +2956,7 @@ project-commands:
, cxx_std_14
, cxx_std_17
, cxx_std_20 # Since 3.12
, cxx_std_23 # Since 3.20
, cxx_aggregate_default_initializers
, cxx_alias_templates
, cxx_alignas
@@ -2848,6 +3018,8 @@ project-commands:
, c_std_90
, c_std_99
, c_std_11
, c_std_17 # Since 3.21
, c_std_23 # Since 3.21
, c_function_prototypes
, c_restrict
, c_static_assert
@@ -2858,13 +3030,21 @@ project-commands:
, cuda_std_14
, cuda_std_17
, cuda_std_20
, cuda_std_23 # Since 3.21
]
-
name: target_compile_options
named-args: &target_compile_options [BEFORE, INTERFACE, PUBLIC, PRIVATE]
-
name: target_include_directories
named-args: [BEFORE, SYSTEM, INTERFACE, PUBLIC, PRIVATE]
named-args: [
AFTER # Since 3.20
, BEFORE
, SYSTEM
, INTERFACE
, PUBLIC
, PRIVATE
]
-
# Since 3.13
name: target_link_directories
@@ -2910,6 +3090,7 @@ project-commands:
, COMPILE_OUTPUT_VARIABLE
, RUN_OUTPUT_VARIABLE
, OUTPUT_VARIABLE
, WORKING_DIRECTORY # Since 3.20
, ARGS
]

View File

@@ -0,0 +1,42 @@
#!/usr/bin/env perl
# SPDX-FileCopyrightText: 2020 Jonathan Poelen <jonathan.poelen@gmail.com>
# SPDX-License-Identifier: MIT
my $file = "";
open(my $input, '<:encoding(UTF-8)', $ARGV[0])
or die "Could not open file '$ARGV[0]': $!";
open(my $output, '>:encoding(UTF-8)', $ARGV[1])
or die "Could not open file '$ARGV[1]': $!";
while (<$input>)
{
$file .= $_;
}
$warning = "\n\n<!-- ***** THIS FILE WAS GENERATED BY A SCRIPT - DO NOT EDIT ***** -->\n";
$first_context = " <context attribute=\"Normal Text\" lineEndContext=\"#stay\" name=\"Normal\">
<RegExpr attribute=\"Comment\" context=\"LineComment\" String=\"--(?:!|(?:-(?=[^-]|\$)))\"/>
<RegExpr attribute=\"Region\" context=\"#stay\" String=\"--\\s*\@\\{\\s*\$\" beginRegion=\"MemberGroup\" />
<RegExpr attribute=\"Region\" context=\"#stay\" String=\"--\\s*\@\\}\\s*\$\" endRegion=\"MemberGroup\" />
</context>";
$file =~ s/\n\s*<context [^\n]*?(?:name="ML_|name="BlockComment").*?<\/context>//gs;
$file =~ s/\n\s*<context [^\n]*?name="Normal".*?<\/context>/\n$first_context/s;
$file =~ s/\n[^\n]*?(?: ml_word|LineContinue)[^\n]+//gs;
$file =~ s/\/\/\//---/gs;
$file =~ s/\/\/!/--!/gs;
$language = $file =~ s/.*?(<language[^>]+?>).*/$1/sr;
$language =~ s/ name="[^"]+/ name="DoxygenLua/s;
$language =~ s/ extensions="[^"]+/ extensions="/s;
$language =~ s/ mimetype="[^"]+/ mimetype="/s;
$language =~ s/ priority="[^"]+"//s;
$version = $language =~ s/.*? version="([^"]+).*/$1/sr;
$version = $version+2;
$language =~ s/ version="[^"]+/ version="$version/s;
$file =~ s/<language[^>]+?>/$warning\n$language/s;
print $output $file;
print $output $warning;

View File

@@ -45,6 +45,7 @@ if ($root == 1)
$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;
$file =~ s/<language([^>]+)*/<language$1 indenter="cstyle"/s;
}
else
{

View File

@@ -0,0 +1,67 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Generate SPDX-Comments syntax file
#
# SPDX-FileCopyrightText: 2020 Alex Turbov <i.zaufi@gmail.com>
# SPDX-License-Identifier: MIT
#
# To install prerequisites:
#
# $ pip install --user click jinja2
#
# To use:
#
# $ ./generate-spdx-syntax.py > ../syntax/spdx-comments.xml
#
import json
import pathlib
import urllib.request
import click
import jinja2
def get_json(url):
with urllib.request.urlopen(url=url) as body:
return json.load(body)
@click.command()
@click.argument('template', type=click.File('r'), default='./spdx-comments.xml.tpl')
def cli(template):
data = {
'licenses': [
*filter(
lambda l: not l['licenseId'].endswith('+')
, get_json(url='https://spdx.org/licenses/licenses.json')['licenses']
)
]
, 'exceptions': [
*filter(
lambda l: not l['licenseExceptionId'].endswith('+')
, get_json(url='https://spdx.org/licenses/exceptions.json')['exceptions']
)
]
}
env = jinja2.Environment(
keep_trailing_newline=True
)
env.block_start_string = '<!--['
env.block_end_string = ']-->'
env.variable_start_string = '<!--{'
env.variable_end_string = '}-->'
env.comment_start_string = '<!--#'
env.comment_end_string = '#-->'
tpl = env.from_string(template.read())
result = tpl.render(data)
print(result.strip(), end=None)
if __name__ == '__main__':
cli()
# TODO Handle execptions and show errors

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
<language
version="4"
kateversion="3.1"
name="SPDX-Comments"
section="Other"
extensions=""
mimetype=""
author="Alex Turbov (i.zaufi@gmail.com)"
license="MIT"
hidden="true"
>
<highlighting>
<list name="tags">
<item>SPDX-License-Identifier:</item>
<item>SPDX-FileContributor:</item>
<item>SPDX-FileCopyrightText:</item>
<item>SPDX-LicenseInfoInFile:</item>
</list>
<list name="operators">
<item>AND</item>
<item>OR</item>
<item>WITH</item>
</list>
<list name="licenses">
<!--[- for license in licenses if not license.isDeprecatedLicenseId ]-->
<item><!--{ license.licenseId }--></item>
<!--[- endfor ]-->
</list>
<list name="deprecated-licenses">
<!--[- for license in licenses if license.isDeprecatedLicenseId ]-->
<item><!--{ license.licenseId }--></item>
<!--[- endfor ]-->
</list>
<list name="exceptions">
<!--[- for exception in exceptions if not exception.isDeprecatedLicenseId ]-->
<item><!--{ exception.licenseExceptionId }--></item>
<!--[- endfor ]-->
</list>
<list name="deprecated-exceptions">
<!--[- for exception in exceptions if exception.isDeprecatedLicenseId ]-->
<item><!--{ exception.licenseExceptionId }--></item>
<!--[- endfor ]-->
</list>
<contexts>
<context name="Normal" attribute="SPDX Tag" lineEndContext="#pop">
<WordDetect String="SPDX-License-Identifier:" attribute="SPDX Tag" context="license-expression" />
<keyword String="tags" attribute="SPDX Tag" />
</context>
<context name="license-expression" attribute="SPDX Value" lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop">
<DetectSpaces/>
<DetectChar char="(" context="#stay" attribute="SPDX License Expression Operator" />
<DetectChar char=")" context="#stay" attribute="SPDX License Expression Operator" />
<DetectChar char="+" context="#stay" attribute="SPDX License Expression Operator" />
<keyword String="licenses" context="#stay" attribute="SPDX License" />
<keyword String="deprecated-licenses" context="#stay" attribute="SPDX Deprecated License" />
<keyword String="exceptions" context="#stay" attribute="SPDX License Exception" />
<keyword String="deprecated-exceptions" context="#stay" attribute="SPDX Deprecated License Exception" />
<keyword String="operators" context="#stay" attribute="SPDX License Expression Operator" />
<RegExpr attribute="SPDX License" context="#stay" String="\bLicenseRef-[^\s]+" />
</context>
</contexts>
<itemDatas>
<itemData name="SPDX Tag" defStyleNum="dsAnnotation" italic="true" spellChecking="false" />
<itemData name="SPDX Value" defStyleNum="dsAnnotation" italic="true" spellChecking="false" />
<itemData name="SPDX License" defStyleNum="dsAnnotation" italic="true" spellChecking="false" />
<itemData name="SPDX License Exception" defStyleNum="dsAnnotation" italic="true" spellChecking="false" />
<itemData name="SPDX Deprecated License" defStyleNum="dsAnnotation" italic="true" spellChecking="false" />
<itemData name="SPDX Deprecated License Exception" defStyleNum="dsAnnotation" italic="true" spellChecking="false" />
<itemData name="SPDX License Expression Operator" defStyleNum="dsOperator" italic="true" spellChecking="false" />
</itemDatas>
</highlighting>
<general>
<keywords casesensitive="1" weakDeliminator=":-." />
</general>
</language>
<!-- kate: indent-width 2; -->

View File

@@ -5,7 +5,7 @@
<!ENTITY funcname "([^&_fragpathseps;}=#$]|[+!@](?!\())([^&_fragpathseps;}=$]*+([+!@](?!\())?+)*+">
<!ENTITY varname "[A-Za-z_][A-Za-z0-9_]*">
<!ENTITY eos "(?=$|[ &tab;])"> <!-- eol or space following -->
<!ENTITY eoexpr "(?=$|[ &tab;&lt;>|&amp;;])">
<!ENTITY eoexpr "(?=$|[ &tab;&lt;>|&amp;;)])">
<!ENTITY substseps "${'&quot;`\\">
<!ENTITY symbolseps "&lt;>|&amp;;()"> <!-- see man bash -->
@@ -18,6 +18,13 @@
<!ENTITY opt "(?:[^&_fragpathseps;=/]*+&_fragpathnosep;)*+">
<!ENTITY pathpart "(?:~|\.\.?|&fragpath;)(?:/&path;|(?=[*?]|[+!@]\(|&fragpath;(?:[/*?]|[+!@]\()))|(?:~|\.\.?)(?=[&wordseps;]|$)">
<!ENTITY _fragpathseps_alt "*?+!@&substseps;}">
<!ENTITY _fragpathnosep_alt "(?:[+!@](?!\()|\\.)?+">
<!ENTITY path_alt "(?:[^&_fragpathseps_alt;]*+&_fragpathnosep_alt;)*+">
<!ENTITY fragpath_alt "(?:[^&_fragpathseps_alt;/]*+&_fragpathnosep_alt;)*+">
<!ENTITY opt_alt "(?:[^&_fragpathseps_alt;=/]*+&_fragpathnosep_alt;)*+">
<!ENTITY pathpart_alt "(?:~|\.\.?|&fragpath_alt;)(?:/&path_alt;|(?=[*?]|[+!@]\(|&fragpath_alt;(?:[/*?]|[+!@]\()))|(?:~|\.\.?)(?=\}|$)">
<!ENTITY _braceexpansion_spe " &tab;&lt;>|&amp;;{}\\`'&quot;$">
<!ENTITY _brace_noexpansion "\{[^&_braceexpansion_spe;,]*+\}">
<!ENTITY _braceexpansion_var "\$(?:\{[^\[\]&_braceexpansion_spe;]*+(?:\[[*@a-zA-Z0-9]\])\})?">
@@ -28,9 +35,11 @@
<!ENTITY braceexpansion "{&_braceexpansion;">
<!ENTITY heredocq "(?|&quot;([^&quot;]+)&quot;|'([^']+)'|\\(.[^&wordseps;&substseps;]*))">
<!ENTITY arithmetic_as_subshell "\(((?:[^`'&quot;()$]++|\$\{[^`'&quot;(){}$]+\}|\$(?=[^{`'&quot;()])|`[^`]*+`|\((?1)(?:[)]|(?=['&quot;])))++)(?:[)](?=$|[^)])|[&quot;'])">
]>
<language name="Bash" version="27" kateversion="5.79" section="Scripts" extensions="*.sh;*.bash;*.ebuild;*.eclass;*.nix;.bashrc;.bash_profile;.bash_login;.profile;PKGBUILD;APKBUILD" mimetype="application/x-shellscript" casesensitive="1" author="Wilbert Berendsen (wilbert@kde.nl)" license="LGPL">
<language name="Bash" version="30" kateversion="5.79" section="Scripts" extensions="*.sh;*.bash;*.ebuild;*.eclass;*.nix;.bashrc;.bash_profile;.bash_login;.profile;PKGBUILD;APKBUILD" mimetype="application/x-shellscript" casesensitive="1" author="Wilbert Berendsen (wilbert@kde.nl)" license="LGPL">
<!-- (c) 2004 by Wilbert Berendsen (wilbert@kde.nl)
Changes by Matthew Woehlke (mw_triad@users.sourceforge.net)
@@ -40,6 +49,7 @@
<highlighting>
<list name="keywords">
<item>break</item>
<item>case</item>
<item>continue</item>
<item>do</item>
@@ -66,7 +76,6 @@
<item>alias</item>
<item>bg</item>
<item>bind</item>
<item>break</item>
<item>builtin</item>
<item>cd</item>
<item>caller</item>
@@ -458,7 +467,7 @@
<DetectSpaces attribute="Normal Text" context="#stay"/>
<DetectChar attribute="Comment" context="Comment" char="#"/>
<!-- start expression in double parentheses -->
<Detect2Chars attribute="Keyword" context="ExprDblParen" char="(" char1="(" beginRegion="expression"/>
<Detect2Chars context="ExprDblParenOrSubShell" char="(" char1="(" lookAhead="1"/>
<!-- start a subshell -->
<DetectChar attribute="Keyword" context="SubShell" char="(" beginRegion="subshell"/>
<!-- start expression in single/double brackets -->
@@ -554,8 +563,8 @@
</context>
<context attribute="Command" lineEndContext="#pop#pop" name="DispatchSubstVariables">
<Detect2Chars attribute="Parameter Expansion" context="#pop!VarBraceStart" char="$" char1="{"/>
<StringDetect attribute="Parameter Expansion" context="#pop!ExprDblParenSubst" String="$((" beginRegion="expression"/>
<Detect2Chars attribute="Parameter Expansion" context="#pop!SubstCommand" char="$" char1="("/>
<StringDetect context="#pop!ExprDblParenSubstOrSubstCommand" String="$((" lookAhead="1"/>
<Detect2Chars attribute="Parameter Expansion" context="#pop!SubstCommand" char="$" char1="(" beginRegion="subshell"/>
</context>
<context attribute="Command" lineEndContext="#pop#pop" name="DispatchStringVariables">
<Detect2Chars attribute="String SingleQ" context="#pop!StringEsc" char="$" char1="'"/>
@@ -695,27 +704,30 @@
</context>
<context attribute="Path" lineEndContext="#stay" name="ExtGlobAndPop">
<DetectChar attribute="Glob" context="#pop!PathThenPop" char=")"/>
<IncludeRules context="FindWord"/>
<IncludeRules context="IncExtGlob"/>
</context>
<context attribute="Path" lineEndContext="#stay" name="RecursiveExtGlob">
<DetectChar attribute="Glob" context="#pop" char=")"/>
<IncludeRules context="IncExtGlob"/>
</context>
<context attribute="Path" lineEndContext="#stay" name="IncExtGlob">
<context attribute="Path" lineEndContext="#stay" name="FindExtGlob">
<Detect2Chars attribute="Glob" context="RecursiveExtGlob" char="?" char1="("/>
<Detect2Chars attribute="Glob" context="RecursiveExtGlob" char="*" char1="("/>
<Detect2Chars attribute="Glob" context="RecursiveExtGlob" char="+" char1="("/>
<Detect2Chars attribute="Glob" context="RecursiveExtGlob" char="@" char1="("/>
<Detect2Chars attribute="Glob" context="RecursiveExtGlob" char="!" char1="("/>
<AnyChar attribute="Glob" context="#stay" String="|?*"/>
</context>
<context attribute="Path" lineEndContext="#stay" name="RecursiveExtGlob">
<DetectChar attribute="Glob" context="#pop" char=")"/>
<IncludeRules context="FindWord"/>
<IncludeRules context="IncExtGlob"/>
</context>
<context attribute="Path" lineEndContext="#stay" name="IncExtGlob">
<IncludeRules context="FindExtGlob"/>
<DetectChar context="PathMaybeBraceExpansion" char="{" lookAhead="1"/>
</context>
<context attribute="Path" lineEndContext="#pop#pop" name="PathThenPop">
<AnyChar context="#pop#pop" String="&wordseps;`" lookAhead="1"/>
<IncludeRules context="FindWord"/>
<IncludeRules context="FindExtGlobAndPop"/>
<AnyChar attribute="Glob" context="#stay" String="?*"/>
<IncludeRules context="FindExtGlob"/>
<DetectChar context="PathMaybeBraceExpansion" char="{" lookAhead="1"/>
<RegExpr attribute="Path" context="#stay" String="&path;"/>
</context>
@@ -724,6 +736,47 @@
<DetectChar attribute="Path" context="#pop" char="{"/>
</context>
<!-- FindPathThenPopInAlternateValue consumes path in ${xx:here}-->
<context attribute="Normal Text" lineEndContext="#pop" name="FindPathThenPopInAlternateValue">
<IncludeRules context="FindExtGlobAndPopInAlternateValue"/>
<AnyChar attribute="Glob" context="PathThenPopInAlternateValue" String="?*"/>
<RegExpr attribute="Path" context="PathThenPopInAlternateValue" String="&pathpart_alt;"/>
</context>
<context attribute="Path" lineEndContext="#stay" name="FindExtGlobAndPopInAlternateValue">
<Detect2Chars attribute="Glob" context="ExtGlobAndPopInAlternateValue" char="?" char1="("/>
<Detect2Chars attribute="Glob" context="ExtGlobAndPopInAlternateValue" char="*" char1="("/>
<Detect2Chars attribute="Glob" context="ExtGlobAndPopInAlternateValue" char="+" char1="("/>
<Detect2Chars attribute="Glob" context="ExtGlobAndPopInAlternateValue" char="@" char1="("/>
<Detect2Chars attribute="Glob" context="ExtGlobAndPopInAlternateValue" char="!" char1="("/>
</context>
<context attribute="Path" lineEndContext="#stay" name="FindExtGlobInAlternateValue">
<Detect2Chars attribute="Glob" context="RecursiveExtGlobInAlternateValue" char="?" char1="("/>
<Detect2Chars attribute="Glob" context="RecursiveExtGlobInAlternateValue" char="*" char1="("/>
<Detect2Chars attribute="Glob" context="RecursiveExtGlobInAlternateValue" char="+" char1="("/>
<Detect2Chars attribute="Glob" context="RecursiveExtGlobInAlternateValue" char="@" char1="("/>
<Detect2Chars attribute="Glob" context="RecursiveExtGlobInAlternateValue" char="!" char1="("/>
<AnyChar attribute="Glob" context="#stay" String="|?*"/>
</context>
<context attribute="Path" lineEndContext="#stay" name="RecursiveExtGlobInAlternateValue">
<DetectChar attribute="Glob" context="#pop" char=")"/>
<DetectChar context="#pop" char="}" lookAhead="1"/>
<IncludeRules context="FindWord"/>
<IncludeRules context="FindExtGlobInAlternateValue"/>
</context>
<context attribute="Path" lineEndContext="#stay" name="ExtGlobAndPopInAlternateValue">
<DetectChar attribute="Glob" context="#pop!PathThenPopInAlternateValue" char=")"/>
<DetectChar attribute="Error" context="#pop#pop" char="}"/>
<IncludeRules context="FindWord"/>
<IncludeRules context="FindExtGlobInAlternateValue"/>
</context>
<context attribute="Path" lineEndContext="#pop#pop" name="PathThenPopInAlternateValue">
<DetectChar attribute="Parameter Expansion" context="#pop#pop" char="}"/>
<IncludeRules context="FindWord"/>
<IncludeRules context="FindExtGlobAndPopInAlternateValue"/>
<AnyChar attribute="Glob" context="#stay" String="?*"/>
<RegExpr attribute="Path" context="#stay" String="&path_alt;"/>
</context>
<context attribute="Pattern" lineEndContext="#stay" name="FindPattern">
<Detect2Chars attribute="Glob" context="ExtPattern" char="?" char1="("/>
<Detect2Chars attribute="Glob" context="ExtPattern" char="*" char1="("/>
@@ -1038,7 +1091,7 @@
<!-- SubstCommand is called after a $( is encountered -->
<context attribute="Normal Text" lineEndContext="#stay" name="SubstCommand" fallthroughContext="Command">
<DetectChar attribute="Parameter Expansion" context="#pop" char=")"/>
<DetectChar attribute="Parameter Expansion" context="#pop" char=")" endRegion="subshell"/>
<IncludeRules context="Start"/>
</context>
@@ -1084,7 +1137,7 @@
<Detect2Chars attribute="Parameter Expansion Operator" context="#pop!AlternatePatternValue" char="," char1=","/>
<DetectChar attribute="Parameter Expansion Operator" context="#pop!VarSub" char=":"/>
<DetectChar attribute="Parameter Expansion Operator" context="#pop!VarSubst" char="/"/>
<AnyChar attribute="Parameter Expansion Operator" context="#pop!AlternateValue" String="%#"/>
<AnyChar attribute="Parameter Expansion Operator" context="#pop!AlternateValue" String="-+=?#%"/>
<AnyChar attribute="Parameter Expansion Operator" context="#pop!AlternatePatternValue" String="^,"/>
<DetectChar attribute="Parameter Expansion Operator" context="#pop!VarTransformation" char="@"/>
</context>
@@ -1109,7 +1162,7 @@
<context attribute="Normal Text" lineEndContext="#stay" name="AlternateValue">
<DetectChar attribute="Parameter Expansion" context="#pop" char="}"/>
<IncludeRules context="FindWord"/>
<IncludeRules context="FindPattern"/>
<IncludeRules context="FindPathThenPopInAlternateValue"/>
</context>
<!-- called as soon as ${xxx^ are ${xxx, are encoutered -->
@@ -1125,7 +1178,7 @@
</context>
<context attribute="Pattern" lineEndContext="#stay" name="VarSubstPat">
<DetectChar attribute="Parameter Expansion Operator" context="#pop!AlternateValue" char="/"/>
<IncludeRules context="AlternateValue"/>
<IncludeRules context="AlternatePatternValue"/>
</context>
<!-- called as soon as ${xxx@ is encoutered -->
@@ -1164,19 +1217,26 @@
<!-- ====== These are the contexts that can be branched to ======= -->
<context attribute="Normal Text" lineEndContext="#stay" name="ExprDblParenOrSubShell">
<RegExpr attribute="Keyword" context="#pop!SubShell" String="\((?=&arithmetic_as_subshell;)|" beginRegion="subshell"/>
<Detect2Chars attribute="Keyword" context="#pop!ExprDblParen" char="(" char1="(" beginRegion="expression"/>
</context>
<!-- ExprDblParen consumes an expression started in command mode till )) -->
<context attribute="Normal Text" lineEndContext="#stay" name="ExprDblParen">
<DetectSpaces attribute="Normal Text" context="#stay"/>
<Detect2Chars attribute="Keyword" context="#pop" char=")" char1=")" endRegion="expression"/>
<IncludeRules context="FindExprDblParen"/>
<!-- ((cmd
) # jump to SubShell context -->
<DetectChar attribute="Keyword" context="#pop!SubShell" char=")" endRegion="expression" beginRegion="subshell"/>
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="FindExprDblParen">
<Detect2Chars attribute="Control" context="#stay" char="&amp;" char1="&amp;"/>
<Detect2Chars attribute="Control" context="#stay" char="|" char1="|"/>
<AnyChar attribute="Operator" context="#stay" String="+-!~*/%&lt;>=&amp;^|?:"/>
<AnyChar context="Number" String="0123456789" lookAhead="1"/>
<DetectChar attribute="Control" context="#stay" char=","/>
<DetectChar attribute="Normal Text" context="ExprSubDblParen" char="("/>
<AnyChar context="Number" String="0123456789" lookAhead="1"/>
<DetectChar attribute="Parameter Expansion Operator" context="Subscript" char="["/>
<IncludeRules context="FindWord"/>
<DetectChar attribute="Error" context="#stay" char="#"/>
@@ -1184,8 +1244,9 @@
<DetectIdentifier attribute="Variable" context="#stay"/>
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="ExprSubDblParen">
<DetectSpaces attribute="Normal Text" context="#stay"/>
<DetectChar attribute="Normal Text" context="#pop" char=")"/>
<IncludeRules context="ExprDblParen"/>
<IncludeRules context="FindExprDblParen"/>
</context>
<context attribute="Normal Text" lineEndContext="#pop" name="MaybeArithmeticBrace">
<IncludeRules context="DispatchBraceExpansion"/>
@@ -1216,11 +1277,18 @@
<AnyChar attribute="Error" context="#stay" String="8901234567"/>
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="ExprDblParenSubstOrSubstCommand">
<RegExpr attribute="Parameter Expansion" context="#pop!SubstCommand" String="\$\((?=&arithmetic_as_subshell;)|" beginRegion="subshell"/>
<StringDetect attribute="Parameter Expansion" context="#pop!ExprDblParenSubst" String="$((" beginRegion="expression"/>
</context>
<!-- ExprDblParenSubst like ExprDblParen but matches )) as Variable -->
<context attribute="Normal Text" lineEndContext="#stay" name="ExprDblParenSubst">
<DetectSpaces attribute="Normal Text" context="#stay"/>
<Detect2Chars attribute="Variable" context="#pop" char=")" char1=")" endRegion="expression"/>
<IncludeRules context="FindExprDblParen"/>
<!-- $((cmd
) # jump to SubstCommand context -->
<DetectChar attribute="Parameter Expansion" context="#pop!SubstCommand" char=")" endRegion="expression" beginRegion="subshell"/>
</context>
<!-- ExprBracket consumes an expression till ] -->
@@ -1305,7 +1373,7 @@
</context>
<context attribute="Normal Text" lineEndContext="#pop" name="ExprDblBracketValue">
<Detect2Chars attribute="Keyword" context="ExprDblParen" char="(" char1="(" beginRegion="expression"/>
<Detect2Chars context="ExprDblBracketDblParentOrSubValue" char="(" char1="(" lookAhead="1"/>
<DetectChar context="ExprDblBracketSubValue" char="(" lookAhead="1"/>
<DetectChar attribute="Operator" context="#pop#pop" char=")"/>
<Detect2Chars attribute="Control" context="#pop#pop!ExprDblBracket" char="&amp;" char1="&amp;"/>
@@ -1321,6 +1389,18 @@
<DetectChar attribute="Operator" context="ExprDblBracketNot" char="("/>
<Detect2Chars context="#pop#pop" char="]" char1="]" lookAhead="1"/>
</context>
<context attribute="Normal Text" lineEndContext="#pop" name="ExprDblBracketDblParentOrSubValue">
<RegExpr context="#pop!ExprDblBracketSubValue" String="\((?=&arithmetic_as_subshell;)|" lookAhead="1"/>
<Detect2Chars attribute="Keyword" context="#pop!ExprDblBracketExprDblParen" char="(" char1="(" beginRegion="expression"/>
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="ExprDblBracketExprDblParen">
<DetectSpaces attribute="Normal Text" context="#stay"/>
<Detect2Chars attribute="Keyword" context="#pop" char=")" char1=")" endRegion="expression"/>
<IncludeRules context="FindExprDblParen"/>
<!-- ((cmd
) # jump to ExprDblBracketValue context -->
<DetectChar attribute="Operator" context="ExprDblBracketValue" char=")" endRegion="expression" beginRegion="subshell"/>
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="ExprDblBracketParam2" fallthroughContext="ExprDblBracketValue">
<DetectSpaces attribute="Normal Text" context="#pop!ExprDblBracketParam3"/>

File diff suppressed because one or more lines are too long

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd"
[
<!ENTITY wordsep "(?:[][,?;()]|\.$|\.?\s)"> <!-- things that end a TagWord -->
<!ENTITY wordsep "(?:[][,?;()]|\.$|\.?\s|$)"> <!-- things that end a TagWord -->
<!ENTITY sl_word ".*?(?=&wordsep;)">
<!ENTITY ml_word ".*?(?=&wordsep;|\*/)">
]>
<language name="Doxygen"
version="13"
version="14"
kateversion="5.0"
section="Markup"
extensions="*.dox;*.doxygen"

View File

@@ -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" mimetype="" version="8" kateversion="5.0" author="Jan Janssen (medhefgo@web.de)" license="LGPL">
<language name="INI Files" section="Configuration" extensions="*.ini;*.pls;*.kcfgc" mimetype="" version="10" kateversion="5.0" author="Jan Janssen (medhefgo@web.de)" license="LGPL">
<highlighting>
<list name="keywords">
@@ -34,15 +34,26 @@
<contexts>
<context name="ini" attribute="Normal Text" lineEndContext="#stay">
<RangeDetect attribute="Section" context="#stay" char="[" char1="]" beginRegion="Section" endRegion="Section" />
<RangeDetect attribute="Section" context="#stay" char="[" char1="]" beginRegion="Section" endRegion="Section" />
<DetectChar attribute="Assignment" context="Value" char="=" />
<AnyChar String=";#" attribute="Comment" context="Comment" firstNonSpace="true" />
<DetectIdentifier />
<DetectSpaces />
</context>
<context name="Value" attribute="Value" lineEndContext="#pop" >
<context name="Value" attribute="Value" lineEndContext="#pop" fallthrough="1" fallthroughContext="#pop!NormalValue">
<RegExpr context="#pop!SpecialValue" String="\s*((-?(\d+(\.\d*)?|\.d+)(e\d+)?|On|Off|Defaults?|Localhost|Null|True|False|Yes|No|Normal)\s*$|~?(E_ALL|E_ERROR|E_WARNING|E_PARSE|E_NOTICE|E_STRICT|E_CORE_ERROR|E_CORE_WARNING|E_COMPILE_ERROR|E_COMPILE_WARNING|E_USER_ERROR|E_USER_WARNING|E_USER_NOTICE)\b)" lookAhead="1" insensitive="1"/>
</context>
<context name="SpecialValue" attribute="Value" lineEndContext="#pop">
<Float attribute="Float" />
<Int attribute="Int" />
<keyword attribute="Keyword" String="keywords" />
<keyword attribute="Keyword" String="keywords"/>
<DetectChar attribute="Int" char="-" />
<DetectSpaces />
</context>
<context name="NormalValue" attribute="Value" lineEndContext="#pop">
</context>
<context name="Comment" attribute="Comment" lineEndContext="#pop">

View File

@@ -7,7 +7,7 @@
<!ENTITY float "(\b&int;(\.((&int;&exp;?+|&exp;)[fFdD]?\b|[fFdD]\b)?|&exp;[fFdD]?\b|[fFdD]\b)|\.&int;&exp;?[fFdD]?\b)">
<!ENTITY hexfloat "\b0[xX](&hex;\.?+&hex;?+|\.&hex;?)[pP][-+]?&int;[fFdD]?\b">
]>
<language name="Java" version="9" kateversion="5.62" section="Sources" extensions="*.java" mimetype="text/x-java" license="LGPL" author="Alfredo Luiz Foltran Fialho (alfoltran@ig.com.br)">
<language name="Java" version="10" kateversion="5.62" section="Sources" extensions="*.java" mimetype="text/x-java" license="LGPL" author="Alfredo Luiz Foltran Fialho (alfoltran@ig.com.br)">
<highlighting>
<list name="java15">
<item>ACTIVE</item>
@@ -3732,6 +3732,7 @@
<item>volatile</item>
</list>
<list name="control flow">
<item>assert</item>
<item>break</item>
<item>case</item>
<item>catch</item>
@@ -3760,6 +3761,7 @@
<item>long</item>
<item>short</item>
<item>static</item>
<item>var</item>
<item>void</item>
</list>
<contexts>

View File

@@ -90,7 +90,7 @@
<!ENTITY checkbox "\[[ x]\](?=\s)">
]>
<language name="Markdown" version="17" kateversion="5.79" section="Markup" extensions="*.md;*.mmd;*.markdown" priority="15" author="Darrin Yeager, Claes Holmerson" license="GPL,BSD">
<language name="Markdown" version="19" kateversion="5.79" section="Markup" extensions="*.md;*.mmd;*.markdown" priority="15" author="Darrin Yeager, Claes Holmerson" license="GPL,BSD">
<highlighting>
<contexts>
<!-- Start of the Markdown document: find metadata or code block -->
@@ -149,14 +149,33 @@
</context>
<context name="find-header" attribute="Normal Text" lineEndContext="#pop">
<RegExpr attribute="Header H1" context="#pop" String="^#\s.*[#]?$" column="0"/>
<RegExpr attribute="Header H2" context="#pop" String="^##\s.*[#]?$" column="0"/>
<RegExpr attribute="Header H3" context="#pop" String="^###\s.*[#]?$" column="0"/>
<RegExpr attribute="Header H4" context="#pop" String="^####\s.*[#]?$" column="0"/>
<RegExpr attribute="Header H5" context="#pop" String="^#####\s.*[#]?$" column="0"/>
<RegExpr attribute="Header H6" context="#pop" String="^######\s.*[#]?$" column="0"/>
<!-- TODO: Replace "(?=.$)" in the regexes with just "$" when close-H#-region are removed -->
<RegExpr attribute="Header H1" context="#pop!close-H2-region" String="^#\s.*[#]?(?=.$)" column="0" endRegion="H1" beginRegion="H1"/>
<RegExpr attribute="Header H2" context="#pop!close-H3-region" String="^##\s.*[#]?(?=.$)" column="0" endRegion="H2" beginRegion="H2"/>
<RegExpr attribute="Header H3" context="#pop!close-H4-region" String="^###\s.*[#]?(?=.$)" column="0" endRegion="H3" beginRegion="H3"/>
<RegExpr attribute="Header H4" context="#pop!close-H5-region" String="^####\s.*[#]?(?=.$)" column="0" endRegion="H4" beginRegion="H4"/>
<RegExpr attribute="Header H5" context="#pop!close-H6-region" String="^#####\s.*[#]?(?=.$)" column="0" endRegion="H5" beginRegion="H5"/>
<RegExpr attribute="Header H6" context="#pop" String="^######\s.*[#]?$" column="0" endRegion="H6" beginRegion="H6"/>
<DetectChar attribute="Normal Text" context="#pop" char="#"/>
</context>
<!-- BUG: 441278 sub-headers should be closed when their parent header is closed (e.g. in h1 h2 h3 h1, h1-h3 should all be closed at the 2nd h1) -->
<!-- TODO: Port to a less hacky version (maybe a new attribute for declaring multiple endRegions) -->
<context name="close-H2-region" attribute="Header H2" lineEndContext="#pop!close-H3-region" fallthroughContext="#pop!close-H3-region">
<RegExpr attribute="Header H2" context="#pop!close-H3-region" String="." lookAhead="true" endRegion="H2"/>
</context>
<context name="close-H3-region" attribute="Header H3" lineEndContext="#pop!close-H4-region" fallthroughContext="#pop!close-H4-region">
<RegExpr attribute="Header H3" context="#pop!close-H4-region" String="." lookAhead="true" endRegion="H3"/>
</context>
<context name="close-H4-region" attribute="Header H4" lineEndContext="#pop!close-H5-region" fallthroughContext="#pop!close-H5-region">
<RegExpr attribute="Header H4" context="#pop!close-H5-region" String="." lookAhead="true" endRegion="H4"/>
</context>
<context name="close-H5-region" attribute="Header H5" lineEndContext="#pop!close-H6-region" fallthroughContext="#pop!close-H6-region">
<RegExpr attribute="Header H5" context="#pop!close-H6-region" String="." lookAhead="true" endRegion="H5"/>
</context>
<context name="close-H6-region" attribute="Header H6" lineEndContext="#pop" fallthroughContext="#pop">
<RegExpr attribute="Header H6" context="#pop" String="." endRegion="H6"/>
</context>
<context name="find-strong-normal" attribute="Normal Text" lineEndContext="#pop">
<RegExpr attribute="Strong-Emphasis Text" context="#pop" minimal="true" String="&strongemphasisregex_ast_und;|&strongemphasisregex_ast_und2;"/>
<RegExpr attribute="Strong Text" context="#pop" minimal="true" String="&strongregex_ast;"/>

View File

@@ -39,7 +39,7 @@
Enhance tr/// and y/// support.
-->
<language name="Perl" version="17" kateversion="5.0" section="Scripts" extensions="*.pl;*.PL;*.pm" mimetype="application/x-perl;text/x-perl" priority="5" author="Anders Lund (anders@alweb.dk)" license="LGPLv2">
<language name="Perl" version="18" kateversion="5.0" section="Scripts" extensions="*.pl;*.PL;*.pm" mimetype="application/x-perl;text/x-perl" priority="5" author="Anders Lund (anders@alweb.dk)" license="LGPLv2">
<highlighting>
<list name="keywords">
<item>if</item>
@@ -92,7 +92,7 @@
<item>+</item>
<item>-</item>
<item>*</item>
<!-- <item>/</item>//-->
<!-- <item>/</item>//-->
<item>%</item>
<item>||</item>
<item>//</item>
@@ -420,7 +420,8 @@
<DetectChar attribute="Operator" context="quote_word_paren" char="(" beginRegion="Wordlist" />
<DetectChar attribute="Operator" context="quote_word_brace" char="{" beginRegion="Wordlist" />
<DetectChar attribute="Operator" context="quote_word_bracket" char="[" beginRegion="Wordlist" />
<RegExpr attribute="Operator" context="quote_word" String="([^a-zA-Z0-9_\s[\]{}()])" beginRegion="Wordlist" />
<DetectChar attribute="Operator" context="quote_word_angular" char="&lt;" beginRegion="Wordlist" />
<RegExpr attribute="Operator" context="quote_word" String="([^a-zA-Z0-9_\s[\]{}()\&lt;&gt;])" beginRegion="Wordlist" />
<RegExpr attribute="Comment" context="#stay" String="\s+#.*" /><!-- q[qwx] # == comment, look for the delim on the next line -->
</context>
@@ -756,6 +757,12 @@
<Detect2Chars attribute="Normal Text" context="#stay" char="\" char1="]" />
<DetectChar attribute="Operator" context="#pop#pop#pop" char="]" endRegion="Wordlist" />
</context>
<context name="quote_word_angular" attribute="Normal Text" lineEndContext="#stay">
<DetectSpaces />
<DetectIdentifier />
<Detect2Chars attribute="Normal Text" context="#stay" char="\" char1="&gt;" />
<DetectChar attribute="Operator" context="#pop#pop#pop" char="&gt;" endRegion="Wordlist" />
</context>
<!-- ====== Here Documents ====== -->
<context name="find_here_document" attribute="Normal Text" lineEndContext="#pop" >

View File

@@ -33,6 +33,10 @@
type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"
-->
<!ENTITY strsubstitution_py3 "\{(?:(?:[a-zA-Z0-9_]+|[0-9]+)(?:\.[a-zA-Z0-9_]+|\[[^ \]]+\])*)?(?:![rs])?(?::(?:[^}]?[&lt;&gt;=^])?[ +-]?#?0?[0-9]*(?:\.[0-9]+)?[bcdeEfFgGnosxX&#37;]?)?\}">
<!ENTITY rawString "(?:ru|u?r|)(?:'(?:[^']++|\\')*+'|&quot;(?:[^&quot;]++|\\&quot;)*+&quot;)">
<!ENTITY formatString "(?:r?f|fr?)(?:'(?:[^'{]++|\\'|\{\{|\{[^}]++\})*+'|&quot;(?:[^&quot;]++|\\&quot;|\{\{|\{[^}]*+\})*+&quot;)">
<!ENTITY string "&rawString;|&formatString;">
]>
<!-- Python syntax highlightning v0.9 by Per Wigren -->
<!-- Python syntax highlighting v1.9 by Michael Bueker (improved keyword differentiation) -->
@@ -48,7 +52,7 @@
<!-- 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="14" style="python" indenter="python" kateversion="5.0" section="Scripts" extensions="*.py;*.pyw;SConstruct;SConscript;*.FCMacro" mimetype="application/x-python;text/x-python;text/x-python3" casesensitive="1" author="Michael Bueker" license="">
<language name="Python" version="22" style="python" indenter="python" kateversion="5.0" section="Scripts" extensions="*.py;*.pyw;SConstruct;SConscript;*.FCMacro" mimetype="application/x-python;text/x-python;text/x-python3" casesensitive="1" author="Michael Bueker" license="">
<highlighting>
<list name="import">
<item>import</item>
@@ -86,10 +90,21 @@
<item>try</item>
<item>while</item>
<item>with</item>
<item>yield</item>
<item>async</item>
<item>await</item>
</list>
<list name="flow_yield">
<item>yield</item>
<!--
"yield from" added here as a keyword for autocompletion. The actual handling
is in context="yield" so that we won't need to add space as a weakDeliminator.
-->
<item>yield from</item>
</list>
<list name="patternmatching">
<item>match</item>
<item>case</item>
</list>
<list name="builtinfuncs">
<item>__import__</item>
<item>abs</item>
@@ -366,89 +381,137 @@
</list>
<contexts>
<context name="Normal" attribute="Normal Text" lineEndContext="#stay">
<DetectSpaces attribute="Normal Text"/>
<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="Flow Control Keyword" String="flow_yield" context="yield"/>
<keyword attribute="Flow Control Keyword" String="patternmatching" context="Pattern Matching" lookAhead="1" firstNonSpace="1"/>
<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"/>
<!-- Complex: 1j ; 1.1j ; 1.j ; .1j ; 1e3j ; 1.1e3j ; 1.e3j ; .1e3j -->
<RegExpr attribute="Complex" String="(?:&beforeDigit;&digitPart;(?:\.(?:&digitPart;)?)?|&beforePointFloat;\.&digitPart;)(?:[eE][\+\-]?&digitPart;)?[jJ]\b" context="#stay"/>
<!-- Hexadecimal: 0xA1, Binary: 0b01, Octal: 0o71 -->
<RegExpr attribute="Hex" String="&beforeDigit;0[xX](?:_?[\da-fA-F])+\b" context="#stay"/>
<RegExpr attribute="Binary" String="&beforeDigit;0[bB](?:_?[01])+\b" context="#stay"/>
<RegExpr attribute="Octal" String="&beforeDigit;0[oO](?:_?[0-7])+\b" context="#stay"/>
<!-- Float: 1.1 ; 1. ; .1 ; 1e3 ; 1.1e3 ; 1.e3 ; .1e3 -->
<RegExpr attribute="Float" String="(?:&beforeDigit;&digitPart;(?:\.(?:&digitPart;)?)?|&beforePointFloat;\.&digitPart;)[eE][\+\-]?&digitPart;\b|(?:&beforeDigit;&digitPart;\.(?:&digitPart;\b)?|&beforePointFloat;\.&digitPart;\b)" context="#stay"/>
<!-- Decimal: 123 ; 000 -->
<RegExpr attribute="Int" String="&beforeDigit;(?:[1-9](?:_?\d)*|0(?:_?0)*)[lL]?\b" 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="Number" />
<IncludeRules context="CommentVariants" />
<IncludeRules context="StringVariants" />
<DetectIdentifier attribute="Normal Text"/>
<RegExpr attribute="Decorator" String="@[_a-zA-Z[:^ascii:]][\._a-zA-Z0-9[:^ascii:]]*" firstNonSpace="true"/>
<AnyChar attribute="Operator" String="+*/%\|=;\!&lt;&gt;!^&amp;~-@" context="#stay"/>
<AnyChar attribute="Operator" String="+*/%\|=;&lt;&gt;!^&amp;~-@" context="#stay"/>
<Int attribute="Error"/>
</context>
<!-- https://docs.python.org/2/reference/lexical_analysis.html#integer-and-long-integer-literals -->
<!-- https://docs.python.org/3/reference/lexical_analysis.html#integer-literals -->
<context name="Number" attribute="Normal Text" lineEndContext="#pop">
<!-- fast path -->
<RegExpr String="&beforeDigit;[0-9]|&beforePointFloat;\.[0-9]" context="AssumeNumber" lookAhead="1"/>
</context>
<context name="AssumeNumber" attribute="Normal Text" lineEndContext="#pop">
<!-- Complex: 1j ; 1.1j ; 1.j ; .1j ; 1e3j ; 1.1e3j ; 1.e3j ; .1e3j -->
<RegExpr attribute="Complex" String="(?:&digitPart;(?:\.(?:&digitPart;)?)?|&beforePointFloat;\.&digitPart;)(?:[eE][\+\-]?&digitPart;)?[jJ]" context="CheckSuffixError"/>
<!-- Hexadecimal: 0xA1, Binary: 0b01, Octal: 0o71 -->
<RegExpr attribute="Hex" String="0[xX](?:_?[0-9a-fA-F])+" context="CheckSuffixError"/>
<RegExpr attribute="Binary" String="0[bB](?:_?[01])+" context="CheckSuffixError"/>
<RegExpr attribute="Octal" String="0[oO](?:_?[0-7])+" context="CheckSuffixError"/>
<!-- Float: 1.1 ; 1. ; .1 ; 1e3 ; 1.1e3 ; 1.e3 ; .1e3 -->
<RegExpr attribute="Float" String="(?:&digitPart;(?:\.(?:&digitPart;)?)?|\.&digitPart;)[eE][\+\-]?&digitPart;|&digitPart;\.(?:&digitPart;)?|\.&digitPart;" context="CheckSuffixError"/>
<!-- Decimal: 123 ; 000 -->
<!-- l and L are python2 suffixes -->
<RegExpr attribute="Int" String="(?:[1-9](?:_?\d)*|0(?:_?0)*)[lL]?" context="CheckSuffixError"/>
</context>
<context name="CheckSuffixError" attribute="Normal Text" lineEndContext="#pop#pop" fallthrough="1" fallthroughContext="#pop#pop">
<RegExpr attribute="Error" String="[\w\d]+" context="#pop#pop"/>
</context>
<context name="yield" attribute="Flow Control Keyword" lineEndContext="#pop" fallthrough="1" fallthroughContext="#pop">
<DetectSpaces attribute="Normal Text" context="#stay"/>
<WordDetect attribute="Flow Control Keyword" context="#pop" String="from"/>
</context>
<context name="Pattern Matching" attribute="Flow Control Keyword" lineEndContext="#pop">
<!--
Python 3.10: https://docs.python.org/3.10/reference/compound_stmts.html#the-match-statement
( 'match' | 'case' ) expression ':'
exclude:
( 'match' | 'case' ) ( 'if' | 'for' | '.' | ':' | '=' | ',' | ']' | ')' ) ...
-->
<RegExpr attribute="Flow Control Keyword" String="\w++(?=\s+(?!(?:if|for)\b)[\w'&quot;~]|\s*+(?![.:=\]),]|(?:if|for)\b)((?:&string;|[^#;(){}]|\(\)|\((?1)\)|\{\}|\{(\s*+(?:(?:&string;|[a-zA-Z0-9.]++)\s*+:\s*+(?:&string;|[^#;(){},]|\(\)|\((?1)\)|\{\}|\{(?2)\})++,?)*+)\})+?):)|" context="#pop"/>
<DetectIdentifier attribute="Normal Text" context="#pop"/>
</context>
<context name="#CheckForString" attribute="Normal Text" lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop">
<DetectSpaces/>
<LineContinue attribute="Normal Text" context="CheckForStringNext"/>
<LineContinue attribute="Normal Text" context="#pop!CheckForStringNext"/>
</context>
<context name="CheckForStringNext" attribute="Normal Text" lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop">
<context name="CheckForStringNext" attribute="Normal Text" lineEndContext="#pop#pop" fallthrough="true" fallthroughContext="#pop#pop">
<DetectSpaces/>
<LineContinue attribute="Normal Text" context="CheckForStringNext"/>
<LineContinue attribute="Normal Text" context="#stay"/>
<IncludeRules context="StringVariants"/>
</context>
<!-- https://docs.python.org/2/reference/lexical_analysis.html#string-literals -->
<!-- https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals -->
<context name="StringVariants" attribute="Normal Text" lineEndContext="#stay">
<DetectSpaces/>
<!-- fast path -->
<RegExpr String="(?:u|r|b|f|ur|fr|rf|br|rb)?['&quot;]" insensitive="true" context="AssumeStringVariants" lookAhead="1"/>
</context>
<context name="AssumeStringVariants" attribute="Normal Text" lineEndContext="#stay">
<RegExpr attribute="String" String="u?'''" insensitive="true" context="#pop!Triple A-string" beginRegion="Triple A-region"/>
<RegExpr attribute="String" String="u?&quot;&quot;&quot;" insensitive="true" context="#pop!Triple Q-string" beginRegion="Triple Q-region"/>
<RegExpr attribute="String" String="u?'" insensitive="true" context="#pop!Single A-string"/>
<RegExpr attribute="String" String="u?&quot;" insensitive="true" context="#pop!Single Q-string"/>
<RegExpr attribute="String" String="u?'''" insensitive="true" context="Triple A-string" beginRegion="Triple A-region"/>
<RegExpr attribute="String" String="u?&quot;&quot;&quot;" 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?&quot;" insensitive="true" context="Single Q-string"/>
<RegExpr attribute="Raw String" String="u?r'''" insensitive="true" context="#pop!Raw Triple A-string" beginRegion="Triple A-region"/>
<RegExpr attribute="Raw String" String="u?r&quot;&quot;&quot;" insensitive="true" context="#pop!Raw Triple Q-string" beginRegion="Triple Q-region"/>
<RegExpr attribute="Raw String" String="u?r'" insensitive="true" context="#pop!Raw A-string"/>
<RegExpr attribute="Raw String" String="u?r&quot;" insensitive="true" context="#pop!Raw 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)&quot;&quot;&quot;" 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)&quot;" insensitive="true" context="Raw Q-string"/>
<StringDetect attribute="F-String" String="f'''" insensitive="true" context="#pop!Triple A-F-String" beginRegion="Triple A-region"/>
<StringDetect attribute="F-String" String="f&quot;&quot;&quot;" insensitive="true" context="#pop!Triple Q-F-String" beginRegion="Triple Q-region"/>
<StringDetect attribute="F-String" String="f'" insensitive="true" context="#pop!Single A-F-String"/>
<StringDetect attribute="F-String" String="f&quot;" insensitive="true" context="#pop!Single Q-F-String"/>
<StringDetect attribute="F-String" String="f'''" insensitive="true" context="Triple A-F-String" beginRegion="Triple A-region"/>
<StringDetect attribute="F-String" String="f&quot;&quot;&quot;" 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&quot;" insensitive="true" context="Single Q-F-String"/>
<RegExpr attribute="Raw F-String" String="(?:fr|rf)'''" insensitive="true" context="#pop!Raw Triple A-F-String" beginRegion="Triple A-region"/>
<RegExpr attribute="Raw F-String" String="(?:fr|rf)&quot;&quot;&quot;" insensitive="true" context="#pop!Raw Triple Q-F-String" beginRegion="Triple Q-region"/>
<RegExpr attribute="Raw F-String" String="(?:fr|rf)'" insensitive="true" context="#pop!Raw A-F-String"/>
<RegExpr attribute="Raw F-String" String="(?:fr|rf)&quot;" insensitive="true" context="#pop!Raw 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)&quot;&quot;&quot;" 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)&quot;" insensitive="true" context="Raw Q-F-String"/>
<StringDetect attribute="B-String" String="b'''" insensitive="true" context="#pop!Triple A-B-String" beginRegion="Triple A-region"/>
<StringDetect attribute="B-String" String="b&quot;&quot;&quot;" insensitive="true" context="#pop!Triple Q-B-String" beginRegion="Triple Q-region"/>
<StringDetect attribute="B-String" String="b'" insensitive="true" context="#pop!Single A-B-String"/>
<StringDetect attribute="B-String" String="b&quot;" insensitive="true" context="#pop!Single Q-B-String"/>
<RegExpr attribute="Raw B-String" String="(?:br|rb)'''" insensitive="true" context="#pop!Raw Triple A-B-String" beginRegion="Triple A-region"/>
<RegExpr attribute="Raw B-String" String="(?:br|rb)&quot;&quot;&quot;" insensitive="true" context="#pop!Raw Triple Q-B-String" beginRegion="Triple Q-region"/>
<RegExpr attribute="Raw B-String" String="(?:br|rb)'" insensitive="true" context="#pop!Raw A-B-String"/>
<RegExpr attribute="Raw B-String" String="(?:br|rb)&quot;" insensitive="true" context="#pop!Raw Q-B-String"/>
</context>
<!-- https://docs.python.org/2/reference/lexical_analysis.html#string-literals -->
<!-- https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals -->
<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?&quot;&quot;&quot;" 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?&quot;" 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)&quot;&quot;&quot;" 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)&quot;" insensitive="true" firstNonSpace="true" context="Single Q-comment"/>
<!-- fast path -->
<RegExpr String="(?:u|r|ur)?['&quot;]" insensitive="true" firstNonSpace="true" context="AssumeCommentVariants" lookAhead="1"/>
</context>
<context name="AssumeCommentVariants" attribute="Normal Text" lineEndContext="#stay">
<RegExpr attribute="Comment" String="(?:u?r?)'''" insensitive="true" context="#pop!Triple A-comment" beginRegion="Triple A-region"/>
<RegExpr attribute="Comment" String="(?:u?r?)&quot;&quot;&quot;" insensitive="true" context="#pop!Triple Q-comment" beginRegion="Triple Q-region"/>
<RegExpr attribute="Comment" String="(?:u?r?)'" insensitive="true" context="#pop!Single A-comment"/>
<RegExpr attribute="Comment" String="(?:u?r?)&quot;" insensitive="true" context="#pop!Single Q-comment"/>
</context>
<context name="Dictionary" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="true">
@@ -472,35 +535,53 @@
<IncludeRules context="Normal" />
</context>
<context name="UnfinishedStringError" attribute="Error" lineEndContext="#stay" noIndentationBasedFolding="true">
<!-- A single string/comment reached the end of the line without a \ line escape -->
<!-- We set ALL succeeding lines to the "Error" attribute so that this error is easier to spot -->
</context>
<!-- Comments -->
<context name="Hash comment" attribute="Comment" lineEndContext="#pop">
<DetectSpaces />
<IncludeRules context="##Comments" />
<DetectIdentifier/>
</context>
<context name="Triple A-comment" attribute="Comment" lineEndContext="#stay" noIndentationBasedFolding="true">
<IncludeRules context="stringescape"/>
<DetectSpaces/>
<StringDetect attribute="Comment" String="'''" context="#pop" endRegion="Triple A-region"/>
<IncludeRules context="##Comments" />
<DetectIdentifier/>
<IncludeRules context="stringescape"/>
<LineContinue attribute="String Char" context="#stay"/>
</context>
<context name="Triple Q-comment" attribute="Comment" lineEndContext="#stay" noIndentationBasedFolding="true">
<IncludeRules context="stringescape"/>
<DetectSpaces/>
<StringDetect attribute="Comment" String="&quot;&quot;&quot;" context="#pop" endRegion="Triple Q-region"/>
<IncludeRules context="##Comments" />
<DetectIdentifier/>
<IncludeRules context="stringescape"/>
<LineContinue attribute="String Char" context="#stay"/>
</context>
<context name="Single A-comment" attribute="Comment" lineEndContext="#stay">
<IncludeRules context="stringescape"/>
<context name="Single A-comment" attribute="Comment" lineEndContext="#pop!UnfinishedStringError">
<DetectSpaces/>
<DetectChar attribute="Comment" char="'" context="#pop"/>
<IncludeRules context="##Comments" />
<DetectIdentifier/>
<IncludeRules context="stringescape"/>
<LineContinue attribute="String Char" context="#stay"/>
</context>
<context name="Single Q-comment" attribute="Comment" lineEndContext="#stay">
<IncludeRules context="stringescape"/>
<context name="Single Q-comment" attribute="Comment" lineEndContext="#pop!UnfinishedStringError">
<DetectSpaces/>
<DetectChar attribute="Comment" char="&quot;" context="#pop"/>
<IncludeRules context="##Comments" />
<DetectIdentifier/>
<IncludeRules context="stringescape"/>
<LineContinue attribute="String Char" context="#stay"/>
</context>
<!-- Strings -->
@@ -520,14 +601,25 @@
<RegExpr attribute="String Char" String="\\[\\'&quot;abfnrtv]|\\[0-7]{1,3}|\\x[0-9A-Fa-f]{2}|\\u[0-9A-Fa-f]{4}|\\U[0-9A-Fa-f]{8}|\\N\{[a-zA-Z0-9\- ]+\}" context="#stay"/>
</context>
<!-- escape characters -->
<context name="bytesescape" 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="\\[\\'&quot;abfnrtv]|\\[0-7]{1,3}|\\x[0-9A-Fa-f]{2}" 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"/>
<Detect2Chars attribute="String Char" char="}" char1="}" context="#stay"/>
<DetectChar attribute="Error" char="}" context="#stay"/>
</context>
<context name="String Interpolation" attribute="String Substitution" lineEndContext="#stay">
<DetectChar attribute="Error" char="\" context="#pop"/>
<RegExpr attribute="String Substitution" String="(?:![rs])?(?::(?:[^}]?[&lt;&gt;=^])?[ +-]?#?0?[0-9]*(?:\.[0-9]+)?[bcdeEfFgGnosxX%]?)?\}" context="#pop"/>
<!-- format specifiers: [[fill]align][sign][#][0][minimumwidth][.precision][type] -->
<RegExpr attribute="String Substitution" String="(?:![rsa])?(?::(?:[^}]?[&lt;&gt;=^])?[ +-]?#?0?[0-9]*(?:\.[0-9]+)?[bcdeEfFgGnosxX%]?)?\}" context="#pop"/>
<IncludeRules context="Normal"/> <!-- TODO: create expression context instead -->
</context>
@@ -542,107 +634,218 @@
Adding byte literals wouldnt 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">
<DetectSpaces attribute="String"/>
<DetectIdentifier attribute="String"/>
<IncludeRules context="stringescape"/>
<IncludeRules context="stringformat"/>
<StringDetect attribute="String" String="'''" context="#pop!#CheckForString" endRegion="Triple A-region"/>
<LineContinue attribute="String Char" context="#stay"/>
</context>
<context name="Raw Triple A-string" attribute="Raw String" lineEndContext="#stay" noIndentationBasedFolding="true">
<HlCStringChar attribute="Raw String" context="#stay"/>
<DetectSpaces attribute="Raw String"/>
<DetectIdentifier attribute="Raw String"/>
<Detect2Chars attribute="Raw String" char="\" char1="'"/>
<Detect2Chars attribute="Raw String" char="\" char1="\"/>
<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">
<DetectSpaces attribute="F-String"/>
<DetectIdentifier attribute="F-String"/>
<IncludeRules context="stringescape"/>
<IncludeRules context="stringinterpolation"/>
<StringDetect attribute="F-String" String="'''" context="#pop!#CheckForString" endRegion="Triple A-region"/>
<LineContinue attribute="String Char" context="#stay"/>
</context>
<context name="Raw Triple A-F-String" attribute="Raw F-String" lineEndContext="#stay" noIndentationBasedFolding="true">
<HlCStringChar attribute="Raw F-String" context="#stay"/>
<DetectSpaces attribute="Raw F-String"/>
<DetectIdentifier attribute="Raw F-String"/>
<Detect2Chars attribute="Raw F-String" char="\" char1="'"/>
<Detect2Chars attribute="Raw F-String" char="\" char1="\"/>
<IncludeRules context="stringinterpolation"/>
<StringDetect attribute="Raw F-String" String="'''" context="#pop!#CheckForString" endRegion="Triple A-region"/>
</context>
<context name="Triple A-B-String" attribute="B-String" lineEndContext="#stay" noIndentationBasedFolding="true">
<RegExpr attribute="B-String" String="([\x20-\x26\x28-\x5B\x5D-\x7E]++|\\(?=[^\\'&quot;abfnrtvx0-7])|\\x(?![0-9a-fA-F]{2})|'(?!''))++"/>
<IncludeRules context="bytesescape"/>
<StringDetect attribute="B-String" String="'''" context="#pop!#CheckForString" endRegion="Triple A-region"/>
<LineContinue attribute="String Char" context="#stay"/>
<RegExpr attribute="Error" String="."/>
</context>
<context name="Raw Triple A-B-String" attribute="Raw B-String" lineEndContext="#stay" noIndentationBasedFolding="true">
<RegExpr attribute="Raw B-String" String="([\x20-\x26\x28-\x5B\x5D-\x7E]++|\\.?|'(?!''))++"/>
<StringDetect attribute="Raw B-String" String="'''" context="#pop!#CheckForString" endRegion="Triple A-region"/>
<RegExpr attribute="Error" String="."/>
</context>
<!-- Triple-quoted Q-strings -->
<context name="Triple Q-string" attribute="String" lineEndContext="#stay" noIndentationBasedFolding="true">
<DetectSpaces attribute="String"/>
<DetectIdentifier attribute="String"/>
<IncludeRules context="stringescape"/>
<IncludeRules context="stringformat"/>
<StringDetect attribute="String" String="&quot;&quot;&quot;" context="#pop!#CheckForString" endRegion="Triple Q-region"/>
<LineContinue attribute="String Char" context="#stay"/>
</context>
<context name="Raw Triple Q-string" attribute="Raw String" lineEndContext="#stay" noIndentationBasedFolding="true">
<HlCStringChar attribute="Raw String" context="#stay"/>
<DetectSpaces attribute="Raw String"/>
<DetectIdentifier attribute="Raw String"/>
<Detect2Chars attribute="Raw String" char="\" char1="&quot;"/>
<Detect2Chars attribute="Raw String" char="\" char1="\"/>
<IncludeRules context="stringformat"/>
<StringDetect attribute="Raw String" String="&quot;&quot;&quot;" context="#pop!#CheckForString" endRegion="Triple Q-region"/>
</context>
<context name="Triple Q-F-String" attribute="F-String" lineEndContext="#stay" noIndentationBasedFolding="true">
<DetectSpaces attribute="F-String"/>
<DetectIdentifier attribute="F-String"/>
<IncludeRules context="stringescape"/>
<IncludeRules context="stringinterpolation"/>
<StringDetect attribute="F-String" String="&quot;&quot;&quot;" context="#pop!#CheckForString" endRegion="Triple Q-region"/>
<LineContinue attribute="String Char" context="#stay"/>
</context>
<context name="Raw Triple Q-F-String" attribute="Raw F-String" lineEndContext="#stay" noIndentationBasedFolding="true">
<HlCStringChar attribute="Raw F-String" context="#stay"/>
<DetectSpaces attribute="Raw F-String"/>
<DetectIdentifier attribute="Raw F-String"/>
<Detect2Chars attribute="Raw F-String" char="\" char1="&quot;"/>
<Detect2Chars attribute="Raw F-String" char="\" char1="\"/>
<IncludeRules context="stringinterpolation"/>
<StringDetect attribute="Raw F-String" String="&quot;&quot;&quot;" context="#pop!#CheckForString" endRegion="Triple Q-region"/>
</context>
<context name="Triple Q-B-String" attribute="B-String" lineEndContext="#stay" noIndentationBasedFolding="true">
<RegExpr attribute="B-String" String="([\x20\x21\x23-\x5B\x5D-\x7E]++|\\(?=[^\\'&quot;abfnrtvx0-7])|\\x(?![0-9a-fA-F]{2})|&quot;(?!&quot;&quot;))++"/>
<IncludeRules context="bytesescape"/>
<StringDetect attribute="B-String" String="&quot;&quot;&quot;" context="#pop!#CheckForString" endRegion="Triple Q-region"/>
<LineContinue attribute="String Char" context="#stay"/>
<RegExpr attribute="Error" String="."/>
</context>
<context name="Raw Triple Q-B-String" attribute="Raw B-String" lineEndContext="#stay" noIndentationBasedFolding="true">
<RegExpr attribute="Raw B-String" String="([\x20\x21\x23-\x5B\x5D-\x7E]++|\\.?|&quot;(?!&quot;&quot;))++"/>
<StringDetect attribute="Raw B-String" String="&quot;&quot;&quot;" context="#pop!#CheckForString" endRegion="Triple Q-region"/>
<RegExpr attribute="Error" String="."/>
</context>
<!-- Single-quoted A-strings -->
<context name="Single A-string" attribute="String" lineEndContext="#stay">
<context name="Single A-string" attribute="String" lineEndContext="#pop!UnfinishedStringError">
<DetectSpaces attribute="String"/>
<DetectIdentifier attribute="String"/>
<IncludeRules context="stringescape"/>
<IncludeRules context="stringformat"/>
<DetectChar attribute="String" char="'" context="#pop!#CheckForString"/>
<LineContinue attribute="String Char" context="#stay"/>
</context>
<context name="Raw A-string" attribute="Raw String" lineEndContext="#stay">
<HlCStringChar attribute="Raw String" context="#stay"/>
<context name="Raw A-string" attribute="Raw String" lineEndContext="#pop!UnfinishedStringError">
<DetectSpaces attribute="Raw String"/>
<DetectIdentifier attribute="Raw String"/>
<Detect2Chars attribute="Raw String" char="\" char1="'"/>
<Detect2Chars attribute="Raw String" char="\" char1="\"/>
<IncludeRules context="stringformat"/>
<DetectChar attribute="Raw String" char="'" context="#pop!#CheckForString"/>
<LineContinue attribute="Raw String" context="#stay"/>
</context>
<context name="Single A-F-String" attribute="F-String" lineEndContext="#stay">
<context name="Single A-F-String" attribute="F-String" lineEndContext="#pop!UnfinishedStringError">
<DetectSpaces attribute="F-String"/>
<DetectIdentifier attribute="F-String"/>
<IncludeRules context="stringescape"/>
<IncludeRules context="stringinterpolation"/>
<DetectChar attribute="F-String" char="'" context="#pop!#CheckForString"/>
<LineContinue attribute="String Char" context="#stay"/>
</context>
<context name="Raw A-F-String" attribute="Raw F-String" lineEndContext="#stay">
<HlCStringChar attribute="Raw F-String" context="#stay"/>
<context name="Raw A-F-String" attribute="Raw F-String" lineEndContext="#pop!UnfinishedStringError">
<DetectSpaces attribute="Raw F-String"/>
<DetectIdentifier attribute="Raw F-String"/>
<Detect2Chars attribute="Raw F-String" char="\" char1="'"/>
<Detect2Chars attribute="Raw F-String" char="\" char1="\"/>
<IncludeRules context="stringinterpolation"/>
<DetectChar attribute="Raw F-String" char="'" context="#pop!#CheckForString"/>
<LineContinue attribute="Raw F-String" context="#stay"/>
</context>
<context name="Single A-B-String" attribute="B-String" lineEndContext="#pop!UnfinishedStringError">
<RegExpr attribute="B-String" String="([\x20-\x26\x28-\x5B\x5D-\x7E]++|\\(?=[^\\'&quot;abfnrtvx0-7])|\\x(?![0-9a-fA-F]{2}))++"/>
<IncludeRules context="bytesescape"/>
<DetectChar attribute="B-String" char="'" context="#pop!#CheckForString"/>
<LineContinue attribute="String Char" context="#stay"/>
<RegExpr attribute="Error" String="."/>
</context>
<context name="Raw A-B-String" attribute="Raw B-String" lineEndContext="#pop!UnfinishedStringError">
<RegExpr attribute="Raw B-String" String="([\x20-\x26\x28-\x5B\x5D-\x7E]++|\\.)++"/>
<DetectChar attribute="Raw B-String" char="'" context="#pop!#CheckForString"/>
<LineContinue attribute="Raw B-String" context="#stay"/>
<RegExpr attribute="Error" String="."/>
</context>
<!-- Single-quoted Q-strings -->
<context name="Single Q-string" attribute="String" lineEndContext="#stay">
<context name="Single Q-string" attribute="String" lineEndContext="#pop!UnfinishedStringError">
<DetectSpaces attribute="String"/>
<DetectIdentifier attribute="String"/>
<IncludeRules context="stringescape"/>
<IncludeRules context="stringformat"/>
<DetectChar attribute="String" char="&quot;" context="#pop!#CheckForString"/>
<LineContinue attribute="String Char" context="#stay"/>
</context>
<context name="Raw Q-string" attribute="Raw String" lineEndContext="#stay">
<HlCStringChar attribute="Raw String" context="#stay"/>
<context name="Raw Q-string" attribute="Raw String" lineEndContext="#pop!UnfinishedStringError">
<DetectSpaces attribute="Raw String"/>
<DetectIdentifier attribute="Raw String"/>
<Detect2Chars attribute="Raw String" char="\" char1="&quot;"/>
<Detect2Chars attribute="Raw String" char="\" char1="\"/>
<IncludeRules context="stringformat"/>
<DetectChar attribute="Raw String" char="&quot;" context="#pop!#CheckForString"/>
<LineContinue attribute="Raw String" context="#stay"/>
</context>
<context name="Single Q-F-String" attribute="F-String" lineEndContext="#stay">
<context name="Single Q-F-String" attribute="F-String" lineEndContext="#pop!UnfinishedStringError">
<DetectSpaces attribute="F-String"/>
<DetectIdentifier attribute="F-String"/>
<IncludeRules context="stringescape"/>
<IncludeRules context="stringinterpolation"/>
<DetectChar attribute="F-String" char="&quot;" context="#pop!#CheckForString"/>
<LineContinue attribute="String Char" context="#stay"/>
</context>
<context name="Raw Q-F-String" attribute="Raw F-String" lineEndContext="#stay">
<HlCStringChar attribute="Raw F-String" context="#stay"/>
<context name="Raw Q-F-String" attribute="Raw F-String" lineEndContext="#pop!UnfinishedStringError">
<DetectSpaces attribute="Raw F-String"/>
<DetectIdentifier attribute="Raw F-String"/>
<Detect2Chars attribute="Raw F-String" char="\" char1="&quot;"/>
<Detect2Chars attribute="Raw F-String" char="\" char1="\"/>
<IncludeRules context="stringinterpolation"/>
<DetectChar attribute="Raw F-String" char="&quot;" context="#pop!#CheckForString"/>
<LineContinue attribute="Raw F-String" context="#stay"/>
</context>
<context name="Single Q-B-String" attribute="B-String" lineEndContext="#pop!UnfinishedStringError">
<RegExpr attribute="B-String" String="([\x20\x21\x23-\x5B\x5D-\x7E]++|\\(?=[^\\'&quot;abfnrtvx0-7])|\\x(?![0-9a-fA-F]{2}))++"/>
<IncludeRules context="bytesescape"/>
<DetectChar attribute="B-String" char="&quot;" context="#pop!#CheckForString"/>
<LineContinue attribute="String Char" context="#stay"/>
<RegExpr attribute="Error" String="."/>
</context>
<context name="Raw Q-B-String" attribute="Raw B-String" lineEndContext="#pop!UnfinishedStringError">
<RegExpr attribute="Raw B-String" String="([\x20\x21\x23-\x5B\x5D-\x7E]++|\\.)++"/>
<DetectChar attribute="Raw B-String" char="&quot;" context="#pop!#CheckForString"/>
<Detect2Chars attribute="Raw B-String" char="\" char1="\"/>
<LineContinue attribute="Raw B-String" context="#stay"/>
<RegExpr attribute="Error" String="."/>
</context>
</contexts>
<itemDatas>
@@ -668,6 +871,8 @@
<itemData name="Raw String" defStyleNum="dsVerbatimString"/>
<itemData name="F-String" defStyleNum="dsSpecialString"/>
<itemData name="Raw F-String" defStyleNum="dsVerbatimString"/>
<itemData name="B-String" defStyleNum="dsString" spellChecking="false"/>
<itemData name="Raw B-String" defStyleNum="dsVerbatimString" spellChecking="false"/>
<itemData name="String Char" defStyleNum="dsChar" spellChecking="false"/>
<itemData name="String Substitution" defStyleNum="dsSpecialChar" spellChecking="false"/>
<itemData name="Decorator" defStyleNum="dsAttribute" spellChecking="false"/>

View File

@@ -6,7 +6,7 @@
<!ENTITY name "(?![0-9])[\w_:][\w.:_-]*">
<!ENTITY entref "&amp;(?:#[0-9]+|#[xX][0-9A-Fa-f]+|&name;);">
]>
<language name="XML" version="12" kateversion="5.0" section="Markup" extensions="*.docbook;*.xml;*.rc;*.daml;*.rdf;*.rss;*.xspf;*.xsd;*.svg;*.ui;*.kcfg;*.qrc;*.wsdl;*.scxml;*.xbel;*.dae;*.sch;*.brd" mimetype="text/xml;text/book;text/daml;text/rdf;application/rss+xml;application/xspf+xml;image/svg+xml;application/x-designer;application/x-xbel;application/xml;application/scxml+xml" casesensitive="1" indenter="xml" author="Wilbert Berendsen (wilbert@kde.nl)" license="LGPL">
<language name="XML" version="14" kateversion="5.0" section="Markup" extensions="*.docbook;*.xml;*.rc;*.daml;*.rdf;*.rss;*.xspf;*.xsd;*.svg;*.ui;*.kcfg;*.qrc;*.wsdl;*.scxml;*.xbel;*.dae;*.sch;*.brd" mimetype="text/xml;text/book;text/daml;text/rdf;application/rss+xml;application/xspf+xml;image/svg+xml;application/x-designer;application/x-xbel;application/xml;application/scxml+xml" casesensitive="1" indenter="xml" author="Wilbert Berendsen (wilbert@kde.nl)" license="LGPL">
<highlighting>
<contexts>
@@ -16,13 +16,13 @@
<context name="FindXML" attribute="Normal Text" lineEndContext="#stay">
<DetectSpaces />
<DetectIdentifier />
<RegExpr attribute="Element Symbols" context="ElementTagName" String="&lt;(?=(&name;))" beginRegion="element" />
<StringDetect attribute="Comment" context="Comment" String="&lt;!--" beginRegion="comment" />
<StringDetect attribute="CDATA" context="CDATAStart" String="&lt;![CDATA[" lookAhead="true" />
<RegExpr attribute="Doctype Symbols" context="DoctypeTagName" String="&lt;!(?=DOCTYPE\s+)" beginRegion="doctype" />
<RegExpr attribute="Doctype Symbols" context="DoctypeTagName" String="&lt;!(?=DOCTYPE(\s|$))" beginRegion="doctype" />
<IncludeRules context="FindProcessingInstruction" />
<RegExpr attribute="Element Symbols" context="ElementTagName" String="&lt;(?=(&name;))" beginRegion="element" />
<IncludeRules context="FindEntityRefs" />
<DetectIdentifier />
</context>
<context name="FindEntityRefs" attribute="Other Text" lineEndContext="#stay">
@@ -70,13 +70,13 @@
<context name="PI-XML" attribute="Other Text" lineEndContext="#stay">
<IncludeRules context="PI" />
<RegExpr attribute="Attribute" context="#stay" String="(?:^|\s+)&name;" />
<DetectChar attribute="Attribute" context="Value" char="=" />
<DetectChar attribute="Attribute Separator" context="Value" char="=" />
</context>
<context name="DoctypeTagName" attribute="Other Text" lineEndContext="#pop">
<StringDetect attribute="Doctype" context="#pop!DoctypeVariableName" String="DOCTYPE" />
</context>
<context name="DoctypeVariableName" attribute="Other Text" lineEndContext="#pop!Doctype" fallthrough="true" fallthroughContext="#pop!Doctype">
<context name="DoctypeVariableName" attribute="Other Text" lineEndContext="#stay" fallthrough="true" fallthroughContext="#pop!Doctype">
<DetectSpaces />
<RegExpr attribute="Doctype Name" context="#pop!Doctype" String="&name;" />
</context>
@@ -116,7 +116,7 @@
<IncludeRules context="FindPEntityRefs" />
</context>
<context name="ElementTagName" attribute="Other Text" lineEndContext="#pop!Element" fallthrough="true" fallthroughContext="#pop!Element">
<context name="ElementTagName" attribute="Other Text" lineEndContext="#pop!Element">
<StringDetect attribute="Element" context="#pop!Element" String="%1" dynamic="true" />
</context>
<context name="Element" attribute="Other Text" lineEndContext="#stay">
@@ -131,7 +131,7 @@
<IncludeRules context="FindXML" />
</context>
<context name="El End TagName" attribute="Other Text" lineEndContext="#pop!El End" fallthrough="true" fallthroughContext="#pop!El End">
<context name="El End TagName" attribute="Other Text" lineEndContext="#pop!El End">
<StringDetect attribute="Element" context="#pop!El End" String="%1" dynamic="true" />
</context>
<context name="El End" attribute="Other Text" lineEndContext="#stay">
@@ -140,7 +140,7 @@
</context>
<context name="Attribute" attribute="Other Text" lineEndContext="#stay">
<DetectChar attribute="Attribute" context="#pop!Value" char="=" />
<DetectChar attribute="Attribute Separator" context="#pop!Value" char="=" />
<RegExpr attribute="Error" context="#stay" String="\S" />
</context>
@@ -175,6 +175,7 @@
<itemData name="Element" defStyleNum="dsKeyword" spellChecking="false" />
<itemData name="Element Symbols" defStyleNum="dsNormal" spellChecking="false" />
<itemData name="Attribute" defStyleNum="dsOthers" spellChecking="false" />
<itemData name="Attribute Separator" defStyleNum="dsOthers" spellChecking="false" />
<itemData name="Value" defStyleNum="dsString" spellChecking="false" />
<itemData name="EntityRef" defStyleNum="dsDecVal" spellChecking="false" />
<itemData name="PEntityRef" defStyleNum="dsDecVal" spellChecking="false" />

View File

@@ -1,6 +1,6 @@
{
"_comments": [
"Last update: Feb 22, 2021 (revision 3)",
"Last update: Jul 28, 2021 (revision 4)",
"This file has been converted from: https://github.com/dempfi/ayu",
"Also see: https://github.com/ayu-theme"
],
@@ -11,7 +11,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name": "ayu Dark",
"revision": 3
"revision": 4
},
"editor-colors": {
"BackgroundColor": "#0a0e14",
@@ -169,8 +169,8 @@
"text-color": "#39bae6"
},
"VerbatimString": {
"selected-text-color": "#c2d94c",
"text-color": "#c2d94c"
"selected-text-color": "#99ca44",
"text-color": "#99ca44"
},
"Warning": {
"selected-text-color": "#f07178",

View File

@@ -1,6 +1,6 @@
{
"_comments": [
"Last update: Sep 21, 2020 (revision 2)",
"Last update: Jul 28, 2021 (revision 3)",
"This file has been converted from: https://github.com/dempfi/ayu",
"Also see: https://github.com/ayu-theme"
],
@@ -11,7 +11,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name": "ayu Light",
"revision": 2
"revision": 3
},
"editor-colors": {
"BackgroundColor": "#fafafa",
@@ -169,8 +169,8 @@
"text-color": "#55b4d4"
},
"VerbatimString": {
"selected-text-color": "#86b300",
"text-color": "#86b300"
"selected-text-color": "#729800",
"text-color": "#729800"
},
"Warning": {
"selected-text-color": "#f07171",

View File

@@ -1,6 +1,6 @@
{
"_comments": [
"Last update: Feb 22, 2021 (revision 3)",
"Last update: Jul 28, 2021 (revision 4)",
"This file has been converted from: https://github.com/dempfi/ayu",
"Also see: https://github.com/ayu-theme"
],
@@ -11,7 +11,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name": "ayu Mirage",
"revision": 3
"revision": 4
},
"editor-colors": {
"BackgroundColor": "#1f2430",
@@ -169,8 +169,8 @@
"text-color": "#5ccfe6"
},
"VerbatimString": {
"selected-text-color": "#bae67e",
"text-color": "#bae67e"
"selected-text-color": "#82e26a",
"text-color": "#82e26a"
},
"Warning": {
"selected-text-color": "#f28779",

View File

@@ -5,7 +5,7 @@
"SPDX-FileCopyrightText: 2016 Dominik Haumann <dhaumann@kde.org>"
],
"license": "SPDX-License-Identifier: MIT",
"revision" : 6,
"revision" : 7,
"name" : "Breeze Dark"
},
"text-styles": {
@@ -149,7 +149,7 @@
"editor-colors": {
"BackgroundColor" : "#232629",
"CodeFolding" : "#224e65",
"BracketMatching" : "#323030",
"BracketMatching" : "#8e44ad",
"CurrentLine" : "#2A2E32",
"IconBorder" : "#31363b",
"IndentationLine" : "#3a3f44",

View File

@@ -5,7 +5,7 @@
"SPDX-FileCopyrightText: 2016 Dominik Haumann <dhaumann@kde.org>"
],
"license": "SPDX-License-Identifier: MIT",
"revision" : 8,
"revision" : 9,
"name" : "Breeze Light"
},
"text-styles": {
@@ -70,7 +70,7 @@
"selected-text-color" : "#9c0e0e"
},
"VerbatimString" : {
"text-color" : "#bf0303",
"text-color" : "#e31616",
"selected-text-color" : "#9c0e0e"
},
"SpecialString" : {

View File

@@ -570,7 +570,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name": "Dracula",
"revision": 7
"revision": 8
},
"text-styles": {
"Alert": {
@@ -694,8 +694,8 @@
"text-color": "#8be9fd"
},
"VerbatimString": {
"selected-text-color": "#f1fa8c",
"text-color": "#f1fa8c"
"selected-text-color": "#d7e60a",
"text-color": "#d7e60a"
},
"Warning": {
"selected-text-color": "#ff5555",

View File

@@ -0,0 +1,184 @@
{
"_comments": [
"A theme focused on ergonomics, using the 3 digit Tango color palette"
],
"metadata": {
"name": "Falcon",
"revision": 4,
"license": "SPDX-License-Identifier: MIT",
"copyright": [ "SPDX-FileCopyrightText: 2021 Alberto Salvia Novella <https://es20490446e.wordpress.com>" ]
},
"custom-styles": {
"Bash": {
"Normal Text": {
"text-color": "#bbbbbb"
}
}
},
"editor-colors": {
"BackgroundColor": "#223333",
"BracketMatching": "#555555",
"CodeFolding": "#224488",
"CurrentLine": "#555555",
"CurrentLineNumber": "#bbbbbb",
"IconBorder": "#223333",
"IndentationLine": "#888888",
"LineNumbers": "#888888",
"MarkBookmark": "#7799cc",
"MarkBreakpointActive": "#ffaa33",
"MarkBreakpointDisabled": "#aa77aa",
"MarkBreakpointReached": "#449900",
"MarkError": "#ef2929",
"MarkExecution": "#888888",
"MarkWarning": "#aa77aa",
"ModifiedLines": "#aa0000",
"ReplaceHighlight": "#224488",
"SavedLines": "#449900",
"SearchHighlight": "#224488",
"Separator": "#555753",
"SpellChecking": "#ef2929",
"TabMarker": "#555555",
"TemplateBackground": "#223333",
"TemplateFocusedPlaceholder": "#23321a",
"TemplatePlaceholder": "#23321a",
"TemplateReadOnlyPlaceholder": "#451e1a",
"TextSelection": "#3366aa",
"WordWrapMarker": "#555753"
},
"text-styles": {
"Alert": {
"background-color": "#320000",
"bold": true,
"selected-text-color": "#ffaa33",
"text-color": "#ee2222"
},
"Annotation": {
"selected-text-color": "#ddddcc",
"text-color": "#aa77aa"
},
"Attribute": {
"selected-text-color": "#ddddcc",
"text-color": "#aa77aa"
},
"BaseN": {
"selected-text-color": "#ffee44",
"text-color": "#eedd00"
},
"BuiltIn": {
"selected-text-color": "#ddddcc",
"text-color": "#7799cc"
},
"Char": {
"selected-text-color": "#ffaa33",
"text-color": "#ffaa33"
},
"Comment": {
"selected-text-color": "#eeeeec",
"text-color": "#888888"
},
"CommentVar": {
"selected-text-color": "#ddddcc",
"text-color": "#aa77aa"
},
"Constant": {
"bold": true,
"selected-text-color": "#ffee44",
"text-color": "#eedd00"
},
"ControlFlow": {
"bold": true,
"selected-text-color": "#ffee44",
"text-color": "#eedd00"
},
"DataType": {
"selected-text-color": "#ddddcc",
"text-color": "#7799cc"
},
"DecVal": {
"selected-text-color": "#ffee44",
"text-color": "#eedd00"
},
"Documentation": {
"selected-text-color": "#eeeeee",
"text-color": "#d3d7cf"
},
"Error": {
"selected-text-color": "#ffaa33",
"text-color": "#ee2222",
"underline": true
},
"Extension": {
"bold": true,
"selected-text-color": "#ddddcc",
"text-color": "#7799cc"
},
"Float": {
"selected-text-color": "#ffaa33",
"text-color": "#ffaa33"
},
"Function": {
"bold": true,
"selected-text-color": "#ddddcc",
"text-color": "#7799cc"
},
"Import": {
"selected-text-color": "#88ee33",
"text-color": "#88ee33"
},
"Information": {
"selected-text-color": "#eeeeee",
"text-color": "#ddddcc"
},
"Keyword": {
"bold": true,
"selected-text-color": "#ddddcc",
"text-color": "#aa77aa"
},
"Normal": {
"selected-text-color": "#eeeeee",
"text-color": "#ddddcc"
},
"Operator": {
"selected-text-color": "#ffee44",
"text-color": "#eedd00"
},
"Others": {
"selected-text-color": "#ffee44",
"text-color": "#eedd00"
},
"Preprocessor": {
"selected-text-color": "#ddddcc",
"text-color": "#aa77aa"
},
"RegionMarker": {
"background-color": "#0d1932",
"selected-text-color": "#ddddcc",
"text-color": "#7799cc"
},
"SpecialChar": {
"selected-text-color": "#ffaa33",
"text-color": "#ffaa33"
},
"SpecialString": {
"selected-text-color": "#eeeeee",
"text-color": "#ddddcc"
},
"String": {
"selected-text-color": "#eeeeee",
"text-color": "#ddddcc"
},
"Variable": {
"bold": true,
"selected-text-color": "#ffaa33",
"text-color": "#ffaa33"
},
"VerbatimString": {
"selected-text-color": "#ffaa33",
"text-color": "#ffaa33"
},
"Warning": {
"selected-text-color": "#ffee44",
"text-color": "#eedd00"
}
}
}

View File

@@ -82,7 +82,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name": "GitHub Dark",
"revision": 2
"revision": 3
},
"text-styles": {
"Alert": {
@@ -205,8 +205,8 @@
"text-color": "#ffab70"
},
"VerbatimString": {
"selected-text-color": "#9ecbff",
"text-color": "#9ecbff"
"selected-text-color": "#41a0ff",
"text-color": "#41a0ff"
},
"Warning": {
"selected-text-color": "#ff5555",

View File

@@ -82,7 +82,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name": "GitHub Light",
"revision": 2
"revision": 3
},
"text-styles": {
"Alert": {
@@ -205,8 +205,8 @@
"text-color": "#e36209"
},
"VerbatimString": {
"selected-text-color": "#032f62",
"text-color": "#032f62"
"selected-text-color": "#034c95",
"text-color": "#034c95"
},
"Warning": {
"selected-text-color": "#ff5555",

View File

@@ -1,6 +1,6 @@
{
"_comments": [
"Last update: Sep 17, 2020 (revision 2)",
"Last update: Jul 28, 2021 (revision 3)",
"This file has been converted from: https://github.com/morhetz/gruvbox"
],
"metadata" : {
@@ -10,7 +10,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name" : "gruvbox Dark",
"revision" : 2
"revision" : 3
},
"text-styles": {
"Normal" : {
@@ -73,7 +73,7 @@
"selected-text-color" : "#b8bb26"
},
"VerbatimString" : {
"text-color" : "#98971a",
"text-color" : "#848216",
"selected-text-color" : "#b8bb26"
},
"SpecialString" : {

View File

@@ -1,6 +1,6 @@
{
"_comments": [
"Last update: Sep 17, 2020 (revision 2)",
"Last update: Jul 28, 2021 (revision 3)",
"This file has been converted from: https://github.com/morhetz/gruvbox"
],
"metadata" : {
@@ -10,7 +10,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name" : "gruvbox Light",
"revision" : 2
"revision" : 3
},
"text-styles": {
"Normal" : {
@@ -73,7 +73,7 @@
"selected-text-color" : "#79740e"
},
"VerbatimString" : {
"text-color" : "#98971a",
"text-color" : "#848216",
"selected-text-color" : "#79740e"
},
"SpecialString" : {

View File

@@ -259,7 +259,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name": "Monokai",
"revision": 5
"revision": 6
},
"text-styles": {
"Alert": {
@@ -383,8 +383,8 @@
"text-color": "#f8f8f2"
},
"VerbatimString": {
"selected-text-color": "#e6db74",
"text-color": "#e6db74"
"selected-text-color": "#d8c72c",
"text-color": "#d8c72c"
},
"Warning": {
"selected-text-color": "#ff5555",

View File

@@ -1,6 +1,6 @@
{
"_comments": [
"Last update: Sep 21, 2020 (revision 2)",
"Last update: Jul 28, 2020 (revision 3)",
"This theme has been adapted from: https://www.nordtheme.com"
],
"metadata": {
@@ -11,7 +11,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name": "Nord",
"revision": 2
"revision": 3
},
"editor-colors": {
"BackgroundColor": "#2e3440",
@@ -170,8 +170,8 @@
"text-color": "#5e81ac"
},
"VerbatimString": {
"selected-text-color": "#a3be8c",
"text-color": "#a3be8c"
"selected-text-color": "#8dae70",
"text-color": "#8dae70"
},
"Warning": {
"selected-text-color": "#bf616a",

View File

@@ -5,7 +5,7 @@
"SPDX-FileCopyrightText: 2016 Dominik Haumann <dhaumann@kde.org>"
],
"license": "SPDX-License-Identifier: MIT",
"revision" : 4,
"revision" : 5,
"name" : "Printing"
},
"text-styles": {
@@ -69,7 +69,7 @@
"selected-text-color" : "#9c0e0e"
},
"VerbatimString" : {
"text-color" : "#bf0303",
"text-color" : "#ea0404",
"selected-text-color" : "#9c0e0e"
},
"SpecialString" : {

View File

@@ -9,7 +9,7 @@
"SPDX-FileCopyrightText: 2018 Andrew Crouthamel <andrew.crouthamel@kdemail.net>"
],
"license": "SPDX-License-Identifier: MIT",
"revision" : 5,
"revision" : 6,
"name" : "Solarized Dark"
},
"text-styles": {
@@ -70,8 +70,8 @@
"selected-text-color" : "#2aa198"
},
"VerbatimString" : {
"text-color" : "#2aa198",
"selected-text-color" : "#2aa198"
"text-color" : "#23877e",
"selected-text-color" : "#23877e"
},
"SpecialString" : {
"text-color" : "#dc322f",

View File

@@ -9,7 +9,7 @@
"SPDX-FileCopyrightText: 2018 Andrew Crouthamel <andrew.crouthamel@kdemail.net>"
],
"license": "SPDX-License-Identifier: MIT",
"revision" : 4,
"revision" : 5,
"name" : "Solarized Light"
},
"text-styles": {
@@ -73,8 +73,8 @@
"selected-text-color" : "#2aa198"
},
"VerbatimString" : {
"text-color" : "#2aa198",
"selected-text-color" : "#2aa198"
"text-color" : "#23837a",
"selected-text-color" : "#23837a"
},
"SpecialString" : {
"text-color" : "#dc322f",

View File

@@ -9,6 +9,7 @@
<file>ayu-light.theme</file>
<file>ayu-mirage.theme</file>
<file>dracula.theme</file>
<file>falcon.theme</file>
<file>github-dark.theme</file>
<file>github-light.theme</file>
<file>gruvbox-dark.theme</file>

View File

@@ -5,7 +5,7 @@
"SPDX-FileCopyrightText: 2020 Nibaldo González <nibgonz@gmail.com>"
],
"license": "SPDX-License-Identifier: MIT",
"revision" : 3,
"revision" : 4,
"name" : "Vim Dark"
},
"text-styles": {
@@ -70,8 +70,8 @@
"selected-text-color" : "#ff54ff"
},
"VerbatimString" : {
"text-color" : "#ff54ff",
"selected-text-color" : "#ff54ff"
"text-color" : "#f000f0",
"selected-text-color" : "#f000f0"
},
"SpecialString" : {
"text-color" : "#ff5500",

View File

@@ -6,7 +6,7 @@ platforms:
- name: Linux
- name: FreeBSD
- name: Windows
- name: MacOSX
- name: macOS
- name: Android
portingAid: false
deprecated: false

View File

@@ -30,10 +30,11 @@ static void applyHighlighter(Highlighter &highlighter,
const QCommandLineOption &outputName,
const Ts &...highlightParams)
{
if (parser.isSet(outputName))
if (parser.isSet(outputName)) {
highlighter.setOutputFile(parser.value(outputName));
else
} else {
highlighter.setOutputFile(stdout);
}
if (fromFileName) {
highlighter.highlightFile(inFileName, highlightParams...);
@@ -126,8 +127,9 @@ int main(int argc, char **argv)
}
if (parser.isSet(listThemes)) {
for (const auto &theme : repo.themes())
for (const auto &theme : repo.themes()) {
std::cout << qPrintable(theme.name()) << std::endl;
}
return 0;
}
@@ -158,9 +160,10 @@ int main(int argc, char **argv)
if (!def.isValid()) {
/* see if it's a extension instead */
def = repo.definitionForFileName(QLatin1String("f.") + syntax);
if (!def.isValid())
if (!def.isValid()) {
/* see if it's a filename instead */
def = repo.definitionForFileName(syntax);
}
}
}
} else if (fromFileName) {
@@ -177,8 +180,9 @@ int main(int argc, char **argv)
QString outputFormat = parser.value(outputFormatOption);
if (0 == outputFormat.compare(QLatin1String("html"), Qt::CaseInsensitive)) {
QString title;
if (parser.isSet(titleOption))
if (parser.isSet(titleOption)) {
title = parser.value(titleOption);
}
HtmlHighlighter highlighter;
highlighter.setDefinition(def);

View File

@@ -28,7 +28,8 @@ elseif(CMAKE_CROSSCOMPILING)
else()
# host build
add_executable(katehighlightingindexer katehighlightingindexer.cpp ../lib/worddelimiters.cpp)
if(Qt5XmlPatterns_FOUND)
ecm_mark_nongui_executable(katehighlightingindexer)
if(Qt5XmlPatterns_FOUND AND NOT ECM_ENABLE_SANITIZERS)
target_link_libraries(katehighlightingindexer Qt5::XmlPatterns)
else()
target_link_libraries(katehighlightingindexer Qt5::Core)

View File

@@ -31,7 +31,8 @@ using KSyntaxHighlighting::Xml::attrToBool;
class HlFilesChecker
{
public:
void setDefinition(const QStringRef &verStr, const QString &filename, const QString &name)
template<typename T>
void setDefinition(const T &verStr, const QString &filename, const QString &name)
{
m_currentDefinition = &*m_definitions.insert(name, Definition{});
m_currentDefinition->languageName = name;
@@ -93,6 +94,12 @@ public:
continue;
}
auto markAsUsedContext = [](ContextName &ContextName) {
if (!ContextName.stay && ContextName.context) {
ContextName.context->isOnlyIncluded = false;
}
};
QMutableMapIterator<QString, Context> contextIt(contexts);
while (contextIt.hasNext()) {
contextIt.next();
@@ -100,12 +107,21 @@ public:
resolveContextName(definition, context, context.lineEndContext, context.line);
resolveContextName(definition, context, context.lineEmptyContext, context.line);
resolveContextName(definition, context, context.fallthroughContext, context.line);
markAsUsedContext(context.lineEndContext);
markAsUsedContext(context.lineEmptyContext);
markAsUsedContext(context.fallthroughContext);
for (auto &rule : context.rules) {
rule.parentContext = &context;
resolveContextName(definition, context, rule.context, rule.line);
if (rule.type != Context::Rule::Type::IncludeRules) {
markAsUsedContext(rule.context);
}
}
}
definition.firstContext = &*definition.contexts.find(definition.firstContextName);
auto *firstContext = &*definition.contexts.find(definition.firstContextName);
firstContext->isOnlyIncluded = false;
definition.firstContext = firstContext;
}
resolveIncludeRules();
@@ -118,6 +134,7 @@ public:
const auto usedContexts = extractUsedContexts();
QMap<const Definition *, const Definition *> maxVersionByDefinitions;
QMap<const Context::Rule *, IncludedRuleUnreachableBy> unreachableIncludedRules;
QMapIterator<QString, Definition> def(m_definitions);
while (def.hasNext()) {
@@ -135,14 +152,7 @@ public:
QSet<const Keywords *> referencedKeywords;
QSet<ItemDatas::Style> usedAttributeNames;
success = checkKeywordsList(definition, referencedKeywords) && success;
success = checkContexts(definition, referencedKeywords, usedAttributeNames, usedContexts) && success;
// search for non-existing or unreferenced keyword lists.
for (const auto &keywords : definition.keywordsList) {
if (!referencedKeywords.contains(&keywords)) {
qWarning() << filename << "line" << keywords.line << "unused keyword:" << keywords.name;
}
}
success = checkContexts(definition, referencedKeywords, usedAttributeNames, usedContexts, unreachableIncludedRules) && success;
// search for non-existing itemDatas.
const auto invalidNames = usedAttributeNames - definition.itemDatas.styleNames;
@@ -159,6 +169,56 @@ public:
}
}
QMutableMapIterator<const Context::Rule *, IncludedRuleUnreachableBy> unreachableIncludedRuleIt(unreachableIncludedRules);
while (unreachableIncludedRuleIt.hasNext()) {
unreachableIncludedRuleIt.next();
IncludedRuleUnreachableBy &unreachableRulesBy = unreachableIncludedRuleIt.value();
if (unreachableRulesBy.alwaysUnreachable) {
auto *rule = unreachableIncludedRuleIt.key();
if (!rule->parentContext->isOnlyIncluded) {
continue;
}
// remove duplicates rules
QSet<const Context::Rule *> rules;
auto &unreachableBy = unreachableRulesBy.unreachableBy;
unreachableBy.erase(std::remove_if(unreachableBy.begin(),
unreachableBy.end(),
[&](const RuleAndInclude &ruleAndInclude) {
if (rules.contains(ruleAndInclude.rule)) {
return true;
}
rules.insert(ruleAndInclude.rule);
return false;
}),
unreachableBy.end());
QString message;
message.reserve(128);
for (auto &ruleAndInclude : std::as_const(unreachableBy)) {
message += QStringLiteral("line ");
message += QString::number(ruleAndInclude.rule->line);
message += QStringLiteral(" [");
message += ruleAndInclude.rule->parentContext->name;
if (rule->filename != ruleAndInclude.rule->filename) {
message += QStringLiteral(" (");
message += ruleAndInclude.rule->filename;
message += QLatin1Char(')');
}
if (ruleAndInclude.includeRules) {
message += QStringLiteral(" via line ");
message += QString::number(ruleAndInclude.includeRules->line);
}
message += QStringLiteral("], ");
}
message.chop(2);
qWarning() << rule->filename << "line" << rule->line << "no IncludeRule can reach this rule, hidden by" << message;
success = false;
}
}
return success;
}
@@ -176,7 +236,7 @@ private:
int popCount = 0;
bool stay = false;
const Context *context = nullptr;
Context *context = nullptr;
};
struct Parser {
@@ -185,12 +245,13 @@ private:
QXmlStreamAttribute &attr;
bool success;
//! Read a string type attribute, \c sucess = \c false when \p str is not empty
//! Read a string type attribute, \c success = \c false when \p str is not empty
//! \return \c true when attr.name() == attrName, otherwise false
bool extractString(QString &str, const QString &attrName)
{
if (attr.name() != attrName)
if (attr.name() != attrName) {
return false;
}
str = attr.value().toString();
if (str.isEmpty()) {
@@ -201,24 +262,26 @@ private:
return true;
}
//! Read a bool type attribute, \c sucess = \c false when \p xmlBool is not \c XmlBool::Unspecified.
//! Read a bool type attribute, \c success = \c false when \p xmlBool is not \c XmlBool::Unspecified.
//! \return \c true when attr.name() == attrName, otherwise false
bool extractXmlBool(XmlBool &xmlBool, const QString &attrName)
{
if (attr.name() != attrName)
if (attr.name() != attrName) {
return false;
}
xmlBool = attr.value().isNull() ? XmlBool::Unspecified : attrToBool(attr.value()) ? XmlBool::True : XmlBool::False;
return true;
}
//! Read a positive integer type attribute, \c sucess = \c false when \p positive is already greater than or equal to 0
//! Read a positive integer type attribute, \c success = \c false when \p positive is already greater than or equal to 0
//! \return \c true when attr.name() == attrName, otherwise false
bool extractPositive(int &positive, const QString &attrName)
{
if (attr.name() != attrName)
if (attr.name() != attrName) {
return false;
}
bool ok = true;
positive = attr.value().toInt(&ok);
@@ -231,12 +294,13 @@ private:
return true;
}
//! Read a color, \c sucess = \c false when \p color is already greater than or equal to 0
//! Read a color, \c success = \c false when \p color is already greater than or equal to 0
//! \return \c true when attr.name() == attrName, otherwise false
bool checkColor(const QString &attrName)
{
if (attr.name() != attrName)
if (attr.name() != attrName) {
return false;
}
const auto value = attr.value().toString();
if (value.isEmpty() /*|| QColor(value).isValid()*/) {
@@ -247,16 +311,17 @@ private:
return true;
}
//! Read a QChar, \c sucess = \c false when \p c is not \c '\0' or does not have one char
//! Read a QChar, \c success = \c false when \p c is not \c '\0' or does not have one char
//! \return \c true when attr.name() == attrName, otherwise false
bool extractChar(QChar &c, const QString &attrName)
{
if (attr.name() != attrName)
if (attr.name() != attrName) {
return false;
}
if (attr.value().size() == 1)
if (attr.value().size() == 1) {
c = attr.value()[0];
else {
} else {
c = QLatin1Char('_');
qWarning() << filename << "line" << xml.lineNumber() << attrName << "must contain exactly one char:" << attr.value();
success = false;
@@ -268,8 +333,9 @@ private:
//! \return parsing status when \p isExtracted is \c true, otherwise \c false
bool checkIfExtracted(bool isExtracted)
{
if (isExtracted)
if (isExtracted) {
return success;
}
qWarning() << filename << "line" << xml.lineNumber() << "unknown attribute:" << attr.name();
return false;
@@ -400,18 +466,19 @@ private:
QString additionalDeliminator;
QString weakDeliminator;
// rules included by IncludeRules
// rules included by IncludeRules (without IncludeRule)
QVector<const Rule *> includedRules;
// IncludeRules included by IncludeRules
QSet<const Rule *> includedIncludeRules;
Context const *parentContext = nullptr;
QString filename;
bool parseElement(const QString &filename, QXmlStreamReader &xml)
{
this->filename = filename;
line = xml.lineNumber();
using Pair = QPair<QString, Type>;
@@ -579,6 +646,8 @@ private:
};
int line;
// becomes false when a context refers to it
bool isOnlyIncluded = true;
QString name;
QString attribute;
ContextName lineEndContext;
@@ -723,8 +792,9 @@ private:
{
Context context;
m_success = context.parseElement(m_currentDefinition->filename, xml) && m_success;
if (m_currentDefinition->firstContextName.isEmpty())
if (m_currentDefinition->firstContextName.isEmpty()) {
m_currentDefinition->firstContextName = context.name;
}
if (m_currentDefinition->contexts.contains(context.name)) {
qWarning() << m_currentDefinition->filename << "line" << xml.lineNumber() << "duplicate context:" << context.name;
m_success = false;
@@ -784,6 +854,7 @@ private:
m_success = false;
continue;
}
if (rule.context.popCount) {
qWarning() << definition.filename << "line" << rule.line << "IncludeRules with #pop prefix";
m_success = false;
@@ -794,6 +865,8 @@ private:
continue;
}
// resolve includedRules and includedIncludeRules
usedContexts.clear();
usedContexts.insert(rule.context.context);
contexts.clear();
@@ -866,11 +939,27 @@ private:
return usedContexts;
}
struct RuleAndInclude {
const Context::Rule *rule;
const Context::Rule *includeRules;
explicit operator bool() const
{
return rule;
}
};
struct IncludedRuleUnreachableBy {
QVector<RuleAndInclude> unreachableBy;
bool alwaysUnreachable = true;
};
//! Check contexts and rules
bool checkContexts(const Definition &definition,
QSet<const Keywords *> &referencedKeywords,
QSet<ItemDatas::Style> &usedAttributeNames,
const QSet<const Context *> &usedContexts) const
const QSet<const Context *> &usedContexts,
QMap<const Context::Rule *, IncludedRuleUnreachableBy> &unreachableIncludedRules) const
{
bool success = true;
@@ -892,16 +981,18 @@ private:
success = false;
}
if (!context.attribute.isEmpty())
if (!context.attribute.isEmpty()) {
usedAttributeNames.insert({context.attribute, context.line});
}
success = checkfallthrough(definition, context) && success;
success = checkUreachableRules(definition.filename, context) && success;
success = checkUreachableRules(definition.filename, context, unreachableIncludedRules) && success;
success = suggestRuleMerger(definition.filename, context) && success;
for (const auto &rule : context.rules) {
if (!rule.attribute.isEmpty())
if (!rule.attribute.isEmpty()) {
usedAttributeNames.insert({rule.attribute, rule.line});
}
success = checkLookAhead(rule) && success;
success = checkStringDetect(rule) && success;
success = checkAnyChar(rule) && success;
@@ -954,9 +1045,14 @@ private:
return false;
}
#define REG_ESCAPE_CHAR R"(\\(?:[^0BDPSWbdpswoux]|x[0-9a-fA-F]{2}|x\{[0-9a-fA-F]+\}|0\d\d|o\{[0-7]+\}|u[0-9a-fA-F]{4}))"
#define REG_CHAR "(?:" REG_ESCAPE_CHAR "|\\[(?:" REG_ESCAPE_CHAR "|.)\\]|[^[.^])"
// is RangeDetect
static const QRegularExpression isRange(QStringLiteral(
R"(^(\\(?:[^0BDPSWbdpswoux]|x[0-9a-fA-F]{2}|x\{[0-9a-fA-F]+\}|0\d\d|o\{[0-7]+\}|u[0-9a-fA-F]{4})|[^[.]|\[[^].\\]\])(?:\.|\[^\1\])\*[?*]?\1$)"));
static const QRegularExpression isRange(QStringLiteral("^\\^?" REG_CHAR "(?:"
"\\.\\*[?*]?" REG_CHAR "|"
"\\[\\^(" REG_ESCAPE_CHAR "|.)\\]\\*[?*]?\\1"
")$"));
if (( rule.lookAhead == XmlBool::True
|| rule.minimal == XmlBool::True
|| rule.string.contains(QStringLiteral(".*?"))
@@ -967,11 +1063,21 @@ private:
return false;
}
// is LineContinue
static const QRegularExpression isLineContinue(QStringLiteral("^\\^?" REG_CHAR "\\$$"));
if (reg.contains(isLineContinue)) {
auto extra = (reg[0] == QLatin1Char('^')) ? "with column=\"0\"" : "";
qWarning() << filename << "line" << rule.line << "RegExpr should be replaced by LineContinue:" << rule.string << extra;
return false;
}
// replace \c, \xhhh, \x{hhh...}, \0dd, \o{ddd}, \uhhhh, with _
static const QRegularExpression sanitize1(
QStringLiteral(R"(\\(?:[^0BDPSWbdpswoux]|x[0-9a-fA-F]{2}|x\{[0-9a-fA-F]+\}|0\d\d|o\{[0-7]+\}|u[0-9a-fA-F]{4}))"));
static const QRegularExpression sanitize1(QStringLiteral(REG_ESCAPE_CHAR));
reg.replace(sanitize1, QStringLiteral("_"));
#undef REG_CHAR
#undef REG_ESCAPE_CHAR
// use minimal or lazy operator
static const QRegularExpression isMinimal(QStringLiteral(
R"([.][*+][^][?+*()|$]*$)"));
@@ -1008,8 +1114,9 @@ private:
char const *extraMsg = rule.string.contains(QLatin1Char('^')) ? "+ column=\"0\" or firstNonSpace=\"1\"" : "";
qWarning() << rule.filename << "line" << rule.line << "RegExpr should be replaced by StringDetect / Detect2Chars / DetectChar" << extraMsg
<< ":" << rule.string;
if (len != reg.size())
if (len != reg.size()) {
qWarning() << rule.filename << "line" << rule.line << "insensitive=\"1\" missing:" << rule.string;
}
return false;
}
@@ -1019,8 +1126,8 @@ private:
// (^sas*) -> ok
// (^sa|s*) -> ko
// (^(sa|s*)) -> ok
auto first = qAsConst(reg).begin();
auto last = qAsConst(reg).end();
auto first = std::as_const(reg).begin();
auto last = std::as_const(reg).end();
int depth = 0;
while (QLatin1Char('(') == *first) {
@@ -1066,8 +1173,8 @@ private:
// add ^ with column=0
if (rule.column == 0 && !rule.isDotRegex) {
bool hasStartOfLine = false;
auto first = qAsConst(reg).begin();
auto last = qAsConst(reg).end();
auto first = std::as_const(reg).begin();
auto last = std::as_const(reg).end();
for (; first != last; ++first) {
if (*first == QLatin1Char('^')) {
hasStartOfLine = true;
@@ -1306,8 +1413,9 @@ private:
//! Search for additionalDeliminator/weakDeliminator which has no effect.
bool checkDelimiters(const Definition &definition, const Context::Rule &rule) const
{
if (rule.additionalDeliminator.isEmpty() && rule.weakDeliminator.isEmpty())
if (rule.additionalDeliminator.isEmpty() && rule.weakDeliminator.isEmpty()) {
return true;
}
bool success = true;
@@ -1472,16 +1580,39 @@ private:
//! - StringDetect, WordDetect, RegExpr with as prefix Detect2Chars or other strings
//! - duplicate rule (Int, Float, keyword with same String, etc)
//! - Rule hidden by a dot regex
bool checkUreachableRules(const QString &filename, const Context &context) const
bool checkUreachableRules(const QString &filename,
const Context &context,
QMap<const Context::Rule *, IncludedRuleUnreachableBy> &unreachableIncludedRules) const
{
struct RuleAndInclude {
const Context::Rule *rule;
const Context::Rule *includeRules;
if (context.isOnlyIncluded) {
return true;
}
explicit operator bool() const
struct Rule4 {
RuleAndInclude setRule(const Context::Rule &rule, const Context::Rule *includeRules = nullptr)
{
return rule;
auto set = [&](RuleAndInclude &ruleAndInclude) {
auto old = ruleAndInclude;
ruleAndInclude = {&rule, includeRules};
return old;
};
if (rule.firstNonSpace == XmlBool::True) {
return set(firstNonSpace);
} else if (rule.column == 0) {
return set(column0);
} else if (rule.column > 0) {
return set(columnGreaterThan0[rule.column]);
} else {
return set(normal);
}
}
private:
RuleAndInclude normal;
RuleAndInclude column0;
QMap<int, RuleAndInclude> columnGreaterThan0;
RuleAndInclude firstNonSpace;
};
// Associate QChar with RuleAndInclude
@@ -1489,8 +1620,9 @@ private:
/// Search RuleAndInclude associated with @p c.
RuleAndInclude find(QChar c) const
{
if (c.unicode() < 128)
if (c.unicode() < 128) {
return m_asciiMap[c.unicode()];
}
auto it = m_utf8Map.find(c);
return it == m_utf8Map.end() ? RuleAndInclude{nullptr, nullptr} : it.value();
}
@@ -1517,10 +1649,11 @@ private:
/// Associates @p c with a rule.
void append(QChar c, const Context::Rule &rule, const Context::Rule *includeRule = nullptr)
{
if (c.unicode() < 128)
if (c.unicode() < 128) {
m_asciiMap[c.unicode()] = {&rule, includeRule};
else
} else {
m_utf8Map[c] = {&rule, includeRule};
}
}
/// Associates each character of @p s with a rule.
@@ -1549,13 +1682,15 @@ private:
// Char4Tables::char is always added.
CharTableArray(Char4Tables &tables, const Context::Rule &rule)
{
if (rule.firstNonSpace == XmlBool::True)
if (rule.firstNonSpace == XmlBool::True) {
appendTable(tables.charsFirstNonSpace);
}
if (rule.column == 0)
if (rule.column == 0) {
appendTable(tables.charsColumn0);
else if (rule.column > 0)
} else if (rule.column > 0) {
appendTable(tables.charsColumnGreaterThan0[rule.column]);
}
appendTable(tables.chars);
}
@@ -1572,8 +1707,9 @@ private:
RuleAndInclude find(QChar c) const
{
for (int i = 0; i < m_size; ++i) {
if (auto ruleAndInclude = m_charTables[i]->find(c))
if (auto ruleAndInclude = m_charTables[i]->find(c)) {
return ruleAndInclude;
}
}
return RuleAndInclude{nullptr, nullptr};
}
@@ -1621,9 +1757,19 @@ private:
int m_size = 0;
};
struct ObservableRule {
const Context::Rule *rule;
const Context::Rule *includeRules;
bool hasResolvedIncludeRules() const
{
return rule == includeRules;
}
};
// Iterates over all the rules, including those in includedRules
struct RuleIterator {
RuleIterator(const QVector<Context::Rule> &rules, const Context::Rule &endRule)
RuleIterator(const QVector<ObservableRule> &rules, const ObservableRule &endRule)
: m_end(&endRule - rules.data())
, m_rules(rules)
{
@@ -1635,7 +1781,7 @@ private:
// if in includedRules
if (m_includedRules) {
++m_i2;
if (m_i2 != m_rules[m_i].includedRules.size()) {
if (m_i2 != m_includedRules->size()) {
return (*m_includedRules)[m_i2];
}
++m_i;
@@ -1643,10 +1789,10 @@ private:
}
// if is a includedRules
while (m_i < m_end && m_rules[m_i].type == Context::Rule::Type::IncludeRules) {
if (m_rules[m_i].includedRules.size()) {
while (m_i < m_end && m_rules[m_i].rule->type == Context::Rule::Type::IncludeRules) {
if (!m_rules[m_i].includeRules && m_rules[m_i].rule->includedRules.size()) {
m_i2 = 0;
m_includedRules = &m_rules[m_i].includedRules;
m_includedRules = &m_rules[m_i].rule->includedRules;
return (*m_includedRules)[m_i2];
}
++m_i;
@@ -1654,7 +1800,7 @@ private:
if (m_i < m_end) {
++m_i;
return &m_rules[m_i - 1];
return m_rules[m_i - 1].rule;
}
return nullptr;
@@ -1663,14 +1809,14 @@ private:
/// \return current IncludeRules or nullptr
const Context::Rule *currentIncludeRules() const
{
return m_includedRules ? &m_rules[m_i] : nullptr;
return m_includedRules ? m_rules[m_i].rule : m_rules[m_i].includeRules;
}
private:
int m_i = 0;
int m_i2;
int m_end;
const QVector<Context::Rule> &m_rules;
const QVector<ObservableRule> &m_rules;
const QVector<const Context::Rule *> *m_includedRules = nullptr;
};
@@ -1680,20 +1826,24 @@ private:
void append(const Context::Rule &rule, const Context::Rule *includedRule)
{
auto array = extractDotRegexes(rule);
if (array[0])
if (array[0]) {
*array[0] = {&rule, includedRule};
if (array[1])
}
if (array[1]) {
*array[1] = {&rule, includedRule};
}
}
/// Search dot regex which hides @p rule
RuleAndInclude find(const Context::Rule &rule)
{
auto array = extractDotRegexes(rule);
if (array[0])
if (array[0]) {
return *array[0];
if (array[1])
}
if (array[1]) {
return *array[1];
}
return RuleAndInclude{};
}
@@ -1707,13 +1857,15 @@ private:
if (rule.firstNonSpace != XmlBool::True && rule.column == -1) {
ret[0] = &dotRegex;
} else {
if (rule.firstNonSpace == XmlBool::True)
if (rule.firstNonSpace == XmlBool::True) {
ret[0] = &dotRegexFirstNonSpace;
}
if (rule.column == 0)
if (rule.column == 0) {
ret[1] = &dotRegexColumn0;
else if (rule.column > 0)
} else if (rule.column > 0) {
ret[1] = &dotRegexColumnGreaterThan0[rule.column];
}
}
return ret;
@@ -1734,23 +1886,44 @@ private:
// characters of LineContinue
Char4Tables lineContinueChars;
RuleAndInclude intRule{};
RuleAndInclude floatRule{};
RuleAndInclude hlCCharRule{};
RuleAndInclude hlCOctRule{};
RuleAndInclude hlCHexRule{};
RuleAndInclude hlCStringCharRule{};
Rule4 intRule{};
Rule4 floatRule{};
Rule4 hlCCharRule{};
Rule4 hlCOctRule{};
Rule4 hlCHexRule{};
Rule4 hlCStringCharRule{};
Rule4 detectIdentifierRule{};
// Contains includedRules and included includedRules
QMap<Context const*, RuleAndInclude> includeContexts;
DotRegex dotRegex;
QVector<ObservableRule> observedRules;
observedRules.reserve(context.rules.size());
for (const Context::Rule &rule : context.rules) {
const Context::Rule *includeRule = nullptr;
if (rule.type == Context::Rule::Type::IncludeRules) {
auto *context = rule.context.context;
if (context && context->isOnlyIncluded) {
includeRule = &rule;
}
}
observedRules.push_back({&rule, includeRule});
if (includeRule) {
for (const Context::Rule *rule2 : rule.includedRules) {
observedRules.push_back({rule2, includeRule});
}
}
}
for (auto &observedRule : observedRules) {
const Context::Rule &rule = *observedRule.rule;
bool isUnreachable = false;
QVector<RuleAndInclude> unreachableBy;
// declare rule as unreacheable if ruleAndInclude is not empty
// declare rule as unreachable if ruleAndInclude is not empty
auto updateUnreachable1 = [&](RuleAndInclude ruleAndInclude) {
if (ruleAndInclude) {
isUnreachable = true;
@@ -1758,7 +1931,7 @@ private:
}
};
// declare rule as unreacheable if ruleAndIncludes is not empty
// declare rule as unreachable if ruleAndIncludes is not empty
auto updateUnreachable2 = [&](const QVector<RuleAndInclude> &ruleAndIncludes) {
if (!ruleAndIncludes.isEmpty()) {
isUnreachable = true;
@@ -1810,43 +1983,42 @@ private:
// check if hidden by DetectChar/AnyChar
case Context::Rule::Type::HlCChar:
updateUnreachable1(CharTableArray(detectChars, rule).find(QLatin1Char('\'')));
updateUnreachable1(hlCCharRule);
hlCCharRule = {&rule, nullptr};
updateUnreachable1(hlCCharRule.setRule(rule));
break;
// check if hidden by DetectChar/AnyChar
case Context::Rule::Type::HlCHex:
updateUnreachable1(CharTableArray(detectChars, rule).find(QLatin1Char('0')));
updateUnreachable1(hlCHexRule);
hlCHexRule = {&rule, nullptr};
updateUnreachable1(hlCHexRule.setRule(rule));
break;
// check if hidden by DetectChar/AnyChar
case Context::Rule::Type::HlCOct:
updateUnreachable1(CharTableArray(detectChars, rule).find(QLatin1Char('0')));
updateUnreachable1(hlCOctRule);
hlCOctRule = {&rule, nullptr};
updateUnreachable1(hlCOctRule.setRule(rule));
break;
// check if hidden by DetectChar/AnyChar
case Context::Rule::Type::HlCStringChar:
updateUnreachable1(CharTableArray(detectChars, rule).find(QLatin1Char('\\')));
updateUnreachable1(hlCStringCharRule);
hlCStringCharRule = {&rule, nullptr};
updateUnreachable1(hlCStringCharRule.setRule(rule));
break;
// check if hidden by DetectChar/AnyChar
case Context::Rule::Type::Int:
updateUnreachable2(CharTableArray(detectChars, rule).find(QStringLiteral("0123456789")));
updateUnreachable1(intRule);
intRule = {&rule, nullptr};
updateUnreachable1(intRule.setRule(rule));
break;
// check if hidden by DetectChar/AnyChar
case Context::Rule::Type::Float:
updateUnreachable2(CharTableArray(detectChars, rule).find(QStringLiteral("0123456789.")));
updateUnreachable1(floatRule);
floatRule = {&rule, nullptr};
updateUnreachable1(floatRule.setRule(rule));
break;
// check if hidden by another DetectIdentifier rule
case Context::Rule::Type::DetectIdentifier:
updateUnreachable1(detectIdentifierRule.setRule(rule));
break;
// check if hidden by DetectChar/AnyChar or another LineContinue
@@ -1865,10 +2037,11 @@ private:
case Context::Rule::Type::RangeDetect:
updateUnreachable1(CharTableArray(detectChars, rule).find(rule.char0));
if (!isUnreachable) {
RuleIterator ruleIterator(context.rules, rule);
RuleIterator ruleIterator(observedRules, observedRule);
while (const auto *rulePtr = ruleIterator.next()) {
if (isUnreachable)
if (isUnreachable) {
break;
}
const auto &rule2 = *rulePtr;
if (rule2.type == rule.type && isCompatible(rule2) && rule.char0 == rule2.char0 && rule.char1 == rule2.char1) {
updateUnreachable1({&rule2, ruleIterator.currentIncludeRules()});
@@ -1884,10 +2057,11 @@ private:
}
// check that `rule` does not have another RegExpr as a prefix
RuleIterator ruleIterator(context.rules, rule);
RuleIterator ruleIterator(observedRules, observedRule);
while (const auto *rulePtr = ruleIterator.next()) {
if (isUnreachable)
if (isUnreachable) {
break;
}
const auto &rule2 = *rulePtr;
if (rule2.type == Context::Rule::Type::RegExpr && isCompatible(rule2) && rule.insensitive == rule2.insensitive
&& rule.dynamic == rule2.dynamic && rule.string.startsWith(rule2.string)) {
@@ -1902,10 +2076,11 @@ private:
case Context::Rule::Type::StringDetect: {
// check that dynamic `rule` does not have another dynamic StringDetect as a prefix
if (rule.type == Context::Rule::Type::StringDetect && rule.dynamic == XmlBool::True) {
RuleIterator ruleIterator(context.rules, rule);
RuleIterator ruleIterator(observedRules, observedRule);
while (const auto *rulePtr = ruleIterator.next()) {
if (isUnreachable)
if (isUnreachable) {
break;
}
const auto &rule2 = *rulePtr;
if (rule2.type != Context::Rule::Type::StringDetect || rule2.dynamic != XmlBool::True || !isCompatible(rule2)) {
@@ -1963,10 +2138,11 @@ private:
// combination of uppercase and lowercase
RuleAndInclude detect2CharsInsensitives[]{{}, {}, {}, {}};
RuleIterator ruleIterator(context.rules, rule);
RuleIterator ruleIterator(observedRules, observedRule);
while (const auto *rulePtr = ruleIterator.next()) {
if (isUnreachable)
if (isUnreachable) {
break;
}
const auto &rule2 = *rulePtr;
const bool isSensitive = (rule2.insensitive == XmlBool::True);
const auto caseSensitivity = isSensitive ? Qt::CaseInsensitive : Qt::CaseSensitive;
@@ -2030,10 +2206,11 @@ private:
// check if hidden by another keyword rule
case Context::Rule::Type::keyword: {
RuleIterator ruleIterator(context.rules, rule);
RuleIterator ruleIterator(observedRules, observedRule);
while (const auto *rulePtr = ruleIterator.next()) {
if (isUnreachable)
if (isUnreachable) {
break;
}
const auto &rule2 = *rulePtr;
if (rule2.type == Context::Rule::Type::keyword && isCompatible(rule2) && rule.string == rule2.string) {
updateUnreachable1({&rule2, ruleIterator.currentIncludeRules()});
@@ -2049,6 +2226,10 @@ private:
// <includedRules .../> <- reference a <DetectChar char="{" /> who will be added
// <DetectChar char="{" /> <- hidden by previous rule
case Context::Rule::Type::IncludeRules:
if (observedRule.includeRules && !observedRule.hasResolvedIncludeRules()) {
break;
}
if (auto &ruleAndInclude = includeContexts[rule.context.context]) {
updateUnreachable1(ruleAndInclude);
}
@@ -2060,6 +2241,10 @@ private:
includeContexts.insert(rulePtr->context.context, RuleAndInclude{rulePtr, &rule});
}
if (observedRule.includeRules) {
break;
}
for (const auto *rulePtr : rule.includedRules) {
const auto &rule2 = *rulePtr;
switch (rule2.type) {
@@ -2087,27 +2272,27 @@ private:
}
case Context::Rule::Type::HlCChar:
hlCCharRule = {&rule2, &rule};
hlCCharRule.setRule(rule2, &rule);
break;
case Context::Rule::Type::HlCHex:
hlCHexRule = {&rule2, &rule};
hlCHexRule.setRule(rule2, &rule);
break;
case Context::Rule::Type::HlCOct:
hlCOctRule = {&rule2, &rule};
hlCOctRule.setRule(rule2, &rule);
break;
case Context::Rule::Type::HlCStringChar:
hlCStringCharRule = {&rule2, &rule};
hlCStringCharRule.setRule(rule2, &rule);
break;
case Context::Rule::Type::Int:
intRule = {&rule2, &rule};
intRule.setRule(rule2, &rule);
break;
case Context::Rule::Type::Float:
floatRule = {&rule2, &rule};
floatRule.setRule(rule2, &rule);
break;
case Context::Rule::Type::LineContinue: {
@@ -2136,12 +2321,18 @@ private:
}
break;
case Context::Rule::Type::DetectIdentifier:
case Context::Rule::Type::Unknown:
break;
}
if (isUnreachable) {
if (observedRule.includeRules && !observedRule.hasResolvedIncludeRules()) {
auto &unreachableIncludedRule = unreachableIncludedRules[&rule];
if (isUnreachable && unreachableIncludedRule.alwaysUnreachable) {
unreachableIncludedRule.unreachableBy.append(unreachableBy);
} else {
unreachableIncludedRule.alwaysUnreachable = false;
}
} else if (isUnreachable) {
success = false;
QString message;
message.reserve(128);
@@ -2165,7 +2356,7 @@ private:
message += QStringLiteral(", ");
}
message.chop(2);
qWarning() << filename << "line" << rule.line << "unreachable element by" << message;
qWarning() << filename << "line" << rule.line << "unreachable rule by" << message;
}
}
@@ -2179,8 +2370,9 @@ private:
{
bool success = true;
if (context.rules.isEmpty())
if (context.rules.isEmpty()) {
return success;
}
auto it = context.rules.begin();
const auto end = context.rules.end() - 1;
@@ -2249,7 +2441,7 @@ private:
//! - "#pop!Comment" -> "Comment"
//! - "##ISO C++" -> ""
//! - "Comment##ISO C++"-> "Comment" in ISO C++
void resolveContextName(Definition &definition, const Context &context, ContextName &contextName, int line)
void resolveContextName(Definition &definition, Context &context, ContextName &contextName, int line)
{
QString name = contextName.name;
if (name.isEmpty()) {
@@ -2281,8 +2473,9 @@ private:
const int idx = name.indexOf(QStringLiteral("##"));
if (idx == -1) {
auto it = definition.contexts.find(name);
if (it != definition.contexts.end())
if (it != definition.contexts.end()) {
contextName.context = &*it;
}
} else {
auto defName = name.mid(idx + 2);
auto listName = name.left(idx);
@@ -2392,14 +2585,16 @@ int main(int argc, char *argv[])
QCoreApplication app(argc, argv);
// ensure enough arguments are passed
if (app.arguments().size() < 3)
if (app.arguments().size() < 3) {
return 1;
}
#ifdef QT_XMLPATTERNS_LIB
// open schema
QXmlSchema schema;
if (!schema.load(QUrl::fromLocalFile(app.arguments().at(2))))
if (!schema.load(QUrl::fromLocalFile(app.arguments().at(2)))) {
return 2;
}
#endif
const QString hlFilenamesListing = app.arguments().value(3);
@@ -2422,7 +2617,7 @@ int main(int argc, char *argv[])
HlFilesChecker filesChecker;
QVariantMap hls;
int anyError = 0;
for (const QString &hlFilename : qAsConst(hlFilenames)) {
for (const QString &hlFilename : std::as_const(hlFilenames)) {
QFile hlFile(hlFilename);
if (!hlFile.open(QIODevice::ReadOnly)) {
qWarning("Failed to open %s", qPrintable(hlFilename));
@@ -2456,7 +2651,7 @@ int main(int argc, char *argv[])
QVariantMap hl;
// transfer text attributes
for (const QString &attribute : qAsConst(textAttributes)) {
for (const QString &attribute : std::as_const(textAttributes)) {
hl[attribute] = xml.attributes().value(attribute).toString();
}
@@ -2489,17 +2684,20 @@ int main(int argc, char *argv[])
filesChecker.resolveContexts();
if (!filesChecker.check())
if (!filesChecker.check()) {
anyError = 7;
}
// bail out if any problem was seen
if (anyError)
if (anyError) {
return anyError;
}
// create outfile, after all has worked!
QFile outFile(app.arguments().at(1));
if (!outFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
if (!outFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
return 9;
}
// write out json
outFile.write(QCborValue::fromVariant(QVariant(hls)).toCbor());

View File

@@ -1,6 +1,8 @@
add_library(KF5SyntaxHighlighting)
ecm_create_qm_loader(syntax_highlighting_QM_LOADER syntaxhighlighting5_qt)
set(syntax_highlighting_srcs
target_sources(KF5SyntaxHighlighting PRIVATE
abstracthighlighter.cpp
context.cpp
contextswitch.cpp
@@ -20,8 +22,9 @@ set(syntax_highlighting_srcs
themedata.cpp
worddelimiters.cpp
${syntax_highlighting_QM_LOADER}
$<TARGET_OBJECTS:SyntaxHighlightingData>
)
ecm_qt_declare_logging_category(syntax_highlighting_srcs
ecm_qt_declare_logging_category(KF5SyntaxHighlighting
HEADER ksyntaxhighlighting_logging.h
IDENTIFIER KSyntaxHighlighting::Log
CATEGORY_NAME kf.syntaxhighlighting
@@ -30,16 +33,27 @@ ecm_qt_declare_logging_category(syntax_highlighting_srcs
EXPORT KSYNTAXHIGHLIGHTING
)
add_library(KF5SyntaxHighlighting ${syntax_highlighting_srcs} $<TARGET_OBJECTS:SyntaxHighlightingData>)
generate_export_header(KF5SyntaxHighlighting BASE_NAME KSyntaxHighlighting)
ecm_generate_export_header(KF5SyntaxHighlighting
BASE_NAME KSyntaxHighlighting
GROUP_BASE_NAME KF
VERSION ${KF_VERSION}
DEPRECATED_BASE_VERSION 0
DEPRECATION_VERSIONS 5.87
EXCLUDE_DEPRECATED_BEFORE_AND_AT ${EXCLUDE_DEPRECATED_BEFORE_AND_AT}
)
set_target_properties(KF5SyntaxHighlighting PROPERTIES
VERSION ${SyntaxHighlighting_VERSION_STRING}
VERSION ${SyntaxHighlighting_VERSION}
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)
target_link_libraries(KF5SyntaxHighlighting
PUBLIC
Qt5::Gui
PRIVATE
Qt5::Network
)
ecm_generate_headers(SyntaxHighlighting_HEADERS
HEADER_NAMES
@@ -52,6 +66,7 @@ ecm_generate_headers(SyntaxHighlighting_HEADERS
State
SyntaxHighlighter
Theme
WildcardMatcher
REQUIRED_HEADERS SyntaxHighlighting_HEADERS
)

View File

@@ -36,11 +36,13 @@ void AbstractHighlighterPrivate::ensureDefinitionLoaded()
defData = DefinitionData::get(m_definition);
}
if (Q_UNLIKELY(!defData->repo && !defData->fileName.isEmpty()))
if (Q_UNLIKELY(!defData->repo && !defData->fileName.isEmpty())) {
qCCritical(Log) << "Repository got deleted while a highlighter is still active!";
}
if (m_definition.isValid())
if (m_definition.isValid()) {
defData->load();
}
}
AbstractHighlighter::AbstractHighlighter()
@@ -85,7 +87,7 @@ void AbstractHighlighter::setTheme(const 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)
static inline int firstNonSpaceChar(QStringView text)
{
for (int i = 0; i < text.length(); ++i) {
if (!text[i].isSpace()) {
@@ -95,7 +97,14 @@ static inline int firstNonSpaceChar(const QString &text)
return text.size();
}
#if KSYNTAXHIGHLIGHTING_BUILD_DEPRECATED_SINCE(5, 87)
State AbstractHighlighter::highlightLine(const QString &text, const State &state)
{
return highlightLine(QStringView(text), state);
}
#endif
State AbstractHighlighter::highlightLine(QStringView text, const State &state)
{
Q_D(AbstractHighlighter);
@@ -145,8 +154,9 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
* skipping empty lines after a line continuation character (see bug 405903)
*/
} else if (!stateData->topContext()->lineEndContext().isStay()
&& !d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList()))
&& !d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList())) {
break;
}
// guard against endless loops
++endlessLoopingCounter;
@@ -160,7 +170,8 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
return newState;
}
int offset = 0, beginOffset = 0;
int offset = 0;
int beginOffset = 0;
bool lineContinuation = false;
/**
@@ -247,8 +258,9 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
skipOffsets.clear();
}
const auto currentSkipOffset = skipOffsets.value(rule.get());
if (currentSkipOffset < 0 || currentSkipOffset > offset)
if (currentSkipOffset < 0 || currentSkipOffset > offset) {
continue;
}
const auto newResult = rule->doMatch(text, offset, stateData->topCaptures());
newOffset = newResult.offset();
@@ -265,8 +277,9 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
}
}
if (newOffset <= offset)
if (newOffset <= offset) {
continue;
}
/**
* apply folding.
@@ -274,12 +287,14 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
* - rule with endRegion + beginRegion: in endRegion, the length is 0
* - rule with lookAhead: length is 0
*/
if (rule->endRegion().isValid() && rule->beginRegion().isValid())
if (rule->endRegion().isValid() && rule->beginRegion().isValid()) {
applyFolding(offset, 0, rule->endRegion());
else if (rule->endRegion().isValid())
} else if (rule->endRegion().isValid()) {
applyFolding(offset, rule->isLookAhead() ? 0 : newOffset - offset, rule->endRegion());
if (rule->beginRegion().isValid())
}
if (rule->beginRegion().isValid()) {
applyFolding(offset, rule->isLookAhead() ? 0 : newOffset - offset, rule->beginRegion());
}
if (rule->isLookAhead()) {
Q_ASSERT(!rule->context().isStay());
@@ -290,12 +305,14 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
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))
if (newOffset == text.size() && std::dynamic_pointer_cast<LineContinue>(rule)) {
lineContinuation = true;
}
break;
}
if (isLookAhead)
if (isLookAhead) {
continue;
}
if (newOffset <= offset) { // no matching rule
if (stateData->topContext()->fallthrough()) {
@@ -316,8 +333,9 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
* on format change, apply the last one and switch to new one
*/
if (newFormat != currentFormat && newFormat->id() != currentFormat->id()) {
if (offset > 0)
if (offset > 0) {
applyFormat(beginOffset, offset - beginOffset, *currentFormat);
}
beginOffset = offset;
currentFormat = newFormat;
}
@@ -333,8 +351,9 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
/**
* apply format for remaining text, if any
*/
if (beginOffset < offset)
if (beginOffset < offset) {
applyFormat(beginOffset, text.size() - beginOffset, *currentFormat);
}
/**
* handle line end context switches
@@ -344,8 +363,9 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
{
int endlessLoopingCounter = 0;
while (!stateData->topContext()->lineEndContext().isStay() && !lineContinuation) {
if (!d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList()))
if (!d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList())) {
break;
}
// guard against endless loops
++endlessLoopingCounter;

View File

@@ -108,6 +108,15 @@ protected:
AbstractHighlighter();
AbstractHighlighter(AbstractHighlighterPrivate *dd);
#if KSYNTAXHIGHLIGHTING_ENABLE_DEPRECATED_SINCE(5, 87)
/**
* @copydoc highlightLine(QStringView,const State&)
* @deprecated since 5.87, use highlightLine(QStringView, const State&) instead.
*/
// no deprecation warning, as removal of this will automatically "port" the using code
State highlightLine(const QString &text, const State &state);
#endif
// 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
@@ -120,14 +129,14 @@ protected:
* @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
* @returns The state of the highlighting 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);
State highlightLine(QStringView text, const State &state);
/**
* Reimplement this to apply formats to your output. The provided @p format

View File

@@ -33,10 +33,6 @@ struct CieLab {
double b;
};
#ifndef M_PI
constexpr double M_PI = 3.14159265358979323846;
#endif
// clang-format off
// xterm color reference
// constexpr Rgb888 xterm256Colors[] {
@@ -388,10 +384,11 @@ CieLab rgbToLab(QRgb rgb)
// Perform the inverse gamma companding for a sRGB color
// http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html
auto inverseGammaCompanding = [](int c) {
if (c <= 10)
if (c <= 10) {
return c / (255.0 * 12.92);
else
} else {
return std::pow((c / 255.0 + 0.055) / 1.055, 2.4);
}
};
const double r = inverseGammaCompanding(qRed(rgb));
@@ -404,10 +401,11 @@ CieLab rgbToLab(QRgb rgb)
// http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_Lab.html
auto f = [](double t) {
if (t > 216.0 / 24389.0)
if (t > 216.0 / 24389.0) {
return std::cbrt(t);
else
} else {
return t * (24389.0 / (27.0 * 116.0)) + 4.0 / 29.0;
}
};
const double f_x = f(x / illuminant_D65[0]);
@@ -440,8 +438,9 @@ inline double pow2(double x)
inline double computeHPrime(double a_prime, double b)
{
if (std::abs(a_prime) < epsilon && std::abs(b) < epsilon)
if (std::abs(a_prime) < epsilon && std::abs(b) < epsilon) {
return 0.0;
}
const double value = std::atan2(b, a_prime) * 180.0 / M_PI;
return (value < 0.0) ? value + 360.0 : value;
@@ -449,34 +448,38 @@ inline double computeHPrime(double a_prime, double b)
inline double computeDeltaHPrime(double C1_prime, double C2_prime, double h1_prime, double h2_prime)
{
if (C1_prime * C2_prime < epsilon)
if (C1_prime * C2_prime < epsilon) {
return 0.0;
}
const double diff = h2_prime - h1_prime;
if (std::abs(diff) <= 180.0)
if (std::abs(diff) <= 180.0) {
return diff;
else if (diff > 180.0)
} else if (diff > 180.0) {
return diff - 360.0;
else
} else {
return diff + 360.0;
}
}
inline double computeHPrimeBar(double C1_prime, double C2_prime, double h1_prime, double h2_prime)
{
const double sum = h1_prime + h2_prime;
if (C1_prime * C2_prime < epsilon)
if (C1_prime * C2_prime < epsilon) {
return sum;
}
const double dist = std::abs(h1_prime - h2_prime);
if (dist <= 180.0)
if (dist <= 180.0) {
return 0.5 * sum;
else if (sum < 360.0)
} else if (sum < 360.0) {
return 0.5 * (sum + 360.0);
else
} else {
return 0.5 * (sum - 360.0);
}
}
/// Calculate the perceptual color difference based on CIEDE2000.
@@ -702,7 +705,7 @@ struct GraphLine {
const int n2 = offset - labelLineLength;
labelLineLength += n2 + 1;
fillLine(labelLine, n2);
labelLine += graphLine.rightRef(graphLine.size() - ps1);
labelLine += QStringView(graphLine).right(graphLine.size() - ps1);
}
}
@@ -781,8 +784,9 @@ public:
state = highlightLine(currentLine, state);
if (hasSeparator) {
if (!firstLine)
if (!firstLine) {
out << QStringLiteral("\x1b[0m────────────────────────────────────────────────────\x1b[K\n");
}
firstLine = false;
}
@@ -793,14 +797,15 @@ public:
for (const auto &fragment : m_highlightedFragments) {
auto const &ansiStyle = ansiStyles[fragment.formatId];
out << ansiStyle.first << currentLine.midRef(fragment.offset, fragment.length) << ansiStyle.second;
out << ansiStyle.first << QStringView(currentLine).mid(fragment.offset, fragment.length) << ansiStyle.second;
}
out << QStringLiteral("\x1b[K\n");
if (hasFormatOrContextTrace && !m_highlightedFragments.empty()) {
if (m_hasContextTrace || m_hasStackSizeTrace)
if (m_hasContextTrace || m_hasStackSizeTrace) {
appendContextNames(oldState, currentLine);
}
printFormats(out, infoStyle, ansiStyles);
out << resetBgColor;
@@ -817,8 +822,9 @@ public:
void applyFolding(int offset, int /*length*/, FoldingRegion region) override
{
if (!m_hasRegionTrace)
if (!m_hasRegionTrace) {
return;
}
const auto id = region.id();
@@ -829,8 +835,9 @@ public:
auto &previousRegion = m_regions[m_regions.size() - 2];
if (previousRegion.state == Region::State::Close && previousRegion.offset == offset) {
std::swap(previousRegion, m_regions.back());
if (previousRegion.bindIndex != -1)
if (previousRegion.bindIndex != -1) {
m_regions[previousRegion.bindIndex].bindIndex = m_regions.size() - 1;
}
}
}
++m_regionDepth;
@@ -840,10 +847,11 @@ public:
auto eit = m_regions.rend();
for (int depth = 0; it != eit; ++it) {
if (it->regionId == id && it->bindIndex < 0) {
if (it->state == Region::State::Close)
if (it->state == Region::State::Close) {
++depth;
else if (--depth < 0)
} else if (--depth < 0) {
break;
}
}
}
@@ -868,8 +876,9 @@ private:
void initRegionStyles(const std::vector<QPair<QString, QString>> &ansiStyles)
{
m_regionStyles.resize(ansiStyles.size());
for (std::size_t i = 0; i < m_regionStyles.size(); ++i)
for (std::size_t i = 0; i < m_regionStyles.size(); ++i) {
m_regionStyles[i] = ansiStyles[i].first;
}
std::sort(m_regionStyles.begin(), m_regionStyles.end());
m_regionStyles.erase(std::unique(m_regionStyles.begin(), m_regionStyles.end()), m_regionStyles.end());
@@ -1216,7 +1225,7 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
}
// initialize ansiStyles
for (auto &&definition : qAsConst(definitions)) {
for (auto &&definition : std::as_const(definitions)) {
const auto formats = definition.formats();
for (auto &&format : formats) {
const auto id = format.id();
@@ -1236,20 +1245,26 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
const bool hasUnderline = format.isUnderline(theme);
const bool hasStrikeThrough = format.isStrikeThrough(theme);
if (hasFg)
if (hasFg) {
buffer.appendForeground(format.textColor(theme).rgb(), is256Colors, colorCache);
else
} else {
buffer.append(foregroundDefaultColor);
if (hasBg)
}
if (hasBg) {
buffer.appendBackground(format.backgroundColor(theme).rgb(), is256Colors, colorCache);
if (hasBold)
}
if (hasBold) {
buffer.append(QLatin1String("1;"));
if (hasItalic)
}
if (hasItalic) {
buffer.append(QLatin1String("3;"));
if (hasUnderline)
}
if (hasUnderline) {
buffer.append(QLatin1String("4;"));
if (hasStrikeThrough)
}
if (hasStrikeThrough) {
buffer.append(QLatin1String("9;"));
}
// if there is ANSI style
if (buffer.latin1().size() > 2) {
@@ -1266,14 +1281,18 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
d->ansiStyles[id].second = buffer.latin1();
} else if (hasEffect) {
buffer.append(QLatin1String("\x1b["));
if (hasBold)
if (hasBold) {
buffer.append(QLatin1String("21;"));
if (hasItalic)
}
if (hasItalic) {
buffer.append(QLatin1String("23;"));
if (hasUnderline)
}
if (hasUnderline) {
buffer.append(QLatin1String("24;"));
if (hasStrikeThrough)
}
if (hasStrikeThrough) {
buffer.append(QLatin1String("29;"));
}
buffer.setFinalStyle();
d->ansiStyles[id].second = buffer.latin1();
}
@@ -1301,10 +1320,11 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
d->currentLine = in.readLine();
state = highlightLine(d->currentLine, state);
if (useEditorBackground)
if (useEditorBackground) {
d->out << QStringLiteral("\x1b[K\n");
else
} else {
d->out << QLatin1Char('\n');
}
}
} else {
AnsiBuffer buffer;
@@ -1328,5 +1348,5 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
void AnsiHighlighter::applyFormat(int offset, int length, const Format &format)
{
auto const &ansiStyle = d->ansiStyles[format.id()];
d->out << ansiStyle.first << d->currentLine.midRef(offset, length) << ansiStyle.second;
d->out << ansiStyle.first << QStringView(d->currentLine).mid(offset, length) << ansiStyle.second;
}

View File

@@ -30,8 +30,9 @@ void Context::setDefinition(const DefinitionRef &def)
bool Context::indentationBasedFoldingEnabled() const
{
if (m_noIndentationBasedFolding)
if (m_noIndentationBasedFolding) {
return false;
}
return m_def.definition().indentationBasedFoldingEnabled();
}
@@ -56,8 +57,9 @@ void Context::load(QXmlStreamReader &reader)
auto rule = Rule::create(reader.name());
if (rule) {
rule->setDefinition(m_def.definition());
if (rule->load(reader))
if (rule->load(reader)) {
m_rules.push_back(std::move(rule));
}
} else {
reader.skipCurrentElement();
}
@@ -79,8 +81,9 @@ void Context::resolveContexts()
m_lineEndContext.resolve(def);
m_lineEmptyContext.resolve(def);
m_fallthroughContext.resolve(def);
for (const auto &rule : m_rules)
for (const auto &rule : m_rules) {
rule->resolveContext();
}
}
Context::ResolveState Context::resolveState()
@@ -100,8 +103,9 @@ Context::ResolveState Context::resolveState()
void Context::resolveIncludes()
{
if (resolveState() == Resolved)
if (resolveState() == Resolved) {
return;
}
if (resolveState() == Resolving) {
qCWarning(Log) << "Cyclic dependency!";
return;
@@ -129,10 +133,11 @@ void Context::resolveIncludes()
}
auto defData = DefinitionData::get(def);
defData->load();
if (inc->contextName().isEmpty())
if (inc->contextName().isEmpty()) {
context = defData->initialContext();
else
} else {
context = defData->contextByName(inc->contextName());
}
}
if (!context) {
qCWarning(Log) << "Unable to resolve include rule for definition" << inc->contextName() << "##" << inc->definitionName() << "in"

View File

@@ -29,8 +29,9 @@ Context *ContextSwitch::context() const
void ContextSwitch::parse(QStringView contextInstr)
{
if (contextInstr.isEmpty() || contextInstr == QLatin1String("#stay"))
if (contextInstr.isEmpty() || contextInstr == QLatin1String("#stay")) {
return;
}
if (contextInstr.startsWith(QLatin1String("#pop!"))) {
++m_popCount;
@@ -60,13 +61,15 @@ void ContextSwitch::resolve(const Definition &def)
d = DefinitionData::get(def)->repo->definitionForName(m_defName);
auto data = DefinitionData::get(d);
data->load();
if (m_contextName.isEmpty())
if (m_contextName.isEmpty()) {
m_context = data->initialContext();
}
}
if (!m_contextName.isEmpty()) {
m_context = DefinitionData::get(d)->contextByName(m_contextName);
if (!m_context)
if (!m_context) {
qCWarning(Log) << "cannot find context" << m_contextName << "in" << def.name();
}
}
}

View File

@@ -51,30 +51,21 @@ DefinitionData *DefinitionData::get(const Definition &def)
Definition::Definition()
: d(new DefinitionData)
{
}
Definition::Definition(const Definition &other)
: d(other.d)
{
d->q = *this;
}
Definition::Definition(Definition &&other) noexcept = default;
Definition::Definition(const Definition &) = default;
Definition::~Definition() = default;
Definition &Definition::operator=(Definition &&other) noexcept = default;
Definition &Definition::operator=(const Definition &) = default;
Definition::Definition(std::shared_ptr<DefinitionData> &&dd)
: d(std::move(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;
@@ -223,8 +214,9 @@ bool Definition::setKeywordList(const QString &name, const QStringList &content)
if (list) {
list->setKeywordList(content);
return true;
} else
} else {
return false;
}
}
QVector<Format> Definition::formats() const
@@ -251,7 +243,7 @@ QVector<Definition> Definition::includedDefinitions() const
// 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)) {
for (const auto &context : std::as_const(definition.d->contexts)) {
// handle context switch attributes of this context itself
for (const auto switchContext :
{context->lineEndContext().context(), context->lineEmptyContext().context(), context->fallthroughContext().context()}) {
@@ -321,8 +313,9 @@ Context *DefinitionData::initialContext() const
Context *DefinitionData::contextByName(const QString &wantedName) const
{
for (const auto context : contexts) {
if (context->name() == wantedName)
if (context->name() == wantedName) {
return context;
}
}
return nullptr;
}
@@ -336,8 +329,9 @@ KeywordList *DefinitionData::keywordList(const QString &wantedName)
Format DefinitionData::formatByName(const QString &wantedName) const
{
const auto it = formats.constFind(wantedName);
if (it != formats.constEnd())
if (it != formats.constEnd()) {
return it.value();
}
return Format();
}
@@ -349,24 +343,29 @@ bool DefinitionData::isLoaded() const
bool DefinitionData::load(OnlyKeywords onlyKeywords)
{
if (fileName.isEmpty())
if (fileName.isEmpty()) {
return false;
}
if (isLoaded())
if (isLoaded()) {
return true;
}
if (bool(onlyKeywords) && keywordIsLoaded)
if (bool(onlyKeywords) && keywordIsLoaded) {
return true;
}
QFile file(fileName);
if (!file.open(QFile::ReadOnly))
if (!file.open(QFile::ReadOnly)) {
return false;
}
QXmlStreamReader reader(&file);
while (!reader.atEnd()) {
const auto token = reader.readNext();
if (token != QXmlStreamReader::StartElement)
if (token != QXmlStreamReader::StartElement) {
continue;
}
if (reader.name() == QLatin1String("highlighting")) {
loadHighlighting(reader, onlyKeywords);
@@ -375,21 +374,22 @@ bool DefinitionData::load(OnlyKeywords onlyKeywords)
}
}
else if (reader.name() == QLatin1String("general"))
else if (reader.name() == QLatin1String("general")) {
loadGeneral(reader);
}
}
for (auto it = keywordLists.begin(); it != keywordLists.end(); ++it) {
it->setCaseSensitivity(caseSensitive);
}
for (const auto context : qAsConst(contexts)) {
for (const auto context : std::as_const(contexts)) {
context->resolveContexts();
context->resolveIncludes();
context->resolveAttributeFormat();
}
for (const auto context : qAsConst(contexts)) {
for (const auto context : std::as_const(contexts)) {
for (const auto &rule : context->rules()) {
rule->resolvePostProcessing();
}
@@ -427,14 +427,16 @@ bool DefinitionData::loadMetaData(const QString &definitionFileName)
fileName = definitionFileName;
QFile file(definitionFileName);
if (!file.open(QFile::ReadOnly))
if (!file.open(QFile::ReadOnly)) {
return false;
}
QXmlStreamReader reader(&file);
while (!reader.atEnd()) {
const auto token = reader.readNext();
if (token != QXmlStreamReader::StartElement)
if (token != QXmlStreamReader::StartElement) {
continue;
}
if (reader.name() == QLatin1String("language")) {
return loadLanguage(reader);
}
@@ -457,11 +459,13 @@ bool DefinitionData::loadMetaData(const QString &file, const QCborMap &obj)
fileName = file;
const auto exts = obj.value(QLatin1String("extensions")).toString();
for (const auto &ext : exts.split(QLatin1Char(';'), Qt::SkipEmptyParts))
for (const auto &ext : exts.split(QLatin1Char(';'), Qt::SkipEmptyParts)) {
extensions.push_back(ext);
}
const auto mts = obj.value(QLatin1String("mimetype")).toString();
for (const auto &mt : mts.split(QLatin1Char(';'), Qt::SkipEmptyParts))
for (const auto &mt : mts.split(QLatin1Char(';'), Qt::SkipEmptyParts)) {
mimetypes.push_back(mt);
}
return true;
}
@@ -471,8 +475,9 @@ bool DefinitionData::loadLanguage(QXmlStreamReader &reader)
Q_ASSERT(reader.name() == QLatin1String("language"));
Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement);
if (!checkKateVersion(reader.attributes().value(QLatin1String("kateversion"))))
if (!checkKateVersion(reader.attributes().value(QLatin1String("kateversion")))) {
return false;
}
name = reader.attributes().value(QLatin1String("name")).toString();
section = reader.attributes().value(QLatin1String("section")).toString();
@@ -485,13 +490,16 @@ bool DefinitionData::loadLanguage(QXmlStreamReader &reader)
author = reader.attributes().value(QLatin1String("author")).toString();
license = reader.attributes().value(QLatin1String("license")).toString();
const auto exts = reader.attributes().value(QLatin1String("extensions")).toString();
for (const auto &ext : exts.split(QLatin1Char(';'), Qt::SkipEmptyParts))
for (const auto &ext : exts.split(QLatin1Char(';'), Qt::SkipEmptyParts)) {
extensions.push_back(ext);
}
const auto mts = reader.attributes().value(QLatin1String("mimetype")).toString();
for (const auto &mt : mts.split(QLatin1Char(';'), Qt::SkipEmptyParts))
for (const auto &mt : mts.split(QLatin1Char(';'), Qt::SkipEmptyParts)) {
mimetypes.push_back(mt);
if (reader.attributes().hasAttribute(QLatin1String("casesensitive")))
}
if (reader.attributes().hasAttribute(QLatin1String("casesensitive"))) {
caseSensitive = Xml::attrToBool(reader.attributes().value(QLatin1String("casesensitive"))) ? Qt::CaseSensitive : Qt::CaseInsensitive;
}
return true;
}
@@ -618,8 +626,9 @@ void DefinitionData::loadGeneral(QXmlStreamReader &reader)
++elementRefCounter;
if (reader.name() == QLatin1String("keywords")) {
if (reader.attributes().hasAttribute(QLatin1String("casesensitive")))
if (reader.attributes().hasAttribute(QLatin1String("casesensitive"))) {
caseSensitive = Xml::attrToBool(reader.attributes().value(QLatin1String("casesensitive"))) ? Qt::CaseSensitive : Qt::CaseInsensitive;
}
// adapt wordDelimiters
wordDelimiters.append(reader.attributes().value(QLatin1String("additionalDeliminator")));
@@ -628,14 +637,15 @@ void DefinitionData::loadGeneral(QXmlStreamReader &reader)
// adapt WordWrapDelimiters
auto wordWrapDeliminatorAttr = reader.attributes().value(
QLatin1String("wordWrapDeliminator"));
if (wordWrapDeliminatorAttr.isEmpty())
if (wordWrapDeliminatorAttr.isEmpty()) {
wordWrapDelimiters = wordDelimiters;
else {
} else {
wordWrapDelimiters.append(wordWrapDeliminatorAttr);
}
} else if (reader.name() == QLatin1String("folding")) {
if (reader.attributes().hasAttribute(QLatin1String("indentationsensitive")))
if (reader.attributes().hasAttribute(QLatin1String("indentationsensitive"))) {
indentationBasedFolding = Xml::attrToBool(reader.attributes().value(QLatin1String("indentationsensitive")));
}
} else if (reader.name() == QLatin1String("emptyLines")) {
loadFoldingIgnoreList(reader);
} else if (reader.name() == QLatin1String("comments")) {
@@ -649,8 +659,9 @@ void DefinitionData::loadGeneral(QXmlStreamReader &reader)
break;
case QXmlStreamReader::EndElement:
--elementRefCounter;
if (elementRefCounter == 0)
if (elementRefCounter == 0) {
return;
}
reader.readNext();
break;
default:
@@ -688,8 +699,9 @@ void DefinitionData::loadComments(QXmlStreamReader &reader)
break;
case QXmlStreamReader::EndElement:
--elementRefCounter;
if (elementRefCounter == 0)
if (elementRefCounter == 0) {
return;
}
reader.readNext();
break;
default:
@@ -719,8 +731,9 @@ void DefinitionData::loadFoldingIgnoreList(QXmlStreamReader &reader)
break;
case QXmlStreamReader::EndElement:
--elementRefCounter;
if (elementRefCounter == 0)
if (elementRefCounter == 0) {
return;
}
reader.readNext();
break;
default:
@@ -754,8 +767,9 @@ void DefinitionData::loadSpellchecking(QXmlStreamReader &reader)
break;
case QXmlStreamReader::EndElement:
--elementRefCounter;
if (elementRefCounter == 0)
if (elementRefCounter == 0) {
return;
}
reader.readNext();
break;
default:
@@ -798,10 +812,6 @@ DefinitionRef::DefinitionRef(const Definition &def)
{
}
DefinitionRef::~DefinitionRef()
{
}
DefinitionRef &DefinitionRef::operator=(const Definition &def)
{
d = def.d;
@@ -810,8 +820,9 @@ DefinitionRef &DefinitionRef::operator=(const Definition &def)
Definition DefinitionRef::definition() const
{
if (!d.expired())
if (!d.expired()) {
return Definition(d.lock());
}
return Definition();
}

View File

@@ -13,6 +13,7 @@
#include <QPair>
#include <QVector>
#include <memory>
#include <qobjectdefs.h>
QT_BEGIN_NAMESPACE
class QChar;
@@ -74,7 +75,7 @@ enum class CommentPosition {
* 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()
* equal the itemDatas of a highlighting 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.
@@ -84,6 +85,13 @@ enum class CommentPosition {
*/
class KSYNTAXHIGHLIGHTING_EXPORT Definition
{
Q_GADGET
Q_PROPERTY(QString name READ name)
Q_PROPERTY(QString translatedName READ translatedName)
Q_PROPERTY(QString section READ section)
Q_PROPERTY(QString translatedSection READ translatedSection)
Q_PROPERTY(QString author READ author)
Q_PROPERTY(QString license READ license)
public:
/**
* Default constructor, creating an empty (invalid) Definition instance.
@@ -93,6 +101,14 @@ public:
*/
Definition();
/**
* Move constructor.
* This definition takes the Definition data from @p other.
* @note @p other may only be assigned to or destroyed afterwards.
* @since 5.86
*/
Definition(Definition &&other) noexcept;
/**
* Copy constructor.
* Both this definition as well as @p other share the Definition data.
@@ -105,7 +121,15 @@ public:
~Definition();
/**
* Assignment operator.
* Move assignment operator.
* This definition takes the Definition data from @p other.
* @note @p other may only be assigned to or destroyed afterwards.
* @since 5.86
*/
Definition &operator=(Definition &&other) noexcept;
/**
* Copy assignment operator.
* Both this definition as well as @p rhs share the Definition data.
*/
Definition &operator=(const Definition &rhs);

View File

@@ -51,24 +51,27 @@ void DefinitionDownloaderPrivate::definitionListDownloadFinished(QNetworkReply *
while (!parser.atEnd()) {
switch (parser.readNext()) {
case QXmlStreamReader::StartElement:
if (parser.name() == QLatin1String("Definition"))
if (parser.name() == QLatin1String("Definition")) {
updateDefinition(parser);
}
break;
default:
break;
}
}
if (pendingDownloads == 0)
if (pendingDownloads == 0) {
Q_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())
if (name.isEmpty()) {
return;
}
auto localDef = repo->definitionForName(name.toString());
if (!localDef.isValid()) {
@@ -86,11 +89,13 @@ void DefinitionDownloaderPrivate::updateDefinition(QXmlStreamReader &parser)
void DefinitionDownloaderPrivate::downloadDefinition(const QUrl &downloadUrl)
{
if (!downloadUrl.isValid())
if (!downloadUrl.isValid()) {
return;
}
auto url = downloadUrl;
if (url.scheme() == QLatin1String("http"))
if (url.scheme() == QLatin1String("http")) {
url.setScheme(QStringLiteral("https"));
}
QNetworkRequest req(url);
auto reply = nam->get(req);
@@ -133,8 +138,9 @@ void DefinitionDownloaderPrivate::downloadDefinitionFinished(QNetworkReply *repl
void DefinitionDownloaderPrivate::checkDone()
{
if (pendingDownloads == 0) {
if (needsReload)
if (needsReload) {
repo->reload();
}
Q_EMIT QTimer::singleShot(0, q, &DefinitionDownloader::done);
}

View File

@@ -13,7 +13,6 @@ namespace KSyntaxHighlighting
{
class Definition;
class DefinitionData;
class DefinitionPrivate;
/** Weak reference for Definition instances.
*
@@ -21,6 +20,8 @@ class DefinitionPrivate;
* in objects hold directly or indirectly by Definition
* to avoid reference count loops and thus memory leaks.
*
* This class follows the rule of zero. It is implicitly movable and copyable.
*
* @internal
*/
class DefinitionRef
@@ -28,7 +29,6 @@ class DefinitionRef
public:
DefinitionRef();
explicit DefinitionRef(const Definition &def);
~DefinitionRef();
DefinitionRef &operator=(const Definition &def);
Definition definition() const;

View File

@@ -21,8 +21,9 @@ using namespace KSyntaxHighlighting;
static Theme::TextStyle stringToDefaultFormat(QStringView str)
{
if (!str.startsWith(QLatin1String("ds")))
if (!str.startsWith(QLatin1String("ds"))) {
return Theme::Normal;
}
static const auto idx = Theme::staticMetaObject.indexOfEnumerator("TextStyle");
Q_ASSERT(idx >= 0);
@@ -30,8 +31,9 @@ static Theme::TextStyle stringToDefaultFormat(QStringView str)
bool ok = false;
const auto value = metaEnum.keyToValue(str.mid(2).toLatin1().constData(), &ok);
if (!ok || value < 0)
if (!ok || value < 0) {
return Theme::Normal;
}
return static_cast<Theme::TextStyle>(value);
}
@@ -44,8 +46,9 @@ FormatPrivate *FormatPrivate::detachAndGet(Format &format)
TextStyleData FormatPrivate::styleOverride(const Theme &theme) const
{
const auto themeData = ThemeData::get(theme);
if (themeData)
if (themeData) {
return themeData->textStyleOverride(definition.definition().name(), name);
}
return TextStyleData();
}
@@ -113,16 +116,18 @@ bool Format::hasTextColor(const Theme &theme) const
QColor Format::textColor(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
if (overrideStyle.textColor)
if (overrideStyle.textColor) {
return overrideStyle.textColor;
}
return d->style.textColor ? QColor::fromRgba(d->style.textColor) : QColor::fromRgba(theme.textColor(d->defaultStyle));
}
QColor Format::selectedTextColor(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
if (overrideStyle.selectedTextColor)
if (overrideStyle.selectedTextColor) {
return overrideStyle.selectedTextColor;
}
return d->style.selectedTextColor ? QColor::fromRgba(d->style.selectedTextColor) : QColor::fromRgba(theme.selectedTextColor(d->defaultStyle));
}
@@ -136,8 +141,9 @@ bool Format::hasBackgroundColor(const Theme &theme) const
QColor Format::backgroundColor(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
if (overrideStyle.backgroundColor)
if (overrideStyle.backgroundColor) {
return overrideStyle.backgroundColor;
}
// use QColor::fromRgba for background QRgb => QColor conversion to avoid unset colors == black!
return d->style.backgroundColor ? QColor::fromRgba(d->style.backgroundColor) : QColor::fromRgba(theme.backgroundColor(d->defaultStyle));
@@ -146,8 +152,9 @@ QColor Format::backgroundColor(const Theme &theme) const
QColor Format::selectedBackgroundColor(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
if (overrideStyle.selectedBackgroundColor)
if (overrideStyle.selectedBackgroundColor) {
return overrideStyle.selectedBackgroundColor;
}
// use QColor::fromRgba for background QRgb => QColor conversion to avoid unset colors == black!
return d->style.selectedBackgroundColor ? QColor::fromRgba(d->style.selectedBackgroundColor)
@@ -157,32 +164,36 @@ QColor Format::selectedBackgroundColor(const Theme &theme) const
bool Format::isBold(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
if (overrideStyle.hasBold)
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)
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)
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)
if (overrideStyle.hasStrikeThrough) {
return overrideStyle.strikeThrough;
}
return d->style.hasStrikeThrough ? d->style.strikeThrough : theme.isStrikeThrough(d->defaultStyle);
}

View File

@@ -70,10 +70,11 @@ void HtmlHighlighter::highlightFile(const QString &fileName, const QString &titl
return;
}
if (title.isEmpty())
if (title.isEmpty()) {
highlightData(&f, fi.fileName());
else
} else {
highlightData(&f, title);
}
}
/**
@@ -87,8 +88,9 @@ void HtmlHighlighter::highlightFile(const QString &fileName, const QString &titl
*/
static QString toHtmlRgbaString(const QColor &color)
{
if (color.alpha() == 0xFF)
if (color.alpha() == 0xFF) {
return color.name();
}
QString rgba = QStringLiteral("rgba(");
rgba.append(QString::number(color.red()));
@@ -111,10 +113,11 @@ void HtmlHighlighter::highlightData(QIODevice *dev, const QString &title)
}
QString htmlTitle;
if (title.isEmpty())
if (title.isEmpty()) {
htmlTitle = QStringLiteral("Kate Syntax Highlighter");
else
} else {
htmlTitle = title.toHtmlEscaped();
}
State state;
*d->out << "<!DOCTYPE html>\n";
@@ -125,8 +128,9 @@ void HtmlHighlighter::highlightData(QIODevice *dev, const QString &title)
<< ")\"/>\n";
*d->out << "</head><body";
*d->out << " style=\"background-color:" << toHtmlRgbaString(QColor::fromRgba(theme().editorColor(Theme::BackgroundColor)));
if (theme().textColor(Theme::Normal))
if (theme().textColor(Theme::Normal)) {
*d->out << ";color:" << toHtmlRgbaString(QColor::fromRgba(theme().textColor(Theme::Normal)));
}
*d->out << "\"><pre>\n";
QTextStream in(dev);
@@ -148,27 +152,34 @@ void HtmlHighlighter::highlightData(QIODevice *dev, const QString &title)
void HtmlHighlighter::applyFormat(int offset, int length, const Format &format)
{
if (length == 0)
if (length == 0) {
return;
}
// collect potential output, cheaper than thinking about "is there any?"
QVarLengthArray<QString, 16> formatOutput;
if (format.hasTextColor(theme()))
if (format.hasTextColor(theme())) {
formatOutput << QStringLiteral("color:") << toHtmlRgbaString(format.textColor(theme())) << QStringLiteral(";");
if (format.hasBackgroundColor(theme()))
}
if (format.hasBackgroundColor(theme())) {
formatOutput << QStringLiteral("background-color:") << toHtmlRgbaString(format.backgroundColor(theme())) << QStringLiteral(";");
if (format.isBold(theme()))
}
if (format.isBold(theme())) {
formatOutput << QStringLiteral("font-weight:bold;");
if (format.isItalic(theme()))
}
if (format.isItalic(theme())) {
formatOutput << QStringLiteral("font-style:italic;");
if (format.isUnderline(theme()))
}
if (format.isUnderline(theme())) {
formatOutput << QStringLiteral("text-decoration:underline;");
if (format.isStrikeThrough(theme()))
}
if (format.isStrikeThrough(theme())) {
formatOutput << QStringLiteral("text-decoration:line-through;");
}
if (!formatOutput.isEmpty()) {
*d->out << "<span style=\"";
for (const auto &out : qAsConst(formatOutput)) {
for (const auto &out : std::as_const(formatOutput)) {
*d->out << out;
}
*d->out << "\">";

View File

@@ -16,6 +16,27 @@
using namespace KSyntaxHighlighting;
namespace
{
struct KeywordComparator {
Qt::CaseSensitivity caseSensitive;
bool operator()(QStringView a, QStringView b) const
{
if (a.size() < b.size()) {
return true;
}
if (a.size() > b.size()) {
return false;
}
return a.compare(b, caseSensitive) < 0;
}
};
}
bool KeywordList::contains(QStringView str, Qt::CaseSensitivity caseSensitive) const
{
/**
@@ -26,9 +47,7 @@ bool KeywordList::contains(QStringView str, Qt::CaseSensitivity caseSensitive) c
/**
* search with right predicate
*/
return std::binary_search(vectorToSearch.begin(), vectorToSearch.end(), QStringView(str), [caseSensitive](QStringView a, QStringView b) {
return a.compare(b, caseSensitive) < 0;
});
return std::binary_search(vectorToSearch.begin(), vectorToSearch.end(), QStringView(str), KeywordComparator{caseSensitive});
}
void KeywordList::load(QXmlStreamReader &reader)
@@ -85,16 +104,14 @@ void KeywordList::initLookupForCaseSensitivity(Qt::CaseSensitivity caseSensitive
* fill vector with refs to keywords
*/
vectorToSort.reserve(m_keywords.size());
for (const auto &keyword : qAsConst(m_keywords)) {
for (const auto &keyword : std::as_const(m_keywords)) {
vectorToSort.push_back(keyword);
}
/**
* sort with right predicate
*/
std::sort(vectorToSort.begin(), vectorToSort.end(), [caseSensitive](QStringView a, QStringView b) {
return a.compare(b, caseSensitive) < 0;
});
std::sort(vectorToSort.begin(), vectorToSort.end(), KeywordComparator{caseSensitive});
}
void KeywordList::resolveIncludeKeywords(DefinitionData &def)

View File

@@ -1,34 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2018 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 <QtGlobal>
#if defined(KSYNTAXHIGHLIGHTING_LIBRARY)
# define KSYNTAXHIGHLIGHTING_EXPORT Q_DECL_EXPORT
#else
# define KSYNTAXHIGHLIGHTING_EXPORT Q_DECL_IMPORT
#endif

View File

@@ -11,7 +11,7 @@
#include "repository_p.h"
#include "theme.h"
#include "themedata_p.h"
#include "wildcardmatcher_p.h"
#include "wildcardmatcher.h"
#include <QCborMap>
#include <QCborValue>
@@ -19,15 +19,75 @@
#include <QFile>
#include <QFileInfo>
#include <QPalette>
#include <QString>
#include <QStringView>
#ifndef NO_STANDARD_PATHS
#include <QStandardPaths>
#endif
#include <algorithm>
#include <iterator>
#include <limits>
using namespace KSyntaxHighlighting;
namespace
{
QString fileNameFromFilePath(const QString &filePath)
{
return QFileInfo{filePath}.fileName();
}
auto anyWildcardMatches(QStringView str)
{
return [str](const Definition &def) {
const auto strings = def.extensions();
return std::any_of(strings.cbegin(), strings.cend(), [str](QStringView wildcard) {
return WildcardMatcher::exactMatch(str, wildcard);
});
};
}
auto anyMimeTypeEquals(QStringView mimeTypeName)
{
return [mimeTypeName](const Definition &def) {
const auto strings = def.mimeTypes();
return std::any_of(strings.cbegin(), strings.cend(), [mimeTypeName](QStringView name) {
return mimeTypeName == name;
});
};
}
// The two function templates below take defs - a map sorted by highlighting name - to be deterministic and independent of translations.
template<typename UnaryPredicate>
Definition findHighestPriorityDefinitionIf(const QMap<QString, Definition> &defs, UnaryPredicate predicate)
{
const Definition *match = nullptr;
auto matchPriority = std::numeric_limits<int>::lowest();
for (const Definition &def : defs) {
const auto defPriority = def.priority();
if (defPriority > matchPriority && predicate(def)) {
match = &def;
matchPriority = defPriority;
}
}
return match == nullptr ? Definition{} : *match;
}
template<typename UnaryPredicate>
QVector<Definition> findDefinitionsIf(const QMap<QString, Definition> &defs, UnaryPredicate predicate)
{
QVector<Definition> matches;
std::copy_if(defs.cbegin(), defs.cend(), std::back_inserter(matches), predicate);
std::stable_sort(matches.begin(), matches.end(), [](const Definition &lhs, const Definition &rhs) {
return lhs.priority() > rhs.priority();
});
return matches;
}
} // unnamed namespace
static void initResource()
{
#ifdef HAS_SYNTAX_RESOURCE
@@ -52,8 +112,9 @@ Repository::~Repository()
{
// reset repo so we can detect in still alive definition instances
// that the repo was deleted
for (const auto &def : qAsConst(d->m_sortedDefs))
for (const auto &def : std::as_const(d->m_sortedDefs)) {
DefinitionData::get(def)->repo = nullptr;
}
}
Definition Repository::definitionForName(const QString &defName) const
@@ -61,58 +122,24 @@ Definition Repository::definitionForName(const QString &defName) const
return d->m_defs.value(defName);
}
static void sortDefinitions(QVector<Definition> &definitions)
{
std::stable_sort(definitions.begin(), definitions.end(), [](const Definition &lhs, const Definition &rhs) {
return lhs.priority() > rhs.priority();
});
}
Definition Repository::definitionForFileName(const QString &fileName) const
{
return definitionsForFileName(fileName).value(0);
return findHighestPriorityDefinitionIf(d->m_defs, anyWildcardMatches(fileNameFromFilePath(fileName)));
}
QVector<Definition> Repository::definitionsForFileName(const QString &fileName) const
{
QFileInfo fi(fileName);
const auto name = fi.fileName();
// use d->m_defs, sorted map by highlighting name, to be deterministic and independent of translations
QVector<Definition> candidates;
for (const Definition &def : qAsConst(d->m_defs)) {
for (const auto &pattern : def.extensions()) {
if (WildcardMatcher::exactMatch(name, pattern)) {
candidates.push_back(def);
break;
}
}
}
sortDefinitions(candidates);
return candidates;
return findDefinitionsIf(d->m_defs, anyWildcardMatches(fileNameFromFilePath(fileName)));
}
Definition Repository::definitionForMimeType(const QString &mimeType) const
{
return definitionsForMimeType(mimeType).value(0);
return findHighestPriorityDefinitionIf(d->m_defs, anyMimeTypeEquals(mimeType));
}
QVector<Definition> Repository::definitionsForMimeType(const QString &mimeType) const
{
// use d->m_defs, sorted map by highlighting name, to be deterministic and independent of translations
QVector<Definition> candidates;
for (const Definition &def : qAsConst(d->m_defs)) {
for (const auto &matchType : def.mimeTypes()) {
if (mimeType == matchType) {
candidates.push_back(def);
break;
}
}
}
sortDefinitions(candidates);
return candidates;
return findDefinitionsIf(d->m_defs, anyMimeTypeEquals(mimeType));
}
QVector<Definition> Repository::definitions() const
@@ -127,7 +154,7 @@ QVector<Theme> Repository::themes() const
Theme Repository::theme(const QString &themeName) const
{
for (const auto &theme : qAsConst(d->m_themes)) {
for (const auto &theme : std::as_const(d->m_themes)) {
if (theme.name() == themeName) {
return theme;
}
@@ -138,14 +165,15 @@ Theme Repository::theme(const QString &themeName) const
Theme Repository::defaultTheme(Repository::DefaultTheme t) const
{
if (t == DarkTheme)
if (t == DarkTheme) {
return theme(QLatin1String("Breeze Dark"));
}
return theme(QLatin1String("Breeze Light"));
}
Theme Repository::defaultTheme(Repository::DefaultTheme t)
{
return qAsConst(*this).defaultTheme(t);
return std::as_const(*this).defaultTheme(t);
}
Theme Repository::themeForPalette(const QPalette &palette) const
@@ -164,7 +192,7 @@ Theme Repository::themeForPalette(const QPalette &palette) const
if (!matchingThemes.empty()) {
// if there's multiple, search for one with a matching highlight color
const auto highlight = palette.color(QPalette::Highlight);
for (const auto &theme : qAsConst(matchingThemes)) {
for (const auto &theme : std::as_const(matchingThemes)) {
auto selection = theme.editorColor(KSyntaxHighlighting::Theme::EditorColorRole::TextSelection);
if (selection == highlight.rgb()) {
return theme;
@@ -179,7 +207,7 @@ Theme Repository::themeForPalette(const QPalette &palette) const
Theme Repository::themeForPalette(const QPalette &palette)
{
return qAsConst(*this).themeForPalette(palette);
return std::as_const(*this).themeForPalette(palette);
}
void RepositoryPrivate::load(Repository *repo)
@@ -189,29 +217,39 @@ void RepositoryPrivate::load(Repository *repo)
// do lookup in standard paths, if not disabled
#ifndef NO_STANDARD_PATHS
for (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
for (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
// default resources are always used
loadSyntaxFolder(repo, QStringLiteral(":/org.kde.syntax-highlighting/syntax"));
// default resources are always used, this is the one location that has a index cbor file
loadSyntaxFolderFromIndex(repo, QStringLiteral(":/org.kde.syntax-highlighting/syntax"));
// extra resources provided by 3rdparty libraries/applications
loadSyntaxFolder(repo, QStringLiteral(":/org.kde.syntax-highlighting/syntax-addons"));
// user given extra paths
for (const auto &path : qAsConst(m_customSearchPaths))
for (const auto &path : std::as_const(m_customSearchPaths)) {
loadSyntaxFolder(repo, path + QStringLiteral("/syntax"));
}
m_sortedDefs.reserve(m_defs.size());
for (auto it = m_defs.constBegin(); it != m_defs.constEnd(); ++it)
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)
if (comparison == 0) {
comparison = left.translatedName().compare(right.translatedName(), Qt::CaseInsensitive);
}
return comparison < 0;
});
@@ -219,54 +257,60 @@ void RepositoryPrivate::load(Repository *repo)
// do lookup in standard paths, if not disabled
#ifndef NO_STANDARD_PATHS
for (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
// default resources are always used
loadThemeFolder(QStringLiteral(":/org.kde.syntax-highlighting/themes"));
// extra resources provided by 3rdparty libraries/applications
loadThemeFolder(QStringLiteral(":/org.kde.syntax-highlighting/themes-addons"));
// user given extra paths
for (const auto &path : qAsConst(m_customSearchPaths))
for (const auto &path : std::as_const(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()))
if (defData->loadMetaData(it.next())) {
addDefinition(def);
}
}
}
bool RepositoryPrivate::loadSyntaxFolderFromIndex(Repository *repo, const QString &path)
void RepositoryPrivate::loadSyntaxFolderFromIndex(Repository *repo, const QString &path)
{
QFile indexFile(path + QLatin1String("/index.katesyntax"));
if (!indexFile.open(QFile::ReadOnly))
return false;
if (!indexFile.open(QFile::ReadOnly)) {
return;
}
const auto indexDoc(QCborValue::fromCbor(indexFile.readAll()));
const auto index = indexDoc.toMap();
for (auto it = index.begin(); it != index.end(); ++it) {
if (!it.value().isMap())
if (!it.value().isMap()) {
continue;
}
const auto fileName = QString(path + QLatin1Char('/') + it.key().toString());
const auto defMap = it.value().toMap();
Definition def;
auto defData = DefinitionData::get(def);
defData->repo = repo;
if (defData->loadMetaData(fileName, defMap))
if (defData->loadMetaData(fileName, defMap)) {
addDefinition(def);
}
}
return true;
}
void RepositoryPrivate::addDefinition(const Definition &def)
@@ -277,8 +321,9 @@ void RepositoryPrivate::addDefinition(const Definition &def)
return;
}
if (it.value().version() >= def.version())
if (it.value().version() >= def.version()) {
return;
}
m_defs.insert(def.name(), def);
}
@@ -287,8 +332,9 @@ 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()))
if (themeData->load(it.next())) {
addTheme(Theme(themeData.release()));
}
}
}
@@ -307,15 +353,17 @@ void RepositoryPrivate::addTheme(const Theme &theme)
m_themes.insert(it, theme);
return;
}
if (themeRevision(*it) < themeRevision(theme))
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())
if (it != m_foldingRegionIds.constEnd()) {
return it.value();
}
m_foldingRegionIds.insert(qMakePair(defName, foldName), ++m_foldingRegionId);
return m_foldingRegionId;
}
@@ -329,8 +377,9 @@ quint16 RepositoryPrivate::nextFormatId()
void Repository::reload()
{
qCDebug(Log) << "Reloading syntax definitions!";
for (const auto &def : qAsConst(d->m_sortedDefs))
for (const auto &def : std::as_const(d->m_sortedDefs)) {
DefinitionData::get(def)->clear();
}
d->m_defs.clear();
d->m_sortedDefs.clear();

View File

@@ -86,6 +86,11 @@ class Theme;
* The internal resource path is ":/org.kde.syntax-highlighting/syntax".
* This path should never be touched by other applications.
*
* -# Then, all custom files compiled into resources are loaded.
* The resource path is ":/org.kde.syntax-highlighting/syntax-addons".
* This path can be used by other libraries/applications to bundle specialized definitions.
* Per default this path isn't used by the framework itself.
*
* -# 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.
@@ -102,6 +107,11 @@ class Theme;
* The internal resource path is ":/org.kde.syntax-highlighting/themes".
* This path should never be touched by other applications.
*
* -# Then, all custom files compiled into resources are loaded.
* The resource path is ":/org.kde.syntax-highlighting/themes-addons".
* This path can be used by other libraries/applications to bundle specialized themes.
* Per default this path isn't used by the framework itself.
*
* -# Finally, all Theme%s located in the paths added addCustomSearchPath()
* are loaded.
*

View File

@@ -29,7 +29,7 @@ public:
void load(Repository *repo);
void loadSyntaxFolder(Repository *repo, const QString &path);
bool loadSyntaxFolderFromIndex(Repository *repo, const QString &path);
void loadSyntaxFolderFromIndex(Repository *repo, const QString &path);
void addDefinition(const Definition &def);

View File

@@ -34,10 +34,11 @@ static bool isHexChar(QChar c)
return isDigit(c) || (c <= QLatin1Char('f') && QLatin1Char('a') <= c) || (c <= QLatin1Char('F') && QLatin1Char('A') <= c);
}
static int matchEscapedChar(const QString &text, int offset)
static int matchEscapedChar(QStringView text, int offset)
{
if (text.at(offset) != QLatin1Char('\\') || text.size() < offset + 2)
if (text.at(offset) != QLatin1Char('\\') || text.size() < offset + 2) {
return offset;
}
const auto c = text.at(offset + 1);
switch (c.unicode()) {
@@ -59,8 +60,9 @@ static int matchEscapedChar(const QString &text, int offset)
// hex encoded character
case 'x':
if (offset + 2 < text.size() && isHexChar(text.at(offset + 2))) {
if (offset + 3 < text.size() && isHexChar(text.at(offset + 3)))
if (offset + 3 < text.size() && isHexChar(text.at(offset + 3))) {
return offset + 4;
}
return offset + 3;
}
return offset;
@@ -75,8 +77,9 @@ static int matchEscapedChar(const QString &text, int offset)
case '6':
case '7':
if (offset + 2 < text.size() && isOctalChar(text.at(offset + 2))) {
if (offset + 3 < text.size() && isOctalChar(text.at(offset + 3)))
if (offset + 3 < text.size() && isOctalChar(text.at(offset + 3))) {
return offset + 4;
}
return offset + 3;
}
return offset + 2;
@@ -116,26 +119,31 @@ bool Rule::load(QXmlStreamReader &reader)
Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement);
m_attribute = reader.attributes().value(QLatin1String("attribute")).toString();
if (reader.name() != QLatin1String("IncludeRules")) // IncludeRules uses this with a different semantic
if (reader.name() != QLatin1String("IncludeRules")) { // IncludeRules uses this with a different semantic
m_context.parse(reader.attributes().value(QLatin1String("context")));
}
m_firstNonSpace = Xml::attrToBool(reader.attributes().value(QLatin1String("firstNonSpace")));
m_lookAhead = Xml::attrToBool(reader.attributes().value(QLatin1String("lookAhead")));
bool colOk = false;
m_column = reader.attributes().value(QLatin1String("column")).toInt(&colOk);
if (!colOk)
if (!colOk) {
m_column = -1;
}
auto regionName = reader.attributes().value(QLatin1String("beginRegion"));
if (!regionName.isEmpty())
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())
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())
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();
@@ -184,42 +192,60 @@ void Rule::loadAdditionalWordDelimiters(QXmlStreamReader &reader)
Rule::Ptr Rule::create(QStringView name)
{
if (name == QLatin1String("AnyChar"))
if (name == QLatin1String("AnyChar")) {
return std::make_shared<AnyChar>();
if (name == QLatin1String("DetectChar"))
}
if (name == QLatin1String("DetectChar")) {
return std::make_shared<DetectChar>();
if (name == QLatin1String("Detect2Chars"))
}
if (name == QLatin1String("Detect2Chars")) {
return std::make_shared<Detect2Char>();
if (name == QLatin1String("DetectIdentifier"))
}
if (name == QLatin1String("DetectIdentifier")) {
return std::make_shared<DetectIdentifier>();
if (name == QLatin1String("DetectSpaces"))
}
if (name == QLatin1String("DetectSpaces")) {
return std::make_shared<DetectSpaces>();
if (name == QLatin1String("Float"))
}
if (name == QLatin1String("Float")) {
return std::make_shared<Float>();
if (name == QLatin1String("Int"))
}
if (name == QLatin1String("Int")) {
return std::make_shared<Int>();
if (name == QLatin1String("HlCChar"))
}
if (name == QLatin1String("HlCChar")) {
return std::make_shared<HlCChar>();
if (name == QLatin1String("HlCHex"))
}
if (name == QLatin1String("HlCHex")) {
return std::make_shared<HlCHex>();
if (name == QLatin1String("HlCOct"))
}
if (name == QLatin1String("HlCOct")) {
return std::make_shared<HlCOct>();
if (name == QLatin1String("HlCStringChar"))
}
if (name == QLatin1String("HlCStringChar")) {
return std::make_shared<HlCStringChar>();
if (name == QLatin1String("IncludeRules"))
}
if (name == QLatin1String("IncludeRules")) {
return std::make_shared<IncludeRules>();
if (name == QLatin1String("keyword"))
}
if (name == QLatin1String("keyword")) {
return std::make_shared<KeywordListRule>();
if (name == QLatin1String("LineContinue"))
}
if (name == QLatin1String("LineContinue")) {
return std::make_shared<LineContinue>();
if (name == QLatin1String("RangeDetect"))
}
if (name == QLatin1String("RangeDetect")) {
return std::make_shared<RangeDetect>();
if (name == QLatin1String("RegExpr"))
}
if (name == QLatin1String("RegExpr")) {
return std::make_shared<RegExpr>();
if (name == QLatin1String("StringDetect"))
}
if (name == QLatin1String("StringDetect")) {
return std::make_shared<StringDetect>();
if (name == QLatin1String("WordDetect"))
}
if (name == QLatin1String("WordDetect")) {
return std::make_shared<WordDetect>();
}
qCWarning(Log) << "Unknown rule type:" << name;
return Ptr(nullptr);
@@ -233,23 +259,26 @@ bool Rule::isWordDelimiter(QChar c) const
bool AnyChar::doLoad(QXmlStreamReader &reader)
{
m_chars = reader.attributes().value(QLatin1String("String")).toString();
if (m_chars.size() == 1)
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
MatchResult AnyChar::doMatch(QStringView text, int offset, const QStringList &) const
{
if (m_chars.contains(text.at(offset)))
if (m_chars.contains(text.at(offset))) {
return offset + 1;
}
return offset;
}
bool DetectChar::doLoad(QXmlStreamReader &reader)
{
const auto s = reader.attributes().value(QLatin1String("char"));
if (s.isEmpty())
if (s.isEmpty()) {
return false;
}
m_char = s.at(0);
m_dynamic = Xml::attrToBool(reader.attributes().value(QLatin1String("dynamic")));
if (m_dynamic) {
@@ -258,18 +287,21 @@ bool DetectChar::doLoad(QXmlStreamReader &reader)
return true;
}
MatchResult DetectChar::doMatch(const QString &text, int offset, const QStringList &captures) const
MatchResult DetectChar::doMatch(QStringView text, int offset, const QStringList &captures) const
{
if (m_dynamic) {
if (m_captureIndex == 0 || captures.size() <= m_captureIndex || captures.at(m_captureIndex).isEmpty())
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))
}
if (text.at(offset) == captures.at(m_captureIndex).at(0)) {
return offset + 1;
}
return offset;
}
if (text.at(offset) == m_char)
if (text.at(offset) == m_char) {
return offset + 1;
}
return offset;
}
@@ -277,40 +309,46 @@ bool Detect2Char::doLoad(QXmlStreamReader &reader)
{
const auto s1 = reader.attributes().value(QLatin1String("char"));
const auto s2 = reader.attributes().value(QLatin1String("char1"));
if (s1.isEmpty() || s2.isEmpty())
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
MatchResult Detect2Char::doMatch(QStringView text, int offset, const QStringList &) const
{
if (text.size() - offset < 2)
if (text.size() - offset < 2) {
return offset;
if (text.at(offset) == m_char1 && text.at(offset + 1) == m_char2)
}
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
MatchResult DetectIdentifier::doMatch(QStringView text, int offset, const QStringList &) const
{
if (!text.at(offset).isLetter() && text.at(offset) != QLatin1Char('_'))
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('_'))
if (!c.isLetterOrNumber() && c != QLatin1Char('_')) {
return i;
}
}
return text.size();
}
MatchResult DetectSpaces::doMatch(const QString &text, int offset, const QStringList &) const
MatchResult DetectSpaces::doMatch(QStringView text, int offset, const QStringList &) const
{
while (offset < text.size() && text.at(offset).isSpace())
while (offset < text.size() && text.at(offset).isSpace()) {
++offset;
}
return offset;
}
@@ -320,63 +358,76 @@ bool Float::doLoad(QXmlStreamReader &reader)
return true;
}
MatchResult Float::doMatch(const QString &text, int offset, const QStringList &) const
MatchResult Float::doMatch(QStringView text, int offset, const QStringList &) const
{
if (offset > 0 && !isWordDelimiter(text.at(offset - 1)))
if (offset > 0 && !isWordDelimiter(text.at(offset - 1))) {
return offset;
}
auto newOffset = offset;
while (newOffset < text.size() && isDigit(text.at(newOffset)))
while (newOffset < text.size() && isDigit(text.at(newOffset))) {
++newOffset;
}
if (newOffset >= text.size() || text.at(newOffset) != QLatin1Char('.'))
if (newOffset >= text.size() || text.at(newOffset) != QLatin1Char('.')) {
return offset;
}
++newOffset;
while (newOffset < text.size() && isDigit(text.at(newOffset)))
while (newOffset < text.size() && isDigit(text.at(newOffset))) {
++newOffset;
}
if (newOffset == offset + 1) // we only found a decimal point
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')))
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('-')))
if (expOffset < text.size() && (text.at(expOffset) == QLatin1Char('+') || text.at(expOffset) == QLatin1Char('-'))) {
++expOffset;
}
bool foundExpDigit = false;
while (expOffset < text.size() && isDigit(text.at(expOffset))) {
++expOffset;
foundExpDigit = true;
}
if (!foundExpDigit)
if (!foundExpDigit) {
return newOffset;
}
return expOffset;
}
MatchResult HlCChar::doMatch(const QString &text, int offset, const QStringList &) const
MatchResult HlCChar::doMatch(QStringView text, int offset, const QStringList &) const
{
if (text.size() < offset + 3)
if (text.size() < offset + 3) {
return offset;
}
if (text.at(offset) != QLatin1Char('\'') || text.at(offset + 1) == QLatin1Char('\''))
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('\\'))
if (text.at(newOffset) == QLatin1Char('\\')) {
return offset;
else
} else {
++newOffset;
}
}
if (newOffset >= text.size())
if (newOffset >= text.size()) {
return offset;
}
if (text.at(newOffset) == QLatin1Char('\''))
if (text.at(newOffset) == QLatin1Char('\'')) {
return newOffset + 1;
}
return offset;
}
@@ -387,23 +438,28 @@ bool HlCHex::doLoad(QXmlStreamReader &reader)
return true;
}
MatchResult HlCHex::doMatch(const QString &text, int offset, const QStringList &) const
MatchResult HlCHex::doMatch(QStringView text, int offset, const QStringList &) const
{
if (offset > 0 && !isWordDelimiter(text.at(offset - 1)))
if (offset > 0 && !isWordDelimiter(text.at(offset - 1))) {
return offset;
}
if (text.size() < offset + 3)
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')))
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)))
if (!isHexChar(text.at(offset + 2))) {
return offset;
}
offset += 3;
while (offset < text.size() && isHexChar(text.at(offset)))
while (offset < text.size() && isHexChar(text.at(offset))) {
++offset;
}
// TODO Kate matches U/L suffix, QtC does not?
@@ -416,28 +472,33 @@ bool HlCOct::doLoad(QXmlStreamReader &reader)
return true;
}
MatchResult HlCOct::doMatch(const QString &text, int offset, const QStringList &) const
MatchResult HlCOct::doMatch(QStringView text, int offset, const QStringList &) const
{
if (offset > 0 && !isWordDelimiter(text.at(offset - 1)))
if (offset > 0 && !isWordDelimiter(text.at(offset - 1))) {
return offset;
}
if (text.size() < offset + 2)
if (text.size() < offset + 2) {
return offset;
}
if (text.at(offset) != QLatin1Char('0'))
if (text.at(offset) != QLatin1Char('0')) {
return offset;
}
if (!isOctalChar(text.at(offset + 1)))
if (!isOctalChar(text.at(offset + 1))) {
return offset;
}
offset += 2;
while (offset < text.size() && isOctalChar(text.at(offset)))
while (offset < text.size() && isOctalChar(text.at(offset))) {
++offset;
}
return offset;
}
MatchResult HlCStringChar::doMatch(const QString &text, int offset, const QStringList &) const
MatchResult HlCStringChar::doMatch(QStringView text, int offset, const QStringList &) const
{
return matchEscapedChar(text, offset);
}
@@ -461,17 +522,19 @@ bool IncludeRules::doLoad(QXmlStreamReader &reader)
{
const auto s = reader.attributes().value(QLatin1String("context"));
const auto split = s.split(QString::fromLatin1("##"), Qt::KeepEmptyParts);
if (split.isEmpty())
if (split.isEmpty()) {
return false;
}
m_contextName = split.at(0).toString();
if (split.size() > 1)
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
MatchResult IncludeRules::doMatch(QStringView text, int offset, const QStringList &) const
{
Q_UNUSED(text);
qCWarning(Log) << "Unresolved include rule for" << m_contextName << "##" << m_defName;
@@ -484,13 +547,15 @@ bool Int::doLoad(QXmlStreamReader &reader)
return true;
}
MatchResult Int::doMatch(const QString &text, int offset, const QStringList &) const
MatchResult Int::doMatch(QStringView text, int offset, const QStringList &) const
{
if (offset > 0 && !isWordDelimiter(text.at(offset - 1)))
if (offset > 0 && !isWordDelimiter(text.at(offset - 1))) {
return offset;
}
while (offset < text.size() && isDigit(text.at(offset)))
while (offset < text.size() && isDigit(text.at(offset))) {
++offset;
}
return offset;
}
@@ -522,21 +587,24 @@ bool KeywordListRule::doLoad(QXmlStreamReader &reader)
return !m_keywordList->isEmpty();
}
MatchResult KeywordListRule::doMatch(const QString &text, int offset, const QStringList &) const
MatchResult KeywordListRule::doMatch(QStringView text, int offset, const QStringList &) const
{
auto newOffset = offset;
while (text.size() > newOffset && !isWordDelimiter(text.at(newOffset)))
while (text.size() > newOffset && !isWordDelimiter(text.at(newOffset))) {
++newOffset;
if (newOffset == offset)
}
if (newOffset == offset) {
return offset;
}
if (m_hasCaseSensitivityOverride) {
if (m_keywordList->contains(QStringView(text).mid(offset, newOffset - offset),
m_caseSensitivityOverride))
if (m_keywordList->contains(text.mid(offset, newOffset - offset), m_caseSensitivityOverride)) {
return newOffset;
}
} else {
if (m_keywordList->contains(QStringView(text).mid(offset, newOffset - offset)))
if (m_keywordList->contains(text.mid(offset, newOffset - offset))) {
return newOffset;
}
}
// we don't match, but we can skip until newOffset as we can't start a keyword in-between
@@ -546,17 +614,19 @@ MatchResult KeywordListRule::doMatch(const QString &text, int offset, const QStr
bool LineContinue::doLoad(QXmlStreamReader &reader)
{
const auto s = reader.attributes().value(QLatin1String("char"));
if (s.isEmpty())
if (s.isEmpty()) {
m_char = QLatin1Char('\\');
else
} else {
m_char = s.at(0);
}
return true;
}
MatchResult LineContinue::doMatch(const QString &text, int offset, const QStringList &) const
MatchResult LineContinue::doMatch(QStringView text, int offset, const QStringList &) const
{
if (offset == text.size() - 1 && text.at(offset) == m_char)
if (offset == text.size() - 1 && text.at(offset) == m_char) {
return offset + 1;
}
return offset;
}
@@ -564,24 +634,28 @@ bool RangeDetect::doLoad(QXmlStreamReader &reader)
{
const auto s1 = reader.attributes().value(QLatin1String("char"));
const auto s2 = reader.attributes().value(QLatin1String("char1"));
if (s1.isEmpty() || s2.isEmpty())
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
MatchResult RangeDetect::doMatch(QStringView text, int offset, const QStringList &) const
{
if (text.size() - offset < 2)
if (text.size() - offset < 2) {
return offset;
if (text.at(offset) != m_begin)
}
if (text.at(offset) != m_begin) {
return offset;
}
auto newOffset = offset + 1;
while (newOffset < text.size()) {
if (text.at(newOffset) == m_end)
if (text.at(newOffset) == m_end) {
return newOffset + 1;
}
++newOffset;
}
return offset;
@@ -596,7 +670,9 @@ bool RegExpr::doLoad(QXmlStreamReader &reader)
m_regexp.setPatternOptions((isMinimal ? QRegularExpression::InvertedGreedinessOption : QRegularExpression::NoPatternOption)
| (isCaseInsensitive ? QRegularExpression::CaseInsensitiveOption : QRegularExpression::NoPatternOption)
// DontCaptureOption is removed by resolvePostProcessing() when necessary
| QRegularExpression::DontCaptureOption);
| QRegularExpression::DontCaptureOption
// ensure Unicode support is enabled
| QRegularExpression::UseUnicodePropertiesOption);
m_dynamic = Xml::attrToBool(reader.attributes().value(QLatin1String("dynamic")));
@@ -605,8 +681,9 @@ bool RegExpr::doLoad(QXmlStreamReader &reader)
void KSyntaxHighlighting::RegExpr::resolvePostProcessing()
{
if (m_isResolved)
if (m_isResolved) {
return;
}
m_isResolved = true;
bool hasCapture = false;
@@ -641,7 +718,7 @@ void KSyntaxHighlighting::RegExpr::resolvePostProcessing()
}
}
MatchResult RegExpr::doMatch(const QString &text, int offset, const QStringList &captures) const
MatchResult RegExpr::doMatch(QStringView text, int offset, const QStringList &captures) const
{
/**
* for dynamic case: create new pattern with right instantiation
@@ -683,16 +760,16 @@ bool StringDetect::doLoad(QXmlStreamReader &reader)
return !m_string.isEmpty();
}
MatchResult StringDetect::doMatch(const QString &text, int offset, const QStringList &captures) const
MatchResult StringDetect::doMatch(QStringView 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 (offset + pattern.size() <= text.size()
&& QStringView(text).mid(offset, pattern.size()).compare(pattern, m_caseSensitivity) == 0)
if (offset + pattern.size() <= text.size() && text.mid(offset, pattern.size()).compare(pattern, m_caseSensitivity) == 0) {
return offset + pattern.size();
}
return offset;
}
@@ -704,23 +781,27 @@ bool WordDetect::doLoad(QXmlStreamReader &reader)
return !m_word.isEmpty();
}
MatchResult WordDetect::doMatch(const QString &text, int offset, const QStringList &) const
MatchResult WordDetect::doMatch(QStringView text, int offset, const QStringList &) const
{
if (text.size() - offset < m_word.size())
if (text.size() - offset < m_word.size()) {
return offset;
}
/**
* detect delimiter characters on the inner and outer boundaries of the string
* NOTE: m_word isn't empty
*/
if (offset > 0 && !isWordDelimiter(text.at(offset - 1)) && !isWordDelimiter(text.at(offset)))
if (offset > 0 && !isWordDelimiter(text.at(offset - 1)) && !isWordDelimiter(text.at(offset))) {
return offset;
}
if (QStringView(text).mid(offset, m_word.size()).compare(m_word, m_caseSensitivity) != 0)
if (text.mid(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())) || isWordDelimiter(text.at(offset + m_word.size() - 1)))
if (text.size() == offset + m_word.size() || isWordDelimiter(text.at(offset + m_word.size())) || isWordDelimiter(text.at(offset + m_word.size() - 1))) {
return offset + m_word.size();
}
return offset;
}

View File

@@ -87,7 +87,7 @@ public:
{
}
virtual MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const = 0;
virtual MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const = 0;
static Rule::Ptr create(QStringView name);
@@ -121,58 +121,58 @@ protected:
bool m_dynamic = false;
};
class AnyChar : public Rule
class AnyChar final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
private:
QString m_chars;
};
class DetectChar : public Rule
class DetectChar final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const override;
private:
QChar m_char;
int m_captureIndex = 0;
};
class Detect2Char : public Rule
class Detect2Char final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const override;
private:
QChar m_char1;
QChar m_char2;
};
class DetectIdentifier : public Rule
class DetectIdentifier final : public Rule
{
protected:
MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
class DetectSpaces : public Rule
class DetectSpaces final : public Rule
{
protected:
MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
class Float : public Rule
class Float final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
class IncludeRules : public Rule
class IncludeRules final : public Rule
{
public:
QString contextName() const;
@@ -181,7 +181,7 @@ public:
protected:
bool doLoad(QXmlStreamReader &reader) override;
MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
private:
QString m_contextName;
@@ -189,44 +189,44 @@ private:
bool m_includeAttribute;
};
class Int : public Rule
class Int final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const override;
};
class HlCChar : public Rule
class HlCChar final : public Rule
{
protected:
MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
class HlCHex : public Rule
class HlCHex final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
class HlCOct : public Rule
class HlCOct final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
class HlCStringChar : public Rule
class HlCStringChar final : public Rule
{
protected:
MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
class KeywordListRule : public Rule
class KeywordListRule final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
private:
KeywordList *m_keywordList;
@@ -234,55 +234,55 @@ private:
Qt::CaseSensitivity m_caseSensitivityOverride;
};
class LineContinue : public Rule
class LineContinue final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
private:
QChar m_char;
};
class RangeDetect : public Rule
class RangeDetect final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
private:
QChar m_begin;
QChar m_end;
};
class RegExpr : public Rule
class RegExpr final : public Rule
{
protected:
void resolvePostProcessing() override;
bool doLoad(QXmlStreamReader &reader) override;
MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const override;
private:
QRegularExpression m_regexp;
bool m_isResolved = false;
};
class StringDetect : public Rule
class StringDetect final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const override;
private:
QString m_string;
Qt::CaseSensitivity m_caseSensitivity;
};
class WordDetect : public Rule
class WordDetect final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const override;
private:
QString m_word;

View File

@@ -104,7 +104,8 @@ bool State::operator!=(const State &other) const
bool State::indentationBasedFoldingEnabled() const
{
if (!d || d->m_contextStack.isEmpty())
if (!d || d->m_contextStack.isEmpty()) {
return false;
}
return d->m_contextStack.last().first->indentationBasedFoldingEnabled();
}

View File

@@ -37,11 +37,13 @@ public:
FoldingRegion SyntaxHighlighterPrivate::foldingRegion(const QTextBlock &startBlock)
{
const auto data = dynamic_cast<TextBlockUserData *>(startBlock.userData());
if (!data)
if (!data) {
return FoldingRegion();
}
for (int i = data->foldingRegions.size() - 1; i >= 0; --i) {
if (data->foldingRegions.at(i).type() == FoldingRegion::Begin)
if (data->foldingRegions.at(i).type() == FoldingRegion::Begin) {
return data->foldingRegions.at(i);
}
}
return FoldingRegion();
}
@@ -68,8 +70,9 @@ void SyntaxHighlighter::setDefinition(const Definition &def)
{
const auto needsRehighlight = definition() != def;
AbstractHighlighter::setDefinition(def);
if (needsRehighlight)
if (needsRehighlight) {
rehighlight();
}
}
bool SyntaxHighlighter::startsFoldingRegion(const QTextBlock &startBlock) const
@@ -86,17 +89,21 @@ QTextBlock SyntaxHighlighter::findFoldingRegionEnd(const QTextBlock &startBlock)
while (block.isValid()) {
block = block.next();
const auto data = dynamic_cast<TextBlockUserData *>(block.userData());
if (!data)
if (!data) {
continue;
}
for (auto it = data->foldingRegions.constBegin(); it != data->foldingRegions.constEnd(); ++it) {
if ((*it).id() != region.id())
if ((*it).id() != region.id()) {
continue;
if ((*it).type() == FoldingRegion::End)
}
if ((*it).type() == FoldingRegion::End) {
--depth;
else if ((*it).type() == FoldingRegion::Begin)
} else if ((*it).type() == FoldingRegion::Begin) {
++depth;
if (depth == 0)
}
if (depth == 0) {
return block;
}
}
}
@@ -111,8 +118,9 @@ void SyntaxHighlighter::highlightBlock(const QString &text)
if (currentBlock().position() > 0) {
const auto prevBlock = currentBlock().previous();
const auto prevData = dynamic_cast<TextBlockUserData *>(prevBlock.userData());
if (prevData)
if (prevData) {
state = prevData->state;
}
}
d->foldingRegions.clear();
state = highlightLine(text, state);
@@ -126,35 +134,43 @@ void SyntaxHighlighter::highlightBlock(const QString &text)
return;
}
if (data->state == state && data->foldingRegions == d->foldingRegions) // we ended up in the same state, so we are done here
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())
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 (length == 0)
if (length == 0) {
return;
}
QTextCharFormat tf;
// always set the foreground color to avoid palette issues
tf.setForeground(format.textColor(theme()));
if (format.hasBackgroundColor(theme()))
if (format.hasBackgroundColor(theme())) {
tf.setBackground(format.backgroundColor(theme()));
if (format.isBold(theme()))
}
if (format.isBold(theme())) {
tf.setFontWeight(QFont::Bold);
if (format.isItalic(theme()))
}
if (format.isItalic(theme())) {
tf.setFontItalic(true);
if (format.isUnderline(theme()))
}
if (format.isUnderline(theme())) {
tf.setFontUnderline(true);
if (format.isStrikeThrough(theme()))
}
if (format.isStrikeThrough(theme())) {
tf.setFontStrikeOut(true);
}
QSyntaxHighlighter::setFormat(offset, length, tf);
}
@@ -165,13 +181,15 @@ void SyntaxHighlighter::applyFolding(int offset, int length, FoldingRegion regio
Q_UNUSED(length);
Q_D(SyntaxHighlighter);
if (region.type() == FoldingRegion::Begin)
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)
if (d->foldingRegions.at(i).id() != region.id() || d->foldingRegions.at(i).type() != FoldingRegion::Begin) {
continue;
}
d->foldingRegions.remove(i);
return;
}

View File

@@ -64,6 +64,8 @@ class RepositoryPrivate;
class KSYNTAXHIGHLIGHTING_EXPORT Theme
{
Q_GADGET
Q_PROPERTY(QString name READ name)
Q_PROPERTY(QString translatedName READ translatedName)
public:
// TODO KF6:
// - make TextStyle an enum class

View File

@@ -160,8 +160,9 @@ bool ThemeData::load(const QString &filePath)
for (auto it = customStyles.begin(); it != customStyles.end(); ++it) {
const auto obj = it.value().toObject();
auto &overrideStyle = m_textStyleOverrides[it.key()];
for (auto it2 = obj.begin(); it2 != obj.end(); ++it2)
for (auto it2 = obj.begin(); it2 != obj.end(); ++it2) {
overrideStyle.insert(it2.key(), readThemeData(it2.value().toObject()));
}
}
return true;

View File

@@ -4,14 +4,16 @@
SPDX-License-Identifier: MIT
*/
#include "wildcardmatcher_p.h"
#include "wildcardmatcher.h"
using namespace KSyntaxHighlighting;
#include <QChar>
#include <QString>
#include <QStringView>
static bool exactMatch(const QString &candidate, const QString &wildcard, int candidatePosFromRight, int wildcardPosFromRight, bool caseSensitive = true)
namespace
{
bool wildcardMatch(QStringView candidate, QStringView wildcard, int candidatePosFromRight, int wildcardPosFromRight)
{
for (; wildcardPosFromRight >= 0; wildcardPosFromRight--) {
const auto ch = wildcard.at(wildcardPosFromRight).unicode();
@@ -27,7 +29,7 @@ static bool exactMatch(const QString &candidate, const QString &wildcard, int ca
// 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)) {
if (wildcardMatch(candidate, wildcard, j, wildcardPosFromRight - 1)) {
return true;
}
}
@@ -47,18 +49,19 @@ static bool exactMatch(const QString &candidate, const QString &wildcard, int ca
}
const auto candidateCh = candidate.at(candidatePosFromRight).unicode();
const auto match = caseSensitive ? (candidateCh == ch) : (QChar::toLower(candidateCh) == QChar::toLower(ch));
if (match) {
if (candidateCh == ch) {
candidatePosFromRight--;
} else {
return false;
}
}
}
return true;
return candidatePosFromRight == -1;
}
bool WildcardMatcher::exactMatch(const QString &candidate, const QString &wildcard, bool caseSensitive)
} // unnamed namespace
bool WildcardMatcher::exactMatch(QStringView candidate, QStringView wildcard)
{
return ::exactMatch(candidate, wildcard, candidate.length() - 1, wildcard.length() - 1, caseSensitive);
return ::wildcardMatch(candidate, wildcard, candidate.length() - 1, wildcard.length() - 1);
}

View File

@@ -0,0 +1,33 @@
/*
SPDX-FileCopyrightText: 2007 Sebastian Pipping <webmaster@hartwork.org>
SPDX-License-Identifier: MIT
*/
#ifndef KSYNTAXHIGHLIGHTING_WILDCARDMATCHER_H
#define KSYNTAXHIGHLIGHTING_WILDCARDMATCHER_H
#include "ksyntaxhighlighting_export.h"
#include <QStringView>
namespace KSyntaxHighlighting
{
namespace WildcardMatcher
{
/**
* Matches a string against a given wildcard case-sensitively.
* The wildcard supports '*' (".*" in regex) and '?' ("." in regex), not more.
*
* @param candidate Text to match
* @param wildcard Wildcard to use
* @return True for an exact match, false otherwise
*
* @since 5.86
*/
KSYNTAXHIGHLIGHTING_EXPORT bool exactMatch(QStringView candidate, QStringView wildcard);
}
}
#endif // KSYNTAXHIGHLIGHTING_WILDCARDMATCHER_H

View File

@@ -11,15 +11,17 @@ using namespace KSyntaxHighlighting;
WordDelimiters::WordDelimiters()
: asciiDelimiters{}
{
for (const char *p = "\t !%&()*+,-./:;<=>?[\\]^{|}~"; *p; ++p)
for (const char *p = "\t !%&()*+,-./:;<=>?[\\]^{|}~"; *p; ++p) {
// int(*p) fix -Wchar-subscripts
asciiDelimiters[int(*p)] = true;
}
}
bool WordDelimiters::contains(QChar c) const
{
if (c.unicode() < 128)
if (c.unicode() < 128) {
return asciiDelimiters[c.unicode()];
}
// perf tells contains is MUCH faster than binary search here, very short array
return notAsciiDelimiters.contains(c);
}

View File

@@ -12,7 +12,7 @@
namespace KSyntaxHighlighting
{
/**
* Repesents a list of character that separates 2 words.
* Represents a list of character that separates 2 words.
*
* Default delimiters are .():!+*,-<=>%&/;?[]^{|}~\, space (' ') and tabulator ('\t').
*

View File

@@ -17,7 +17,7 @@ namespace Xml
/** Parse a xs:boolean attribute. */
inline bool attrToBool(QStringView str)
{
return str == QLatin1String("1") || str.compare(QString("true"), Qt::CaseInsensitive) == 0;
return str == QStringLiteral("1") || str.compare(QStringLiteral("true"), Qt::CaseInsensitive) == 0;
}
}

View File

@@ -3,7 +3,7 @@ include(autogenerated/autogenerated.pri)
QT += network
DEFINES += KSYNTAXHIGHLIGHTING_LIBRARY
DEFINES += KF5SyntaxHighlighting_EXPORTS
RESOURCES += \
data/themes/theme-data.qrc

View File

@@ -25,7 +25,7 @@ Project {
name: "KSyntaxHighlighting_bundled"
condition: !qtc.preferSystemSyntaxHighlighting || !Qt.KSyntaxHighlighting.present
cpp.defines: base.concat("KSYNTAXHIGHLIGHTING_LIBRARY")
cpp.defines: base.concat("KF5SyntaxHighlighting_EXPORTS")
cpp.includePaths: [
product.sourceDirectory + "/src/lib/",
product.sourceDirectory + "/autogenerated/src/lib/",
@@ -66,7 +66,6 @@ Project {
"htmlhighlighter.h",
"keywordlist.cpp",
"keywordlist_p.h",
"ksyntaxhighlighting_export.h",
"matchresult_p.h",
"repository.cpp",
"repository.h",