Merge remote-tracking branch 'origin/13.0'

Conflicts:
	cmake/QtCreatorIDEBranding.cmake
	qbs/modules/qtc/qtc.qbs

Change-Id: I2a3d92a14e4dd16897d19f7d8a8c7b0ec30d14a5
This commit is contained in:
Eike Ziller
2024-02-19 14:44:54 +01:00
196 changed files with 6735 additions and 3421 deletions

View File

@@ -83,4 +83,9 @@ QtcLibrary {
]
}
}
Export {
Depends { name: "cpp" }
cpp.includePaths: project.ide_source_tree + "/src/libs/3rdparty/"
}
}

View File

@@ -26,6 +26,7 @@ add_qtc_library(KSyntaxHighlighting
src/lib/definitiondownloader.cpp src/lib/definitiondownloader.h
src/lib/definitionref_p.h
src/lib/definition_p.h
src/lib/dynamicregexpcache_p.h
src/lib/foldingregion.cpp src/lib/foldingregion.h
src/lib/format.cpp src/lib/format.h src/lib/format_p.h
src/lib/htmlhighlighter.cpp src/lib/htmlhighlighter.h
@@ -44,7 +45,7 @@ add_qtc_library(KSyntaxHighlighting
src/lib/xml_p.h
)
set(export_symbol_declaration DEFINES KF5SyntaxHighlighting_EXPORTS)
set(export_symbol_declaration DEFINES KF6SyntaxHighlighting_EXPORTS)
if (QTC_STATIC_BUILD)
set(export_symbol_declaration PUBLIC_DEFINES KSYNTAXHIGHLIGHTING_STATIC_DEFINE)
endif()

View File

@@ -1,12 +1,12 @@
// This file was generated by ecm_setup_version(): DO NOT EDIT!
#ifndef SyntaxHighlighting_VERSION_H
#define SyntaxHighlighting_VERSION_H
#ifndef KSYNTAXHIGHLIGHTING_VERSION_H
#define KSYNTAXHIGHLIGHTING_VERSION_H
#define SyntaxHighlighting_VERSION_STRING "5.103.0"
#define SyntaxHighlighting_VERSION_MAJOR 5
#define SyntaxHighlighting_VERSION_MINOR 103
#define SyntaxHighlighting_VERSION_PATCH 0
#define SyntaxHighlighting_VERSION ((5<<16)|(103<<8)|(0))
#define KSYNTAXHIGHLIGHTING_VERSION_STRING "5.249.0"
#define KSYNTAXHIGHLIGHTING_VERSION_MAJOR 5
#define KSYNTAXHIGHLIGHTING_VERSION_MINOR 249
#define KSYNTAXHIGHLIGHTING_VERSION_PATCH 0
#define KSYNTAXHIGHLIGHTING_VERSION ((5<<16)|(249<<8)|(0))
#endif

View File

@@ -2,14 +2,12 @@
#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
# ifdef KF6SyntaxHighlighting_EXPORTS
/* We are building this library */
# define KSYNTAXHIGHLIGHTING_EXPORT Q_DECL_EXPORT
# else
@@ -43,8 +41,6 @@
#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
@@ -88,7 +84,7 @@
#define KSYNTAXHIGHLIGHTING_BUILD_DEPRECATED_SINCE(major, minor) 1
#ifdef KSYNTAXHIGHLIGHTING_NO_DEPRECATED
# define KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT 0x56700
# define KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT KSYNTAXHIGHLIGHTING_VERSION
#endif
#ifdef KSYNTAXHIGHLIGHTING_NO_DEPRECATED_WARNINGS
# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE 0
@@ -98,7 +94,7 @@
# ifdef KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT
# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT
# else
# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE 0x56700
# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE KSYNTAXHIGHLIGHTING_VERSION
# endif
#endif
@@ -107,112 +103,9 @@
#endif
#ifdef KSYNTAXHIGHLIGHTING_DEPRECATED
# define KSYNTAXHIGHLIGHTING_ENABLE_DEPRECATED_SINCE(major, minor) (ECM_GENERATEEXPORTHEADER_VERSION_VALUE(major, minor, 0) > KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT)
# define KSYNTAXHIGHLIGHTING_ENABLE_DEPRECATED_SINCE(major, minor) (((major<<16)|(minor<<8)) > 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 0x56700
#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 0x56700
# 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

@@ -8,4 +8,5 @@ name = "pypi"
[packages]
click = "~= 8.0"
jinja2 = "~= 3.0"
lxml = "*"
PyYAML = "*"

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd"
<!DOCTYPE language
[
<!-- NOTE See https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#variable-references -->
<!ENTITY var_ref_re "[/\.\+\-_0-9A-Za-z]+">
@@ -12,7 +12,7 @@
SPDX-FileCopyrightText: 2004 Alexander Neundorf <neundorf@kde.org>
SPDX-FileCopyrightText: 2005 Dominik Haumann <dhdev@gmx.de>
SPDX-FileCopyrightText: 2007, 2008, 2013, 2014 Matthew Woehlke <mw_triad@users.sourceforge.net>
SPDX-FileCopyrightText: 2013-2015, 2017-2020 Alex Turbov <i.zaufi@gmail.com>
SPDX-FileCopyrightText: 2013-2015, 2017-2023 Alex Turbov <i.zaufi@gmail.com>
SPDX-License-Identifier: LGPL-2.0-or-later
-->
@@ -26,7 +26,7 @@
<language
name="CMake"
version="<!--{version}-->"
kateversion="5.0"
kateversion="5.62"
section="Other"
extensions="CMakeLists.txt;*.cmake;*.cmake.in"
style="CMake"
@@ -94,6 +94,13 @@
<item><!--{ expr }--></item>
<!--[- endfor ]-->
</list>
<!--[- for expr in complex_generator_expressions ]-->
<list name="genex-<!--{expr.name}-->-subcommands">
<!--[- for cmd in expr.subcommands ]-->
<item><!--{ cmd }--></item>
<!--[- endfor ]-->
</list>
<!--[- endfor ]-->
<list name="standard-modules">
<!--[- for module in modules.utility ]-->
@@ -135,7 +142,7 @@
<contexts>
<context attribute="Normal Text" lineEndContext="#stay" name="Normal Text">
<DetectSpaces/>
<DetectSpaces />
<!--[ for command in commands -]-->
<WordDetect String="<!--{command.name}-->" insensitive="true" attribute="<!--{command.attribute}-->" context="<!--{command.name}-->_ctx"<!--[ if command.start_region ]--> beginRegion="<!--{command.start_region}-->"<!--[ endif -]--> <!--[- if command.end_region ]--> endRegion="<!--{command.end_region}-->"<!--[ endif ]--> />
<!--[ endfor -]-->
@@ -427,11 +434,22 @@
<DetectChar attribute="Comment" context="Comment" char="#" />
<DetectChar attribute="Generator Expression" context="#pop" char="&gt;" />
<keyword attribute="Generator Expression Keyword" context="#stay" String="generator-expressions" insensitive="false" />
<!--[- for expr in complex_generator_expressions ]-->
<WordDetect String="<!--{expr.name}-->" attribute="Generator Expression Keyword" context="genex_<!--{expr.name}-->_ctx" />
<!--[- endfor ]-->
<IncludeRules context="Detect Aliased Targets" />
<IncludeRules context="Detect Variable Substitutions" />
<DetectIdentifier />
</context>
<!--[- for expr in complex_generator_expressions ]-->
<context attribute="Generator Expression" lineEndContext="#stay" name="genex_<!--{expr.name}-->_ctx" fallthroughContext="#pop">
<DetectChar char=":" context="#stay" />
<DetectSpaces />
<keyword attribute="Generator Expression Sub-Command" context="#pop" String="genex-<!--{expr.name}-->-subcommands" insensitive="false" />
</context>
<!--[- endfor ]-->
</contexts>
<itemDatas>
@@ -460,6 +478,7 @@
<itemData name="Environment Variable Substitution" defStyleNum="dsFloat" spellChecking="false" />
<itemData name="Standard Environment Variable" defStyleNum="dsFloat" spellChecking="false" />
<itemData name="Generator Expression Keyword" defStyleNum="dsKeyword" color="#b84040" selColor="#b84040" spellChecking="false" />
<itemData name="Generator Expression Sub-Command" defStyleNum="dsKeyword" color="#c05050" selColor="#c05050" spellChecking="false" />
<itemData name="Generator Expression" defStyleNum="dsOthers" color="#b86050" selColor="#b86050" spellChecking="false" />
<itemData name="Standard Module" defStyleNum="dsImport" spellChecking="false" />
<itemData name="Deprecated Module" defStyleNum="dsImport" spellChecking="false" />

View File

@@ -1,4 +1,4 @@
version: 44
version: 50
global-properties:
- ALLOW_DUPLICATE_CUSTOM_TARGETS
@@ -112,11 +112,12 @@ target-properties:
- AUTOGEN_BUILD_DIR
- AUTOGEN_ORIGIN_DEPENDS # Since 3.14
- AUTOGEN_TARGET_DEPENDS
- AUTOMOC_COMPILER_PREDEFINES # Since ???
- AUTOGEN_USE_SYSTEM_INCLUDE # Since 3.27
- AUTOMOC_COMPILER_PREDEFINES # Since 3.10
- AUTOMOC_DEPEND_FILTERS
- AUTOMOC_EXECUTABLE # Since 3.14
- AUTOMOC_MACRO_NAMES
- AUTOMOC_MOC_OPTIONS # Since ???
- AUTOMOC_MOC_OPTIONS
- AUTOMOC_PATH_PREFIX # Since 3.16
- AUTOMOC
- AUTOUIC
@@ -154,14 +155,23 @@ target-properties:
- <CONFIG>_POSTFIX
- CROSSCOMPILING_EMULATOR
- CUDA_ARCHITECTURES # Since 3.18
- CUDA_CUBIN_COMPILATION # Since 3.27
- CUDA_EXTENSIONS
- CUDA_FATBIN_COMPILATION # Since 3.27
- CUDA_OPTIX_COMPILATION # Since 3.27
- CUDA_PTX_COMPILATION
- CUDA_SEPARABLE_COMPILATION
- CUDA_RESOLVE_DEVICE_SYMBOLS
- CUDA_RUNTIME_LIBRARY # Since 3.17
- CUDA_EXTENSIONS
- CUDA_STANDARD
- CUDA_STANDARD_REQUIRED
- CXX_EXTENSIONS
- CXX_MODULE_DIRS # Since 3.28
- CXX_MODULE_DIRS_<NAME> # Since 3.28
- CXX_MODULE_SET # Since 3.28
- CXX_MODULE_SET_<NAME> # Since 3.28
- CXX_MODULE_SETS # Since 3.28
- CXX_SCAN_FOR_MODULES # Since 3.28
- CXX_STANDARD
- CXX_STANDARD_REQUIRED
# - DEBUG_POSTFIX # NOTE: Handled by `<CONFIG>_POSTFIX`
@@ -170,6 +180,7 @@ target-properties:
- DEPLOYMENT_REMOTE_DIRECTORY
- DEPRECATION # Since 3.17
- DISABLE_PRECOMPILE_HEADERS # Since 3.16
- DLL_NAME_WITH_SOVERSION # Since 3.27
- DOTNET_SDK # Since 3.23
- DOTNET_TARGET_FRAMEWORK # Since 3.17
- DOTNET_TARGET_FRAMEWORK_VERSION # Since 3.12
@@ -234,10 +245,12 @@ target-properties:
- INSTALL_REMOVE_ENVIRONMENT_RPATH # Since 3.16
- INSTALL_RPATH
- INSTALL_RPATH_USE_LINK_PATH
- INTERFACE_AUTOMOC_MACRO_NAMES # Since 3.27
- INTERFACE_AUTOUIC_OPTIONS
- INTERFACE_COMPILE_DEFINITIONS
- INTERFACE_COMPILE_FEATURES
- INTERFACE_COMPILE_OPTIONS
- INTERFACE_CXX_MODULE_SETS # Since 3.28
- INTERFACE_HEADER_SETS # Since 3.23
- INTERFACE_HEADER_SETS_TO_VERIFY # Since 3.24
- INTERFACE_INCLUDE_DIRECTORIES
@@ -261,6 +274,7 @@ target-properties:
- JOB_POOL_LINK
- LABELS
- <LANG>_CLANG_TIDY
- <LANG>_CLANG_TIDY_EXPORT_FIXES_DIR # Since 3.26
- <LANG>_COMPILER_LAUNCHER
- <LANG>_CPPCHECK # Since 3.10
- <LANG>_CPPLINT
@@ -451,18 +465,22 @@ test-properties:
- FIXTURES_CLEANUP
- FIXTURES_REQUIRED
- FIXTURES_SETUP
- GENERATED_RESOURCE_SPEC_FILE # Since 3.28
- LABELS
- MEASUREMENT
- PASS_REGULAR_EXPRESSION
- PROCESSOR_AFFINITY # Since 3.12
- PROCESSORS
- REQUIRED_FILES
- RESOURCE_GROUPS # Since 3.16
- RESOURCE_LOCK
- RUN_SERIAL
- SKIP_REGULAR_EXPRESSION # Since 3.16
- SKIP_RETURN_CODE
- TIMEOUT
- TIMEOUT_AFTER_MATCH
- TIMEOUT_SIGNAL_GRACE_PERIOD # Since 3.27
- TIMEOUT_SIGNAL_NAME # Since 3.27
- WILL_FAIL
- WORKING_DIRECTORY
@@ -473,6 +491,7 @@ source-properties:
- COMPILE_DEFINITIONS
- COMPILE_FLAGS
- COMPILE_OPTIONS # Since 3.11
- CXX_SCAN_FOR_MODULES # Since 3.28
- EXTERNAL_OBJECT
- Fortran_FORMAT
- Fortran_PREPROCESS # Since 3.18
@@ -490,6 +509,7 @@ source-properties:
- SKIP_AUTOMOC
- SKIP_AUTORCC
- SKIP_AUTOUIC
- SKIP_LINTING # Since 3.27
- SKIP_PRECOMPILE_HEADERS # Since 3.16
- SKIP_UNITY_BUILD_INCLUSION # Since 3.16
- Swift_DEPENDENCIES_FILE # Since 3.15
@@ -535,76 +555,155 @@ install-properties:
- CPACK_WIX_ACL
generator-expressions:
# Boolean Generator Expressions
# * Logical Operators
# Conditional Expressions
- IF
- 0
- 1
- BOOL
# Logical Operators
- AND
- OR
- NOT
# * String Comparisons
# String Comparisons
- STREQUAL
- EQUAL
- IN_LIST # Since 3.12
# Version Comparisons
- VERSION_LESS
- VERSION_GREATER
- VERSION_EQUAL
- VERSION_LESS_EQUAL
- VERSION_GREATER_EQUAL
# * Path Comparisons
- PATH_EQUAL # Since 3.24
# * Path Queries
# * Path Decomposition
# * Path Transformations
# TODO Need a bit deeper genex parsing to get sub-commands of `PATH`
- PATH # Since 3.24
# * Variable Queries
- TARGET_EXISTS # Since 3.12
- CONFIG
- PLATFORM_ID
- C_COMPILER_ID
- CXX_COMPILER_ID
- CUDA_COMPILER_ID # Since 3.15
- Fortran_COMPILER_ID
- C_COMPILER_VERSION
- CXX_COMPILER_VERSION
- CUDA_COMPILER_VERSION # Since 3.15
- Fortran_COMPILER_VERSION
- TARGET_POLICY
- COMPILE_FEATURES
- COMPILE_LANG_AND_ID # Since 3.15
- COMPILE_LANGUAGE
- LINK_LANG_AND_ID # Since 3.18
- LINK_LANGUAGE # Since 3.18
- DEVICE_LINK # Since 3.18
- HOST_LINK # Since 3.18
- LINK_LIBRARY # Since 3.24
- LINK_GROUP # Since 3.24
# String-Valued Generator Expressions
# * Escaped Characters
- ANGLE-R
- COMMA
- SEMICOLON
# * Conditional Expressions
- IF
# * String Transformations
# String Transformations
- LOWER_CASE
- UPPER_CASE
- MAKE_C_IDENTIFIER
# List Expressions
# * List Comparisons
- IN_LIST # Since 3.12
- name: LIST # Since 3.27
subcommands:
# * List Queries
- LENGTH
- GET
- SUBLIST
- FIND
# * List Transformations
- JOIN
- APPEND
- PREPEND
- INSERT
- POP_BACK
- POP_FRONT
- REMOVE_ITEM
- REMOVE_AT
- REMOVE_DUPLICATES
- FILTER
- TRANSFORM
- FRANSFORM
# * List Ordering
- REVERSE
- SORT
- JOIN
- REMOVE_DUPLICATES # Since 3.15
- FILTER # Since 3.15
- LOWER_CASE
- UPPER_CASE
- GENEX_EVAL # Since 3.12
- TARGET_GENEX_EVAL # Since 3.12
# * Variable Queries (NOTE Already included above)
# * Target-Dependent Queries
# Path Expressions
# * Path Comparisons
- PATH_EQUAL # Since 3.24
- name: PATH # Since 3.24
subcommands:
# * Path Queries
- 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
# * Path Decomposition
- GET_ROOT_NAME
- GET_ROOT_DIRECTORY
- GET_ROOT_PATH
- GET_FILENAME
- GET_EXTENSION
- GET_STEM
- GET_RELATIVE_PART
- GET_PARENT_PATH
# * Path Transformations
- CMAKE_PATH
- APPEND
- REMOVE_FILENAME
- REPLACE_FILENAME
- REMOVE_EXTENSION
- REPLACE_EXTENSION
- NORMAL_PATH
- RELATIVE_PATH
- ABSOLUTE_PATH
# Shell Paths
- SHELL_PATH
# Configuration Expressions
- CONFIG
- OUTPUT_CONFIG # Since 3.20
- COMMAND_CONFIG # Since 3.20
# Toolchain And Language Expressions
# * Platform
- PLATFORM_ID
# * Compiler Version
- C_COMPILER_VERSION
- CXX_COMPILER_VERSION
- CUDA_COMPILER_VERSION # Since 3.15
- OBJC_COMPILER_VERSION # Since 3.16
- OBJCXX_COMPILER_VERSION # Since 3.16
- Fortran_COMPILER_VERSION
- HIP_COMPILER_VERSION # Since 3.21
- ISPC_COMPILER_VERSION # Since 3.19
# * Compiler Language And ID
- C_COMPILER_ID
- CXX_COMPILER_ID
- CUDA_COMPILER_ID # Since 3.15
- OBJC_COMPILER_ID # Since 3.16
- OBJCXX_COMPILER_ID # Since 3.16
- Fortran_COMPILER_ID
- HIP_COMPILER_ID # Since 3.21
- ISPC_COMPILER_ID # Since 3.19
- COMPILE_LANGUAGE # Since 3.3
- COMPILE_LANG_AND_ID # Since 3.15
# * Compile Features
- COMPILE_FEATURES
# * Compile Context
- COMPILE_ONLY # Since 3.27
# * Linker Language And ID
- LINK_LANGUAGE # Since 3.18
- LINK_LANG_AND_ID # Since 3.18
# * Link Features
- LINK_LIBRARY # Since 3.24
- LINK_GROUP # Since 3.24
# * Link Context
- LINK_ONLY
- DEVICE_LINK # Since 3.18
- HOST_LINK # Since 3.18
# Target-Dependent Expressions
- TARGET_EXISTS # Since 3.12
- TARGET_NAME_IF_EXISTS # Since 3.12
- TARGET_NAME
- TARGET_PROPERTY
- TARGET_OBJECTS
- TARGET_POLICY
- TARGET_FILE
- TARGET_FILE_BASE_NAME # Since 3.15
- TARGET_FILE_PREFIX # Since 3.15
- TARGET_FILE_SUFFIX # Since 3.15
- TARGET_FILE_NAME
- TARGET_FILE_DIR
- TARGET_IMPORT_FILE # Since 3.27
- TARGET_IMPORT_FILE_BASE_NAME # Since 3.27
- TARGET_IMPORT_FILE_PREFIX # Since 3.27
- TARGET_IMPORT_FILE_SUFFIX # Since 3.27
- TARGET_IMPORT_FILE_NAME # Since 3.27
- TARGET_IMPORT_FILE_DIR # Since 3.27
- TARGET_LINKER_FILE
- TARGET_LINKER_FILE_BASE_NAME # Since 3.15
- TARGET_LINKER_FILE_PREFIX # Since 3.15
@@ -612,7 +711,6 @@ generator-expressions:
- TARGET_LINKER_FILE_NAME
- TARGET_LINKER_FILE_DIR
- TARGET_SONAME_FILE
- TARGET_SONAME_FILE
- TARGET_SONAME_FILE_NAME
- TARGET_SONAME_FILE_DIR
- TARGET_PDB_FILE
@@ -622,19 +720,22 @@ generator-expressions:
- TARGET_BUNDLE_DIR_NAME # Since 3.24
- TARGET_BUNDLE_DIR
- TARGET_BUNDLE_CONTENT_DIR
- TARGET_PROPERTY
- TARGET_RUNTIME_DLLS # Since 3.21
- INSTALL_PREFIX
# Output-Related Expressions
- TARGET_NAME
- LINK_ONLY
- TARGET_RUNTIME_DLL_DIRS # Since 3.27
# Export And Install Expressions
- INSTALL_INTERFACE
- BUILD_INTERFACE
- MAKE_C_IDENTIFIER
- TARGET_OBJECTS
- SHELL_PATH
- OUTPUT_CONFIG # Since 3.20
- COMMAND_CONFIG # Since 3.20
- BUILD_LOCAL_INTERFACE # Since 3.26
- INSTALL_PREFIX
# Multi-level Expression Evaluation
- GENEX_EVAL # Since 3.12
- TARGET_GENEX_EVAL # Since 3.12
# Escaped Characters
- ANGLE-R
- COMMA
- SEMICOLON
# Deprecated Expressions
# - CONFIGURATION
variables:
# Variables that Provide Information
@@ -686,6 +787,7 @@ variables:
- CMAKE_JOB_POOL_LINK
- CMAKE_JOB_POOLS # Since 3.11
- CMAKE_<LANG>_COMPILER_AR
- CMAKE_<LANG>_COMPILER_FRONTEND_VARIANT # Since 3.14
- CMAKE_<LANG>_COMPILER_RANLIB
- CMAKE_LINK_LIBRARY_SUFFIX
- CMAKE_LINK_SEARCH_END_STATIC
@@ -735,9 +837,17 @@ variables:
- CMAKE_VS_NsightTegra_VERSION
- CMAKE_VS_NUGET_PACKAGE_RESTORE # Since 3.23
- CMAKE_VS_PLATFORM_NAME
- CMAKE_VS_PLATFORM_NAME_DEFAULT # Since 3.14.3
- CMAKE_VS_PLATFORM_TOOLSET
- CMAKE_VS_PLATFORM_TOOLSET_CUDA
- CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE
- CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR # Since 3.16
- CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE # Since 3.8
- CMAKE_VS_PLATFORM_TOOLSET_VERSION # Since 3.12
- CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER # Since 3.22
- CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION # Since 3.22
- CMAKE_VS_TARGET_FRAMEWORK_VERSION # Since 3.22
- CMAKE_VS_VERSION_BUILD_NUMBER # Since 3.26
- CMAKE_VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION # Since 3.27
- CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION
- CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM # Since 3.19
- CMAKE_XCODE_BUILD_SYSTEM # Since 3.19
@@ -766,6 +876,7 @@ variables:
# Variables that Change Behavior
- BUILD_SHARED_LIBS
- CMAKE_ABSOLUTE_DESTINATION_FILES
- CMAKE_ADD_CUSTOM_COMMAND_DEPENDS_EXPLICIT_ONLY # Since 3.27
- CMAKE_APPBUNDLE_PATH
- CMAKE_AUTOMOC_RELAXED_MODE
- CMAKE_BACKWARDS_COMPATIBILITY
@@ -973,16 +1084,20 @@ variables:
- CMAKE_ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>
- CMAKE_AUTOGEN_ORIGIN_DEPENDS # Since 3.14
- CMAKE_AUTOGEN_PARALLEL
- CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE # Since 3.27
- CMAKE_AUTOGEN_VERBOSE # Since 3.13
- CMAKE_AUTOMOC
- CMAKE_AUTOMOC_DEPEND_FILTERS
- CMAKE_AUTOMOC_MOC_OPTIONS
- CMAKE_AUTOMOC_PATH_PREFIX # Since 3.16
- CMAKE_AUTOMOC_EXECUTABLE # Since 3.27
- CMAKE_AUTORCC
- CMAKE_AUTORCC_OPTIONS
- CMAKE_AUTORCC_EXECUTABLE # Since 3.27
- CMAKE_AUTOUIC
- CMAKE_AUTOUIC_OPTIONS
- CMAKE_AUTOUIC_SEARCH_PATHS
- CMAKE_AUTOUIC_EXECUTABLE # Since 3.27
- CMAKE_BUILD_RPATH
- CMAKE_BUILD_RPATH_USE_ORIGIN # Since 3.14
- CMAKE_BUILD_WITH_INSTALL_NAME_DIR
@@ -993,14 +1108,17 @@ variables:
- CMAKE_<CONFIG>_POSTFIX
- CMAKE_CROSS_CONFIGS # Since 3.17
- CMAKE_CTEST_ARGUMENTS # Since 3.17
- CMAKE_CUDA_SEPARABLE_COMPILATION # Since 3.11
- CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS # Since 3.16
- CMAKE_CUDA_RUNTIME_LIBRARY # Since 3.17
- CMAKE_CUDA_SEPARABLE_COMPILATION # Since 3.11
- CMAKE_CXX_SCAN_FOR_MODULES # Since 3.28
- CMAKE_DEBUG_POSTFIX
- CMAKE_DEFAULT_BUILD_TYPE # Since 3.17
- CMAKE_DEFAULT_CONFIGS # Since 3.17
- CMAKE_DISABLE_PRECOMPILE_HEADERS # Since 3.17
- CMAKE_ENABLE_EXPORTS
- CMAKE_DLL_NAME_WITH_SOVERSION # Since 3.27
# `CMAKE_ENABLE_EXPORTS` has been moved to deprecated section
- CMAKE_EXECUTABLE_ENABLE_EXPORTS # Since 3.27
- CMAKE_EXE_LINKER_FLAGS
- CMAKE_EXE_LINKER_FLAGS_<CONFIG>
- CMAKE_EXE_LINKER_FLAGS_<CONFIG>_INIT
@@ -1024,8 +1142,8 @@ variables:
- CMAKE_INSTALL_RPATH_USE_LINK_PATH
- CMAKE_INTERPROCEDURAL_OPTIMIZATION
- CMAKE_INTERPROCEDURAL_OPTIMIZATION_<CONFIG>
- CMAKE_IOS_INSTALL_COMBINED
- CMAKE_<LANG>_CLANG_TIDY
- CMAKE_<LANG>_CLANG_TIDY_EXPORT_FIXES_DIR # Since 3.26
- CMAKE_<LANG>_COMPILER_LAUNCHER
- CMAKE_<LANG>_CPPCHECK # Since 3.10
- CMAKE_<LANG>_CPPLINT
@@ -1044,6 +1162,9 @@ variables:
- CMAKE_LIBRARY_PATH_FLAG
- CMAKE_LINK_DEF_FILE_FLAG
- CMAKE_LINK_DEPENDS_NO_SHARED
- CMAKE_LINK_DEPENDS_USE_LINKER # Since 3.27
- CMAKE_LINK_GROUP_USING_<FEATURE> # Since 3.24
- CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED # Since 3.24
- CMAKE_LINK_INTERFACE_LIBRARIES
- CMAKE_LINK_LIBRARY_FILE_FLAG
- CMAKE_LINK_LIBRARY_FLAG
@@ -1072,9 +1193,11 @@ variables:
- CMAKE_PCH_INSTANTIATE_TEMPLATES # Since 3.19
- CMAKE_PDB_OUTPUT_DIRECTORY
- CMAKE_PDB_OUTPUT_DIRECTORY_<CONFIG>
- CMAKE_PLATFORM_NO_VERSIONED_SONAME # Since 3.1
- CMAKE_POSITION_INDEPENDENT_CODE
- CMAKE_RUNTIME_OUTPUT_DIRECTORY
- CMAKE_RUNTIME_OUTPUT_DIRECTORY_<CONFIG>
- CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS # Since 3.27
- CMAKE_SHARED_LINKER_FLAGS
- CMAKE_SHARED_LINKER_FLAGS_<CONFIG>
- CMAKE_SHARED_LINKER_FLAGS_<CONFIG>_INIT
@@ -1095,6 +1218,10 @@ variables:
- CMAKE_USE_RELATIVE_PATHS
- CMAKE_VERIFY_INTERFACE_HEADER_SETS # Since 3.24
- CMAKE_VISIBILITY_INLINES_HIDDEN
- CMAKE_VS_DEBUGGER_COMMAND # Since 3.27
- CMAKE_VS_DEBUGGER_COMMAND_ARGUMENTS # Since 3.27
- CMAKE_VS_DEBUGGER_ENVIRONMENT # Since 3.27
- CMAKE_VS_DEBUGGER_WORKING_DIRECTORY # Since 3.27
- CMAKE_VS_GLOBALS # Since 3.13
- CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD
- CMAKE_VS_INCLUDE_PACKAGE_TO_DEFAULT_BUILD
@@ -1137,6 +1264,7 @@ variables:
- CMAKE_Fortran_MODOUT_FLAG
- CMAKE_HIP_ARCHITECTURES # Since 3.21
- CMAKE_HIP_EXTENSIONS # Since 3.21
- CMAKE_HIP_PLATFORM # Since 3.28
- CMAKE_HIP_STANDARD # Since 3.21
- CMAKE_HIP_STANDARD_REQUIRED # Since 3.21
- CMAKE_ISPC_HEADER_DIRECTORY # Since 3.19
@@ -1533,6 +1661,41 @@ variables:
- CPACK_COMMAND_HDIUTIL
- CPACK_COMMAND_SETFILE
- CPACK_COMMAND_REZ
# [built-in]: CPack Inno Setup Generator (Since 3.27)
- CPACK_INNOSETUP_USE_CMAKE_BOOL_FORMAT
- CPACK_INNOSETUP_ARCHITECTURE
- CPACK_INNOSETUP_INSTALL_ROOT
- CPACK_INNOSETUP_ALLOW_CUSTOM_DIRECTORY
- CPACK_INNOSETUP_PROGRAM_MENU_FOLDER
- CPACK_INNOSETUP_LANGUAGES
- CPACK_INNOSETUP_IGNORE_LICENSE_PAGE
- CPACK_INNOSETUP_IGNORE_README_PAGE
- CPACK_INNOSETUP_PASSWORD
- CPACK_INNOSETUP_USE_MODERN_WIZARD
- CPACK_INNOSETUP_ICON_FILE
- CPACK_INNOSETUP_SETUP_<directive>
- CPACK_INNOSETUP_CUSTOM_INSTALL_INSTRUCTIONS
- CPACK_INNOSETUP_MENU_LINKS
- CPACK_INNOSETUP_CREATE_UNINSTALL_LINK
- CPACK_INNOSETUP_RUN_EXECUTABLES
- CPACK_INNOSETUP_<compName>_INSTALL_DIRECTORY
- CPACK_INNOSETUP_VERIFY_DOWNLOADS
- CPACK_INNOSETUP_EXECUTABLE
- CPACK_INNOSETUP_EXECUTABLE_ARGUMENTS
- CPACK_INNOSETUP_DEFINE_<macro>
- CPACK_INNOSETUP_EXTRA_SCRIPTS
- CPACK_INNOSETUP_CODE_FILES
# [built-in]: CPack FreeBSD Generator (Since 3.10)
- CPACK_FREEBSD_PACKAGE_NAME
- CPACK_FREEBSD_PACKAGE_COMMENT
- CPACK_FREEBSD_PACKAGE_DESCRIPTION
- CPACK_FREEBSD_PACKAGE_WWW
- CPACK_FREEBSD_PACKAGE_LICENSE
- CPACK_FREEBSD_PACKAGE_LICENSE_LOGIC
- CPACK_FREEBSD_PACKAGE_MAINTAINER
- CPACK_FREEBSD_PACKAGE_ORIGIN
- CPACK_FREEBSD_PACKAGE_CATEGORIES
- CPACK_FREEBSD_PACKAGE_DEPS
# -CPackExt (Since 3.13)
- CPACK_EXTERNAL_REQUESTED_VERSIONS
- CPACK_EXTERNAL_ENABLE_STAGING
@@ -1970,6 +2133,7 @@ variables:
- CUPS_INCLUDE_DIR
# - FindCURL
- CURL_NO_CURL_CMAKE
- CURL_USE_STATIC_LIBS # Since 3.28
# - FindCurses
- CURSES_CFLAGS
- CURSES_HAVE_CURSES_H
@@ -1989,7 +2153,6 @@ variables:
- CXXTEST_TESTGEN_EXECUTABLE
- CXXTEST_TESTGEN_INTERPRETER
# - FindCygwin
# - FindDart
# - FindDCMTK
# - FindDevIL
# - FindDoxygen
@@ -1997,6 +2160,7 @@ variables:
# - FindEnvModules
- EnvModules_COMMAND
# - FindEXPAT
- EXPAT_USE_STATIC_LIBS # Since 3.28
# - FindFLEX
- FLEX_EXECUTABLE
# - FindFLTK
@@ -2598,6 +2762,11 @@ deprecated-or-internal-variables:
- CMAKE_OBJDUMP
# Mentioned in "Deprecated and Removed Features" of release notes 3.21
- CMAKE_SYSTEM_ARCH
# Superseded by `CMAKE_EXECUTABLE_ENABLE_EXPORTS`
- CMAKE_ENABLE_EXPORTS
- CMAKE_IOS_INSTALL_COMBINED # Since 3.28
# 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
@@ -2614,6 +2783,7 @@ environment-variables:
- CMAKE_COLOR_DIAGNOSTICS # Since 3.24
- CMAKE_CONFIGURATION_TYPES # Since 3.22
- CMAKE_CONFIG_TYPE
- CMAKE_CROSSCOMPILING_EMULATOR # Since 3.28
- CMAKE_EXPORT_COMPILE_COMMANDS # Since 3.17
- CMAKE_GENERATOR
- CMAKE_GENERATOR_INSTANCE
@@ -2657,11 +2827,13 @@ environment-variables:
# Environment Variables for CTest
- CMAKE_CONFIG_TYPE
- CTEST_INTERACTIVE_DEBUG_MODE
- CTEST_NO_TESTS_ACTION # Since 3.26
- CTEST_OUTPUT_ON_FAILURE
- CTEST_PARALLEL_LEVEL
- CTEST_PROGRESS_OUTPUT
- CTEST_USE_LAUNCHERS_DEFAULT
- DASHBOARD_TEST_FROM_CTEST
# Environment Variables for the CMake curses interface
- CCMAKE_COLORS
# Here are the `find_package` specific variables described at the
# https://cmake.org/cmake/help/latest/command/find_package.html
@@ -2731,6 +2903,7 @@ scripting-commands:
, OS_RELEASE
, OS_VERSION
, OS_PLATFORM
, MSYSTEM_PREFIX # Since 3.28
# Since 3.22
, DISTRIB_INFO
, DISTRIB_<name>
@@ -3380,6 +3553,8 @@ scripting-commands:
, CHECK_START
, CHECK_PASS
, CHECK_FAIL
# Since 3.26
, CONFIGURE_LOG
]
-
name: option
@@ -3520,10 +3695,12 @@ project-commands:
, COMMENT
, DEPFILE
, JOB_POOL # Since 3.15
, JOB_SERVER_AWARE # Since 3.28
, VERBATIM
, APPEND
, USES_TERMINAL
, COMMAND_EXPAND_LISTS
, DEPENDS_EXPLICIT_ONLY # Since 3.27
, TARGET
, PRE_BUILD
, PRE_LINK
@@ -3543,6 +3720,7 @@ project-commands:
, COMMENT
, DEPFILE
, JOB_POOL # Since 3.15
, JOB_SERVER_AWARE # Since 3.28
, VERBATIM
, APPEND
, USES_TERMINAL
@@ -3587,6 +3765,9 @@ project-commands:
, TARGET
]
has-target-name-after-kw: TARGET
-
name: cmake_file_api # Since 3.27
named-args: [QUERY, API_VERSION, CODEMODEL, CACHE, CMAKEFILES, TOOLCHAINS]
-
name: create_test_sourcelist
named-args: [EXTRA_INCLUDE, FUNCTION]
@@ -3614,6 +3795,7 @@ project-commands:
ASM
, ASM-ATT
, ASM_NASM
, ASM_MARMASM # Since 3.26
, ASM_MASM
, C
, CSharp
@@ -3650,6 +3832,7 @@ project-commands:
property-args: &get_target_property [target-properties]
-
name: get_test_property
named-args: [DIRECTORY] # Since 3.28
property-args: &get_test_property [test-properties]
-
name: include_directories
@@ -3741,7 +3924,7 @@ project-commands:
named-args: [AFTER, BEFORE]
-
name: link_libraries
named-args: [debug, optimized, general]
special-args: &link_libraries_sa [debug, optimized, general]
-
name: load_cache
named-args: [READ_WITH_PREFIX, EXCLUDE, INCLUDE_INTERNALS]
@@ -3793,7 +3976,10 @@ project-commands:
first-args-are-targets?: true # NOTE Multiple target args
-
name: set_tests_properties
named-args: [PROPERTIES]
named-args: [
DIRECTORY # Since 3.28
, PROPERTIES
]
property-args: *get_test_property
-
name: source_group
@@ -3888,6 +4074,7 @@ project-commands:
, cuda_std_17
, cuda_std_20
, cuda_std_23 # Since 3.21
, cuda_std_26 # Since 3.25
]
first-arg-is-target?: true
-
@@ -3913,6 +4100,7 @@ project-commands:
-
name: target_link_libraries
named-args: *target_compile_definitions
special-args: *link_libraries_sa
first-arg-is-target?: true
-
name: target_link_options
@@ -3935,6 +4123,10 @@ project-commands:
, BASE_DIRS
, FILES
]
special-args: [
HEADERS
, CXX_MODULES # Since 3.28
]
first-arg-is-target?: true
-
name: try_compile
@@ -3959,6 +4151,9 @@ project-commands:
, SOURCE_FROM_CONTENT
, SOURCE_FROM_VAR
, SOURCE_FROM_FILE
# Since 3.26
, LOG_DESCRIPTION
, NO_LOG
]
-
name: try_run
@@ -3987,6 +4182,9 @@ project-commands:
, NO_CACHE
, RUN_OUTPUT_STDOUT_VARIABLE
, RUN_OUTPUT_STDERR_VARIABLE
# Since 3.26
, LOG_DESCRIPTION
, NO_LOG
]
ctest-commands:
@@ -4150,7 +4348,6 @@ modules:
- CTestCoverageCollectGCOV
- CTestScriptMode
- CTestUseLaunchers
- Dart
- DeployQt4
- ExternalData
- ExternalProject
@@ -4196,7 +4393,6 @@ modules:
- FindCVS
- FindCxxTest
- FindCygwin
- FindDart
- FindDCMTK
- FindDevIL
- FindDoxygen
@@ -4339,6 +4535,7 @@ modules:
- CMakeExpandImportedTargets
- CMakeForceCompiler
- CMakeParseArguments
- Dart # Since 3.27
- Documentation
- MacroAddFileDependencies
- TestCXXAcceptsFlag
@@ -4350,6 +4547,7 @@ modules:
- WriteCompilerDetectionHeader
# Deprecated Find Modules
- FindCUDA
- FindDart # Since 3.27
- FindPythonInterp
- FindPythonLibs
- FindQt
@@ -4773,6 +4971,7 @@ standard-module-commands:
- BUILD_IN_SOURCE
- BUILD_ALWAYS
- BUILD_BYPRODUCTS
- BUILD_JOB_SERVER_AWARE # Since 3.28
- INSTALL_COMMAND
- TEST_COMMAND
- TEST_BEFORE_INSTALL
@@ -4800,6 +4999,7 @@ standard-module-commands:
- INDEPENDENT_STEP_TARGETS
- LIST_SEPARATOR
- COMMAND
- INSTALL_BYPRODUCTS # Since 3.26
special-args: [IGNORED, OPTIONAL, REQUIRED, CHECKOUT, REBASE, REBASE_CHECKOUT]
property-args: *get_target_property
- name: ExternalProject_Get_Property
@@ -4814,6 +5014,7 @@ standard-module-commands:
- INDEPENDENT
- BYPRODUCTS
- ALWAYS
- JOB_SERVER_AWARE # Since 3.28
- EXCLUDE_FROM_MAIN
- WORKING_DIRECTORY
- LOG
@@ -4901,7 +5102,10 @@ standard-module-commands:
- UPDATE_DISCONNECTED
- PATCH_COMMAND
- SOURCE_SUBDIR
- OVERRIDE_FIND_PACKAGE
- FIND_PACKAGE_ARGS
- SYSTEM
- EXCLUDE_FROM_ALL # Since 3.28
-
name: FetchContent_Populate
named-args:
@@ -5169,7 +5373,12 @@ standard-module-commands:
# FindDoxygen
-
name: doxygen_add_docs
named-args: [ALL, USE_STAMP_FILE, WORKING_DIRECTORY, COMMENT]
named-args:
- ALL
- USE_STAMP_FILE
- WORKING_DIRECTORY
- COMMENT
- CONFIG_FILE # Since 3.27
# FindEnvModules
-
name: env_module
@@ -5248,6 +5457,7 @@ standard-module-commands:
named-args: *pkgcm
-
name: pkg_get_variable
named-args: [DEFINE_VARIABLES] # Since 3.28
# FindProtobuf
-
name: protobuf_generate_cpp

View File

@@ -3,25 +3,31 @@
#
# Generate Kate syntax file for CMake
#
# SPDX-FileCopyrightText: 2017-2020 Alex Turbov <i.zaufi@gmail.com>
# SPDX-FileCopyrightText: 2017-2023 Alex Turbov <i.zaufi@gmail.com>
#
# To install prerequisites:
#
# $ pip install --user click jinja2 pyyaml
# $ pip install --user click jinja2 lxml pyyaml
#
# To use:
#
# $ ./generate-cmake-syntax.py cmake.yaml > ../syntax/cmake.xml
#
from __future__ import annotations
import functools
import re
from dataclasses import dataclass, field
import click
import jinja2
import re
import yaml
import sys
from lxml import etree
_TEMPLATED_NAME = re.compile('<[^>]+>')
_TEMPLATED_NAME = re.compile(r'(?:<[^>]+>)')
_PROPERTY_KEYS = [
'global-properties'
, 'directory-properties'
@@ -33,7 +39,7 @@ _PROPERTY_KEYS = [
]
_KW_RE_LIST = ['kw', 're']
_VAR_KIND_LIST = ['variables', 'deprecated-or-internal-variables', 'environment-variables']
_CONTROL_FLOW_LIST = set((
_CONTROL_FLOW_LIST = {
'break'
, 'continue'
, 'elseif'
@@ -45,39 +51,226 @@ _CONTROL_FLOW_LIST = set((
, 'if'
, 'return'
, 'while'
))
}
_VAR_REF_ENTITY = '&var_ref_re;'
_HEURISTICS = [
(
{'MAX(_(COUNT|MAJOR|MINOR|PATCH|TWEAK))?', 'MIN(_(COUNT|MAJOR|MINOR|PATCH|TWEAK))?'}
, 'M(AX|IN)(_(COUNT|MAJOR|MINOR|PATCH|TWEAK))?'
)
, ({'OUTPUTS', 'OUTPUT_(HEADER|SOURCE)'}, 'OUTPUT(S|_(HEADER|SOURCE))')
, ({'PREFIX', 'SUFFIX'}, '(PRE|SUF)FIX')
, ({'CPPCHECK', 'CPPLINT'}, 'CPP(CHECK|LINT)')
, ({'DEPENDS', 'PREDEPENDS'}, '(PRE)?DEPENDS')
, ({'ICON', 'ICONURL'}, 'ICON(URL)?')
, (
{
'&var%ref%re;(_INIT)?'
, 'DEBUG(_INIT)?'
, 'MINSIZEREL(_INIT)?'
, 'RELEASE(_INIT)?'
, 'RELWITHDEBINFO(_INIT)?'
}
, '(DEBUG|MINSIZEREL|REL(EASE|WITHDEBINFO)|&var%ref%re;)(_INIT)?'
)
, ({'RELEASE', 'RELWITHDEBINFO'}, 'REL(EASE|WITHDEBINFO)')
, ({'POST', 'POSTUN', 'PRE', 'PREUN'}, 'P(RE|OST)(UN)?')
, ({'AUTOPROV', 'AUTOREQ', 'AUTOREQPROV'}, 'AUTO(PROV|REQ(PROV)?)')
, ({'DEFINITIONS', 'OPTIONS'}, '(DEFINI|OP)TIONS')
, ({'LIB_NAMES', 'LIBRARY'}, 'LIB(_NAMES|RARY)')
, ({'EXTENSIONS', 'EXTRA_FLAGS'}, 'EXT(ENSIONS|RA_FLAGS)')
, ({'DISABLED', 'DISPLAY_NAME'}, 'DIS(ABLED|PLAY_NAME)')
, ({'LIBRARIES', 'LINK_LIBRARIES', 'STATIC_LINK_LIBRARIES'}, '((STATIC_)?LINK_)?LIBRARIES')
, ({'INCLUDE_DIRS', 'LIBRARY_DIRS'}, '(INCLUDE|LIBRARY)_DIRS')
, ({'BINARY_DIR', 'SOURCE_DIR'}, '(BINARY|SOURCE)_DIR')
, ({'CFLAGS(_OTHER)?', 'LDFLAGS(_OTHER)?'}, '(C|LD)FLAGS(_OTHER)?')
, ({'INCLUDE_DIRECTORIES', 'LIBRARIES'}, '(INCLUDE_DIRECTO|LIBRA)RIES')
, ({'POSTFLIGHT_&var%ref%re;_SCRIPT', 'PREFLIGHT_&var%ref%re;_SCRIPT'}, 'P(RE|OST)FLIGHT_&var%ref%re;_SCRIPT')
, ({'DIRECTORIES', 'FRAMEWORK_DIRECTORIES'}, '(FRAMEWORK_)?DIRECTORIES')
, ({'FILE_FLAG', 'FILE'}, 'FILE(_FLAG)?')
, ({'DIR_PERMISSIONS', 'FILE_PERMISSIONS'}, '(DIR|FILE)_PERMISSIONS')
, ({'COMPILER_LAUNCHER', 'LINKER_LAUNCHER'}, '(COMPIL|LINK)ER_LAUNCHER')
, ({'COMPILER', 'COMPILE_(DEFINI|OP)TIONS'}, 'COMPILE(R|_(DEFINI|OP)TIONS)')
, ({'LICENSEURL', 'LICENSE_(EXPRESSION|FILE_NAME)'}, 'LICENSE(URL|_(EXPRESSION|FILE_NAME))')
, ({'NO_SONAME', 'SONAME'}, '(NO_)?SONAME')
, ({'CODE_SIGN_ON_COPY', 'REMOVE_HEADERS_ON_COPY'}, '(CODE_SIGN|REMOVE_HEADERS)_ON_COPY')
, ({'(REFERENCE|REFERENCEPROP_&var%ref%re;_TAG)_&var%ref%re;'}, 'REFERENCE(PROP_&var%ref%re;_TAG)?_&var%ref%re;')
, ({'DISABLE_FIND_PACKAGE', 'REQUIRE_FIND_PACKAGE'}, '(DISABLE|REQUIRE)_FIND_PACKAGE')
, (
{'GROUP_USING_&var%ref%re;(_SUPPORTED)?', 'LIBRARY_USING_&var%ref%re;(_SUPPORTED)?'}
, '(GROUP|LIBRARY)_USING_&var%ref%re;(_SUPPORTED)?'
)
, (
{
'EXE_LINKER_FLAGS_&var%ref%re;(_INIT)?'
, 'MODULE_LINKER_FLAGS_&var%ref%re;(_INIT)?'
, 'SHARED_LINKER_FLAGS_&var%ref%re;(_INIT)?'
, 'STATIC_LINKER_FLAGS_&var%ref%re;(_INIT)?'
}
, '(EXE|MODULE|SHARED|STATIC)_LINKER_FLAGS_&var%ref%re;(_INIT)?'
)
, (
{
'ARCHIVE_OUTPUT_DIRECTORY'
, 'COMPILE_PDB_OUTPUT_DIRECTORY'
, 'LIBRARY_OUTPUT_DIRECTORY'
, 'PDB_OUTPUT_DIRECTORY'
, 'RUNTIME_OUTPUT_DIRECTORY'
}
, '(ARCHIVE|(COMPILE_)?PDB|LIBRARY|RUNTIME)_OUTPUT_DIRECTORY'
)
, (
{
'ARCHIVE_OUTPUT_(DIRECTORY|NAME)'
, 'LIBRARY_OUTPUT_(DIRECTORY|NAME)'
, 'RUNTIME_OUTPUT_(DIRECTORY|NAME)'
}
, '(ARCHIVE|LIBRARY|RUNTIME)_OUTPUT_(DIRECTORY|NAME)'
)
, ({'ASM&var_ref_re;', 'ASM&var_ref_re;FLAGS'}, 'ASM&var_ref_re;(FLAGS)?')
, (
{
'CMAKE_POLICY_DEFAULT_CMP[0-9]{4}'
, 'CMAKE_POLICY_WARNING_CMP[0-9]{4}'
}
, 'CMAKE_POLICY_(DEFAULT|WARNING)_CMP[0-9]{4}'
)
, ({'CMAKE_ARGV[0-9]+', 'CMAKE_MATCH_[0-9]+'}, 'CMAKE_(ARGV|MATCH_)[0-9]+')
]
@dataclass
class RePartNode:
children: dict[str, RePartNode] = field(default_factory=dict, hash=False)
is_leaf: bool = False
def try_transform_placeholder_string_to_regex(name):
@dataclass
class RegexCollection:
special_cases: list[str] = field(default_factory=list, hash=False)
re_tree: dict[str, RePartNode] = field(default_factory=dict, hash=False)
def add_case(self, regex: str) -> RegexCollection:
self.special_cases.append(regex)
return self
def update_tree(self, name_parts: list[str]) -> RegexCollection:
safe_var_ref = _VAR_REF_ENTITY.replace('_', '%')
current = functools.reduce(
lambda current, part: (
self.re_tree if current is None else current.children
).setdefault(part, RePartNode())
, safe_var_ref.join(name_parts).replace(f'{safe_var_ref}_{safe_var_ref}', safe_var_ref).split('_')
, None
)
current.is_leaf = True
return self
def try_transform_placeholder_string_to_regex(state: RegexCollection, name: str):
'''
NOTE Some placeholders are not IDs, but numbers...
`CMAKE_MATCH_<N>` 4 example
'''
m = _TEMPLATED_NAME.split(name)
if 'CMAKE_MATCH_' in m:
return 'CMAKE_MATCH_[0-9]+'
name_parts = _TEMPLATED_NAME.split(name)
match name_parts:
case ['CMAKE_MATCH_' as head, ''] | ['CMAKE_ARGV' as head, ''] | ['ARGV' as head, '']:
return state.add_case(head + '[0-9]+')
if 'CMAKE_ARGV' in m:
return 'CMAKE_ARGV[0-9]+'
case ['CMAKE_POLICY_DEFAULT_CMP' as head, ''] | ['CMAKE_POLICY_WARNING_CMP' as head, '']:
return state.add_case(head + '[0-9]{4}')
if 'CMAKE_POLICY_DEFAULT_CMP' in m:
return 'CMAKE_POLICY_DEFAULT_CMP[0-9]{4}'
case ['', '__TRYRUN_OUTPUT']:
return state.add_case(f'{_VAR_REF_ENTITY}__TRYRUN_OUTPUT')
if 'CMAKE_POLICY_WARNING_CMP' in m:
return 'CMAKE_POLICY_WARNING_CMP[0-9]{4}'
case (['ASM', ''] | ['ASM', 'FLAGS']) as asm_env:
return state.add_case(f'{asm_env[0]}{_VAR_REF_ENTITY}{asm_env[1]}')
if 'ARGV' in m:
return 'ARGV[0-9]+'
return state.update_tree(name_parts)
return '&var_ref_re;'.join(m) if 1 < len(m) else name
def is_first_subset_of_second(first, second):
subset = set(first)
fullset = set(second)
return subset.issubset(fullset)
def try_optimize_known_alt_groups(groups: list[str]) -> list[str]:
for case in _HEURISTICS:
if is_first_subset_of_second(case[0], groups):
groups = sorted([*filter(lambda item: item not in case[0], groups), case[1]])
return groups
def try_optimize_trailing_var_ref_regex(groups: list[str]) -> list[str]:
tail_var_ref_re = '_' + _VAR_REF_ENTITY.replace('_', '%')
candidates = [*filter(lambda s: s.endswith(tail_var_ref_re), groups)]
return sorted([
*filter(lambda item: item not in candidates, groups)
, f'({"|".join(try_optimize_known_alt_groups([s[:-len(tail_var_ref_re)] for s in candidates]))}){tail_var_ref_re}'
]) if len(candidates) > 1 else groups
def build_regex(state: list[str], kv: tuple[str, RePartNode]) -> list[str]:
name, value = kv
match (value, len(value.children)):
case (RePartNode(children={}, is_leaf=True), 0):
return [*state, name]
case (node, sz) if sz > 0:
alt_group = try_optimize_known_alt_groups(
try_optimize_trailing_var_ref_regex(
functools.reduce(build_regex, node.children.items(), [])
)
)
match (len(alt_group), node.is_leaf):
case (1, False):
return [*state, f'{name}_{alt_group[0]}']
case (1, True):
return [*state, f'{name}(_{alt_group[0]})?']
case (sz, False) if sz > 0:
return [*state, f'{name}_({"|".join(alt_group)})']
case (sz, True) if sz > 0:
return [*state, f'{name}(_({"|".join(alt_group)}))?']
case _:
raise AssertionError('Zero children?')
case _:
raise AssertionError(f'NOT MATCHED: {name=}{value=}')
return state
def try_placeholders_to_regex(names):
if not names:
return None
l = map(try_transform_placeholder_string_to_regex, names)
l = sorted(l, reverse=True)
return '\\b(?:' + '|'.join(l) + ')\\b'
data = functools.reduce(
try_transform_placeholder_string_to_regex
, names
, RegexCollection()
)
return (
'\\b(?:'
+ '|'.join(
try_optimize_known_alt_groups(
try_optimize_trailing_var_ref_regex(
functools.reduce(
build_regex
, data.re_tree.items()
, data.special_cases
)
)
)
).replace('%', '_')
+ ')\\b'
)
def partition_iterable(fn, iterable):
@@ -287,7 +480,8 @@ def cli(input_yaml, template):
del data['standard-module-commands']
# Fix node names to be accessible from Jinja template
data['generator_expressions'] = data['generator-expressions']
data['generator_expressions'] = (ex for ex in data['generator-expressions'] if isinstance(ex, str))
data['complex_generator_expressions'] = [ex for ex in data['generator-expressions'] if not isinstance(ex, str)]
data['deprecated_or_internal_variables'] = data['deprecated-or-internal-variables']
data['environment_variables'] = data['environment-variables']
del data['generator-expressions']

View File

@@ -0,0 +1,143 @@
#!/usr/bin/perl
# This perl script read stdin and write on stdout. It shall be an XML language file.
#
# * If the name of the language is 'HTML', then it creates the language 'PHP (HTML)'
# which shall be used for PHP hl.
#
# * If the name of the language is something else (say '*'), it creates the language '*/PHP'.
# This new language is the same as the old one, but is able to detect PHP everywhere.
#
# This script will correctly set extensions & mimetype, and will replace
# <IncludeRules context="##*"> by <IncludeRules context="##*/PHP">
#
# Generated languages need a language named 'PHP/PHP', which shall take care of PHP hl itself
# and which will be called every time something like <?php is encountred.
#
# This script also supports Twig and does the same as for PHP.
#
# SPDX-FileCopyrightText: Jan Villat <jan.villat@net2000.ch>
# License: LGPL
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]': $!";
my $language = $ARGV[1];
if ($language =~ /-php\.xml$/)
{
$language = "PHP";
}
else
{
$language = "Twig";
}
while (<$input>)
{
$file .= $_;
}
$warning = "\n\n<!-- ***** THIS FILE WAS GENERATED BY A SCRIPT - DO NOT EDIT ***** -->\n";
$file =~ s/(?=<language)/$warning\n\n\n/;
$file =~ /<language.*?name="([^"]+)"/;
my $syntaxName = $1;
if ($syntaxName eq "HTML")
{
$root = 1;
}
if ($language eq "Twig")
{
$file =~ s/<language([^>]+)priority="[^"]*"/<language$1/s;
}
if ($root == 1)
{
$file =~ s/<language([^>]+)name="[^"]*"/<language$1name="$language (HTML)"/s;
$file =~ s/<language([^>]+)section="[^"]*"/<language$1section="Scripts"/s;
if ($language eq "PHP")
{
$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;
}
# Twig
else
{
$file =~ s/<language([^>]+)extensions="[^"]*"/<language$1extensions="*.twig;*.html.twig;*.htm.twig"/s;
$file =~ s/<language([^>]+)mimetype="[^"]*"/<language$1mimetype="text\/x-twig"/s;
}
}
else
{
$file =~ s/<language([^>]+)hidden="[^"]*"/<language$1/s;
$file =~ s/<language([^>]+)section="[^"]*"/<language$1section="Other"/s;
my $extra = " hidden=\"true\"";
my $mimetype = "";
my $extensions = "";
if ($language eq "Twig")
{
$mimetype = "text/x-twig";
if ($syntaxName eq "JavaScript")
{
$extra = " priority=\"1\"";
$extensions = "*.js.twig;*.mjs.twig;*.cjs.twig";
}
elsif ($syntaxName eq "TypeScript")
{
$extra = " priority=\"1\"";
$extensions = "*.ts.twig;*.mts.twig;*.cts.twig";
}
}
$file =~ s/<language([^>]+)mimetype="[^"]*"/<language$1mimetype="$mimetype"/s;
$file =~ s/<language([^>]+)name="([^"]*)"/<language$1name="$2\/$language"$extra/s;
$file =~ s/<language([^>]+)extensions="[^"]*"/<language$1extensions="$extensions"/s;
}
# replace list with a include
$file =~ s/<list name="([^"]+)">.*?<\/list>/<list name="$1"><include>$1##$syntaxName<\/include><\/list>/gs;
$file =~ s/<language([^>]+)kateversion="[^"]*"/<language$1kateversion="5.79"/s;
$file =~ s/ fallthrough="(true|1)"//gs;
if ($language eq "Twig")
{
# remove Mustache syntax
if ($root == 1)
{
$file =~ s/<context name="MustacheJS.*?<\/context>//gs;
$file =~ s/<StringDetect attribute="Value" context="#pop#pop!MustacheJS" String="[^"]+[^\/]+\/>//gs;
}
}
elsif ($root == 1 || $ARGV[0] =~ /mustache.xml$/)
{
$file =~ s/<(?:RegExpr (attribute="Processing Instruction" context="PI"|context="PI" attribute="Processing Instruction")|itemData name="Processing Instruction")[^\/]+\/>|<context name="PI".*?<\/context>//gs;
}
my $find_language = "##$language/$language";
my $language_suffix = "/$language";
if ($language eq "PHP")
{
$find_language = "FindPHP";
}
$file =~ s/<IncludeRules\s([^>]*)context="([^"#]*)##(?!Alerts|Comments|Doxygen|Modelines)([^"]+)"/<IncludeRules $1context="$2##$3$language_suffix"/g;
$file =~ s/(<context\s[^>]*[^>\/]>)/$1\n<IncludeRules context="$find_language" \/>/g;
$file =~ s/(<context\s[^>]*[^>\/])\s*\/>/$1>\n<IncludeRules context="$find_language" \/>\n<\/context>/g;
if ($language eq "PHP")
{
$findphp = "<context name=\"FindPHP\" attribute=\"Normal Text\" lineEndContext=\"#stay\">\n<Detect2Chars context=\"##PHP/PHP\" char=\"&lt;\" char1=\"?\" lookAhead=\"true\" />\n</context>\n";
$file =~ s/(?=<\/contexts\s*>)/$findphp/;
}
print $output $file;
print $output $warning;

View File

@@ -0,0 +1,55 @@
#!/usr/bin/env ruby
#
# Generates the keyword lists for directives and variables used in nginx and
# prints them to stdout, ready to be copy & pasted into nginx.xml.
#
# SPDX-FileCopyrightText: 2023 Georg Gadinger <nilsding@nilsding.org>
# SPDX-License-Identifier: MIT
#
# Usage:
# % ./generate-nginx-lists.rb
#
# if you want to install the required dependencies provide `INSTALL_GEMS` in
# your ENV:
# % INSTALL_GEMS=1 ./generate-nginx-lists.rb
require "bundler/inline"
gemfile(ENV["INSTALL_GEMS"]) do
source "https://rubygems.org"
gem "nokogiri", "~> 1.14"
gem "faraday", "~> 2.7"
gem "builder", "~> 3.2"
end
def fetch_vars(url)
Faraday.get(url)
.then { Nokogiri::HTML.parse _1.body }
.css("div#content a[href]")
.map(&:text)
.reject { _1.end_with?("_") } # some vars are just a prefix, ignore those
.sort
.uniq
end
def build_xml_list(name, url: nil, items: [])
builder = Builder::XmlMarkup.new(indent: 2)
builder.comment! "see #{url} for a full list of #{name}"
builder.list(name:) do |b|
items.each do |item|
b.item item
end
end
end
{
directives: "https://nginx.org/en/docs/dirindex.html",
variables: "https://nginx.org/en/docs/varindex.html",
}.each do |name, url|
items = fetch_vars(url)
puts build_xml_list(name, url:, items:).gsub(/^/, ' ' * 4)
puts
end

View File

@@ -1,78 +0,0 @@
#!/usr/bin/perl
# This perl script read stdin and write on stdout. It shall be an XML language file.
#
# * If the name of the language is 'HTML', then it creates the language 'PHP (HTML)'
# which shall be used for PHP hl.
#
# * If the name of the language is something else (say '*'), it creates the language '*/PHP'.
# This new language is the same as the old one, but is able to detect PHP everywhere.
#
# This script will correctly set extensions & mimetype, and will replace
# <IncludeRules context="##*"> by <IncludeRules context="##*/PHP">
#
# Generated languages need a language named 'PHP/PHP', which shall take care of PHP hl itself
# and which will be called every time something like <?php is encountred.
#
# SPDX-FileCopyrightText: Jan Villat <jan.villat@net2000.ch>
# License: LGPL
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";
$file =~ s/(?=<language)/$warning\n\n\n/;
if ($file =~ /<language[^>]+name="HTML"/)
{
$root = 1;
}
if ($root == 1)
{
$file =~ s/<language([^>]+)name="[^"]*"/<language$1name="PHP (HTML)"/s;
$file =~ s/<language([^>]+)section="[^"]*"/<language$1section="Scripts"/s;
$file =~ s/<language([^>]+)extensions="[^"]*"/<language$1extensions="*.php;*.php3;*.wml;*.phtml;*.phtm;*.inc;*.ctp"/s;
$file =~ s/<language([^>]+)mimetype="[^"]*"/<language$1mimetype="text\/x-php4-src;text\/x-php3-src;text\/vnd.wap.wml;application\/x-php"/s;
$file =~ s/<language([^>]+)*/<language$1 indenter="cstyle"/s;
}
else
{
if ($file =~ /<language[^>]+hidden="[^"]*"/) {
$file =~ s/<language([^>]+)name="([^"]*)"/<language$1name="$2\/PHP"/s;
$file =~ s/<language([^>]+)hidden="[^"]*"/<language$1hidden="true"/s;
}
else
{
$file =~ s/<language([^>]+)name="([^"]*)"/<language$1name="$2\/PHP" hidden="true"/s;
}
$file =~ s/<language([^>]+)section="[^"]*"/<language$1section="Other"/s;
$file =~ s/<language([^>]+)extensions="[^"]*"/<language$1extensions=""/s;
$file =~ s/<language([^>]+)mimetype="[^"]*"/<language$1mimetype=""/s;
}
if ($root == 1 || $ARGV[0] =~ /mustache.xml$/)
{
$file =~ s/<(?:RegExpr (attribute="Processing Instruction" context="PI"|context="PI" attribute="Processing Instruction")|itemData name="Processing Instruction")[^\/]+\/>|<context name="PI".*?<\/context>//gs;
}
$findphp = "<context name=\"FindPHP\" attribute=\"Normal Text\" lineEndContext=\"#stay\">\n<Detect2Chars context=\"##PHP/PHP\" char=\"&lt;\" char1=\"?\" lookAhead=\"true\" />\n</context>\n";
$file =~ s/<IncludeRules\s([^>]*)context="([^"#]*)##(?!Alerts|Comments|Doxygen|Modelines)([^"]+)"/<IncludeRules $1context="$2##$3\/PHP"/g;
$file =~ s/(<context\s[^>]*[^>\/]>)/$1\n<IncludeRules context="FindPHP" \/>/g;
$file =~ s/(<context\s[^>]*[^>\/])\s*\/>/$1>\n<IncludeRules context="FindPHP" \/>\n<\/context>/g;
$file =~ s/(?=<\/contexts\s*>)/$findphp/;
print $output $file;
print $output $warning;

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
<!DOCTYPE language>
<!-- ***** THIS FILE WAS GENERATED BY A SCRIPT - DO NOT EDIT *****
cd data/generators
# increase version of spdx-comments.xml.tpl then

View File

@@ -0,0 +1,498 @@
#!/usr/bin/env python3
# SPDX-FileCopyrightText: 2023 Jonathan Poelen <jonathan.poelen@gmail.com>
# SPDX-License-Identifier: MIT
from pathlib import Path
from collections import defaultdict
from typing import TextIO
import re
import sys
exclude_line = {
' - non-standard\n',
' - experimental\n',
' - deprecated\n',
'page-type: css-combinator\n',
'page-type: css-selector\n',
'page-type: css-module\n',
'page-type: landing-page\n',
'page-type: guide\n',
}
page_type_accepted = {
'page-type: css-type\n',
'page-type: css-function\n',
'page-type: css-property\n',
'page-type: css-keyword\n',
'page-type: css-shorthand-property\n',
'page-type: css-pseudo-element\n',
'page-type: css-pseudo-class\n',
'page-type: css-at-rule-descriptor\n',
'page-type: css-at-rule\n',
'page-type: css-media-feature\n',
'page-type: svg-attribute\n',
}
exclude_title = {
'<alpha-value>',
'<angle>',
'<angle-percentage>',
'<basic-shape>',
'<calc-constant>',
'<calc-sum>',
'<color-interpolation-method>',
'<color>',
'<custom-ident>',
'<dashed-ident>',
'<display-listitem>',
'<display-inside>',
'<dimension>',
'<easing-function>'
'<filter-function>',
'<flex>',
'<frequency-percentage>',
'<frequency>',
'<gradient>',
'<hex-color>',
'<hue>',
'<hue-interpolation-method>',
'<ident>',
'<image>',
'<integer>',
'<length>',
'<length-percentage>',
'<number>',
'<percentage>',
'<position>',
'<ratio>',
'<resolution>',
'<string>',
'<time-percentage>',
'<time>',
'<transform-function>',
'"!important"',
}
properties_ignore_value = (
'counter-increment',
'counter-reset',
'counter-set',
'text-rendering',
'page',
)
units: list[str] = []
colors: set[str] = set()
system_colors: set[str] = set()
deprecated_system_colors: set[str] = set()
values: set[str] = set()
properties: set[str] = set()
svg_values: set[str] = set()
svg_properties: set[str] = set()
functions: set[str] = set()
pseudo_classes: set[str] = set()
pseudo_elements: set[str] = set()
experimental_pseudo_classes: set[str] = set()
experimental_pseudo_elements: set[str] = set()
at_rules: set[str] = set()
media_features: set[str] = set()
media_feature_values: set[str] = set()
_update_version_extractor = re.compile(r' version="(\d+)" ')
def update_version(s: str) -> str:
return _update_version_extractor.sub(lambda m: f' version="{int(m[1])+1}" ', s, count=1)
_md_value_extractor = re.compile(r'(?<=[^\w][ /])`([-\w][-\w\d]+(?:<[^>]+>[?+*])?)`')
_html_value_extractor = re.compile(r'<code>([-\w][-\w\d]+)</code>')
_is_md_value = re.compile(r'^\s*- `')
_is_html_table_desc = re.compile(r'^\s+<td><code>')
def css_parse_values(f: TextIO, prop: str, values: set[str]) -> None:
line:str = ''
# Format:
# ## Syntax or ### Syntax
#
# ```css
# (optional)
# ```
# ## Values or ### Values or not...
#
# - `ident` or html table <td><code>....</code></td>
#
# ## SVG only ... (optional)
# ## other title
for line in f:
if line.endswith('## Syntax\n') or line.endswith('## Values\n') or '## SVG only' in line:
for line in f:
if _is_md_value.match(line):
if 'deprecated' not in line:
values.update(_md_value_extractor.findall(line))
elif line.startswith('#'):
if not (line.endswith('## Values\n') or '## SVG only' in line
or (prop == 'display'
and (line.endswith('## Grouped values\n')
or line.endswith('## Outside\n')
or line.endswith('## Inside\n')
or line.endswith('## List Item\n')
or line.endswith('## Internal\n')
or line.endswith('## Box\n')
or line.endswith('## Precomposed\n')
))
):
return
elif line == '```css\n':
for line in f:
if line.startswith('```\n'):
break
elif _is_html_table_desc.match(line):
values.update(_html_value_extractor.findall(line))
def css_parse_named_colors(f: TextIO) -> set[str]:
return set(re.findall('\n <td>(?:\n )?<code>([a-z]+)</code>', f.read()))
def css_parse_units(f: TextIO) -> list[str]:
return re.findall(r'`([^`]+)`', ''.join(re.findall(r'\n\| (`[^|]+)', f.read())))
_svg_values_extractor = re.compile(r'<th scope="row">Value</th>\n\s*<td>(.*?)</td>', re.DOTALL)
_svg_value_extractor = re.compile(r'<code>([-\w\d]+)</code>')
def css_parse_svg_attribute(f: TextIO, prop: str, properties: set[str], values: set[str]) -> None:
contents = f.read()
if 'can be used as a CSS property' in contents:
properties.add(prop)
m = _svg_values_extractor.search(contents)
if m:
values.update(_svg_value_extractor.findall(m[1]))
_experimental_selector_extractor = re.compile(r'\n- {{CSSxRef([^}]+)}} {{Experimental_Inline}}')
_selector_extractor = re.compile(r'":+([-\w\d]+)[()]*"')
def css_parse_pseudo_classes_or_elements(f: TextIO) -> tuple[
set[str], # experimental
list[str]
]:
s = f.read()
experimental_str = ''.join(_experimental_selector_extractor.findall(s))
return (set(_selector_extractor.findall(experimental_str)), _selector_extractor.findall(s))
if len(sys.argv) < 5:
print(f'''{Path(sys.argv[0]).name} content-main-directory syntax/css.xml sass-site-directory syntax/scss.xml
content-main-directory is https://github.com/mdn/content/ (https://github.com/mdn/content/archive/refs/heads/main.zip)
sass-site-directory is https://github.com/sass/sass-site/tree/main (https://github.com/sass/sass-site/archive/refs/heads/main.zip)
''', file=sys.stderr)
exit(1)
css_dir = Path(sys.argv[1])
css_filename = Path(sys.argv[2])
scss_dir = Path(sys.argv[3])
scss_filename = Path(sys.argv[4])
tmp_pseudo_classes = (set(), ())
tmp_pseudo_elements = (set(), ())
for pattern in (
'files/en-us/web/svg/attribute/**/',
'files/en-us/web/css/**/',
):
for md in css_dir.glob(pattern):
with open(md/'index.md', encoding='utf8') as f:
if f.readline() != '---\n':
continue
title = f.readline()[7:-1]
if title in exclude_title:
continue
if title.startswith('"'):
title = title[1:-1]
page_type = ''
for line in f:
if line in exclude_line:
page_type = ''
break
if line.startswith('page-type: '):
if line not in page_type_accepted:
raise Exception(f'Unknown {line[:-1]}')
page_type = line[11:-1]
if line == '---\n':
break
if page_type == 'css-property' or page_type == 'css-at-rule-descriptor':
properties.add(title)
if not title.endswith('-name') and title not in properties_ignore_value:
css_parse_values(f, title, values)
elif page_type == 'css-shorthand-property':
properties.add(title)
elif page_type == 'css-pseudo-class':
pseudo_classes.add(title[1:].removesuffix('()'))
elif page_type == 'css-pseudo-element':
pseudo_elements.add(title[2:].removesuffix('()'))
elif page_type == 'css-type':
if title == '<named-color>':
colors = css_parse_named_colors(f)
if title == '<system-color>':
css_parse_values(f, '', system_colors)
deprecated_system_colors = set(re.findall('\n- `([^`]+)` {{deprecated_inline}}', f.read()))
else:
css_parse_values(f, '', values)
elif page_type == 'css-function':
functions.add(title[:-2])
elif page_type == 'css-at-rule':
at_rules.add(title)
elif page_type == 'css-media-feature':
media_features.add(title)
css_parse_values(f, title, media_feature_values)
elif page_type == 'css-keyword':
values.add(title)
elif title == 'CSS values and units':
units = css_parse_units(f)
elif title == 'Pseudo-classes':
tmp_pseudo_classes = css_parse_pseudo_classes_or_elements(f)
elif title == 'Pseudo-elements':
tmp_pseudo_elements = css_parse_pseudo_classes_or_elements(f)
elif page_type == 'svg-attribute':
css_parse_svg_attribute(f, title, svg_properties, svg_values)
elif title == 'CSS value functions':
functions.update(re.findall(r'\n- {{CSSxRef\("[^"]+", "([-\w\d]+)\(\)"\)}}\n', f.read()))
experimental_pseudo_classes = tmp_pseudo_classes[0]
experimental_pseudo_classes -= pseudo_classes
pseudo_classes.update(tmp_pseudo_classes[1])
experimental_pseudo_elements = tmp_pseudo_elements[0]
experimental_pseudo_elements -= pseudo_elements
pseudo_elements.update(tmp_pseudo_elements[1])
global_values = {
'auto',
'inherit',
'initial',
'revert',
'revert-layer',
'unset',
}
values -= global_values
svg_values -= global_values
pseudo_classes -= experimental_pseudo_classes
pseudo_elements -= experimental_pseudo_elements
# add values of functions
values.update((
# repeat()
'auto-fill',
'auto-fit',
))
# move some keyword colors in values
for special_color in ('transparent', 'currentcolor'):
values.add(special_color)
colors.discard(special_color)
# fix not specified value in mdn file
if 'user-invalid' in experimental_pseudo_classes:
pseudo_classes.discard('user-valid')
experimental_pseudo_classes.add('user-valid')
media_features.update((
'min-width',
'max-width',
'min-height',
'max-height',
))
# fix errors in mdn file
for e in ('has', 'host-context'):
pseudo_classes.add(e)
experimental_pseudo_classes.discard(e)
# @font-format functions
functions.update((
'format',
'local',
'tech',
))
# def show(name, values):
# print(f'{name} ({len(values)}):')
# print('\n'.join(sorted(values)), end='\n\n')
#
# show('properties', properties)
# show('svg properties', svg_properties)
# show('values', values)
# show('svg values', svg_values)
# show('global values', global_values)
# show('functions', functions)
# show('pseudo-classes', pseudo_classes)
# show('pseudo-elements', pseudo_elements)
# show('experimental pseudo-classes', experimental_pseudo_classes)
# show('experimental pseudo-elements', experimental_pseudo_elements)
# show('at-rules', at_rules)
# show('media-features', media_features)
# show('media-features values', media_feature_values)
# show('colors', colors)
# show('system colors', system_colors)
# show('deprecated system colors', deprecated_system_colors)
# show('units', units)
# print('units reg:', '|'.join(units))
#
# Update CSS
#
sep = '\n '
css_replacements = {
prop: f'</item>{sep}<item>'.join(sorted(seq))
for prop, seq in (
('properties', properties),
('values', values),
('value keywords', global_values),
('functions', functions),
('pseudo-classes', pseudo_classes),
('pseudo-elements', pseudo_elements),
('media features', media_features)
)
}
for prop, seq in (('properties', svg_properties - properties), ('values', svg_values - values)):
if seq:
items = f'</item>{sep}<item>'.join(sorted(seq))
css_replacements[prop] += f'</item>\n{sep}<!-- SVG only -->\n{sep}<item>{items}'
rep1 = f'</item>{sep}<item>'.join(sorted(colors))
rep2 = f'</item>{sep}<item>'.join(sorted(system_colors))
css_replacements['colors'] = f'{rep1}</item>{sep}{sep}<!-- System colors -->{sep}<item>{rep2}'
item_extractor = re.compile('<item>([^-<][^<]*)')
current_at_rules = set()
def _css_update_and_extract_items(m) -> str:
seq = css_replacements.get(m[1])
if seq:
end = ' ' if m[3] == '</list>' else sep
return f'<list name="{m[1]}">{sep}<item>{seq}</item>\n{end}{m[3]}'
current_at_rules.update(item_extractor.findall(m[2]))
return m[0]
css_content = css_filename.read_text()
original_css_content = css_content
names = f"{'|'.join(css_replacements)}|at-rules(?: definitions)?"
css_content = re.sub(rf'<list name="({names})">(.*?)(</list>|<!-- manual list -->)',
_css_update_and_extract_items, css_content, flags=re.DOTALL)
_regexpr_unit_prefix = r'(<RegExpr attribute="Unit".*?String="\(%\|\()'
regexpr_unit_extractor = re.compile(fr'{_regexpr_unit_prefix}([^)]+)')
css_content = regexpr_unit_extractor.sub('\\1' + "|".join(units), css_content, 1)
if original_css_content != css_content:
css_content = update_version(css_content)
css_filename.write_text(css_content)
def show_at_rule_difference(language: str, old_at_rules: set[str], new_at_rules: set[str]) -> None:
at_rule_added = new_at_rules - old_at_rules
at_rule_removed = old_at_rules - new_at_rules
nl = '\n '
if at_rule_added or at_rule_removed:
print(f"""\x1b[31m{language} At-rules requires a manual update
New ({len(at_rule_added)}):\x1b[0m
{nl.join(at_rule_added)}
\x1b[31mRemoved ({len(at_rule_removed)}):\x1b[0m
{nl.join(at_rule_removed)}""")
show_at_rule_difference('CSS', current_at_rules, at_rules)
#
# Extract SCSS data
#
scss_functions:list[str] = []
scss_at_rules:set[str] = {'@content', '@return'}
_function_list_extractor = re.compile(r'{% function (.*?) %}')
_function_extractor = re.compile(r"'([-._a-zA-Z0-9]+)\(")
_at_rule_extractor = re.compile(r'@[-a-z0-9]+')
for md in sorted(scss_dir.glob('source/documentation/modules/**/*.md')):
func_list = _function_list_extractor.findall(md.read_text())
func_items = set(_function_extractor.findall(''.join(func_list)))
scss_functions.append(f'\n{sep}<!-- {md.stem} -->')
scss_functions.extend(f'{sep}<item>{func}</item>' for func in sorted(func_items - functions))
for md in scss_dir.glob('source/documentation/at-rules/**/*.md'):
with open(md) as f:
f.readline()
scss_at_rules.update(_at_rule_extractor.findall(f.readline()))
subproperties = set(
'-'.join(splitted[i:n])
for prop in properties
for splitted in (prop.rsplit('-', prop.count('-') - 1) # '-aaa-bbb' -> ['-aaa', 'bbb']
if prop.startswith('-')
else prop.split('-'), ) # 'aaa-bbb' -> ['aaa', 'bbb']
for i in range(len(splitted))
for n in range(i+1, len(splitted)+1)
)
#
# Update SCSS
#
scss_current_at_rules = set()
def _scss_update_and_extract_items(m) -> str:
name = m[1]
if name == 'functions':
return f"""<list name="functions">
<include>functions##CSS</include>
<!-- https://sass-lang.com/documentation/modules/ -->{f''.join(scss_functions)}
</list>"""
if name == 'at-rules':
scss_current_at_rules.update(_at_rule_extractor.findall(m[2]))
return m[0]
# sub-properties
items = f'</item>{sep}<item>'.join(sorted(subproperties - properties))
return f'<list name="{name}">{sep}<item>{items}</item>\n </list>'
scss_content = scss_filename.read_text()
original_scss_content = scss_content
scss_content = re.sub(r'<list name="(sub-properties|functions|at-rules)">(.*?)</list>',
_scss_update_and_extract_items, scss_content, count=3, flags=re.DOTALL)
scss_content = re.sub(r'<!ENTITY pseudoclasses "[^"]*">',
f'<!ENTITY pseudoclasses "{"|".join(sorted(pseudo_classes))}">',
scss_content, count=1)
scss_content = regexpr_unit_extractor.sub('\\1' + "|".join(units), scss_content, 1)
if original_scss_content != scss_content:
scss_content = update_version(scss_content)
scss_filename.write_text(scss_content)
show_at_rule_difference('SCSS', scss_current_at_rules, scss_at_rules)

View File

@@ -0,0 +1,45 @@
#!/usr/bin/env python3
# SPDX-FileCopyrightText: 2023 Jonathan Poelen <jonathan.poelen@gmail.com>
# SPDX-License-Identifier: MIT
from pathlib import Path
from urllib import request
import re
import sys
if len(sys.argv) < 1:
print(f'{sys.argv[0]} syntax/less.xml', file=sys.stderr)
exit(1)
#
# Extract functions
#
data = request.urlopen('https://lesscss.org/functions/').read().decode()
functions = re.findall(r'</a>([-_\w\d]+)</h3>', data, flags=re.DOTALL)
functions.append('%')
#
# Update syntax
#
sep = '\n '
new_list = f"""<list name="functions">
<include>functions##CSS</include>
<!-- Less functions, @see http://lesscss.org/functions/ -->
<item>{f'</item>{sep}<item>'.join(sorted(functions))}</item>
</list>"""
less_filename = Path(sys.argv[1])
less_content = less_filename.read_text()
original_less_content = less_content
less_content = re.sub(r'<list name="functions">.*?</list>',
new_list, less_content, count=1, flags=re.DOTALL)
if original_less_content != less_content:
less_content = re.sub(' version="(\d+)" ', lambda m: f' version="{int(m[1])+1}" ',
less_content, count=1)
less_filename.write_text(less_content)

View File

@@ -6,39 +6,22 @@
SPDX-FileCopyrightText: 2005 Dominik Haumann <dhdev@gmx.de>
SPDX-FileCopyrightText: 2008 Wilbert Berendsen <info@wilbertberendsen.nl>
This file describes the XML format used for syntax highlight descriptions
for the Kate text editor (http://kate.kde.org), which is part of the KDE
desktop environment (http://www.kde.org).
You'll find the "Writing a Kate Highlighting XML File HOWTO" at
http://kate.kde.org/doc/hlhowto.php
This file describes the XML format used for syntax highlight descriptions
for the Kate text editor (https://kate-editor.org), which is part of the
KDE desktop environment (https://kde.org).
You'll find the "Working with Syntax Highlighting" at
https://docs.kde.org/stable5/en/kate/katepart/highlight.html
This format is identified using the SYSTEM identifier
SYSTEM "language.dtd"
You can validate your syntax files using "validatehl.sh yourSyntax.xml".
This needs xmllint from the libxml2 XML library.
Files using this format should include a DOCTYPE declaration like this:
<!DOCTYPE language SYSTEM "language.dtd">
You can validate your syntax files using "validatehl.sh yourSyntax.xml".
This needs xmllint from the libxml2 XML library.
In any case, the katehighlightingindexer will validate all files bundled
with KTextEditor during compile time and fail on errors.
To use your syntax file, copy it to ~/.local/share/katepart5/syntax/ in
your home directory. You have to open a new instance of kwrite/kate to use
the new syntax file.
In any case, the katehighlightingindexer will validate all files bundled
with KTextEditor during compile time and fail on errors.
TODO
- find a more readable way for the - -dtdvalid stuff, it's just annoying
xml comments don't allow it.
-->
<!--
Entity declarations
You can use '&per;' instead of '.'. This seems to be useful in <item> elements.
TODO
- Are there any more such pre-defined entities?
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<!--
Default Styles
@@ -132,19 +115,12 @@
mimetype: A list of mimetypes to decide for which documents to use this syntax description [optional]
version: Version number of this syntax description
kateversion: Kate version required for using this file
casesensitive: Whether text is matched case sensitive. [boolean, optional, default=true] FIXME: This is not implemented yet
casesensitive: Ignored but preserved to maintain compatibility in older versions of KF5.
priority: Priority of this language, if more than one are usable for the file [optional]
author: Name of author of this hl file [optional]
license: License for this hl file [optional]
indenter: Name of the Indenter to use for this highlighting mode per default, like "cstyle" [optional]
hidden: Should it be hidden in menu [boolean, optional, default=false]
TODO
- Which matches are affected by casesensitive? keyword, RegExpr, StringDetect, WordDetect...?
WARNING: due to helper scripts, the language opening tag must be on a
*single line* and *cannot* be split in multiple lines.
-->
<xs:element name="language">
<xs:complexType>
@@ -160,6 +136,7 @@
<xs:attribute name="kateversion" use="required" type="xs:decimal"/>
<xs:attribute name="style"/>
<xs:attribute name="mimetype"/>
<!-- always ignored, <keywords casesensitive> must be used -->
<xs:attribute name="casesensitive" type="xs:boolean"/>
<xs:attribute name="priority" type="xs:integer"/>
<xs:attribute name="author"/>
@@ -317,20 +294,18 @@
context specification
name: The name of this context specification. Used in '*Context' attributes [optional]
attribute: The name of the ItemData to be used for matching text
lineEndContext: Next context if end of line is encountered
lineEmptyContext: Next context if an empty line is encountered [optional]
lineEndContext: Next context if end of line is encountered [optional, default='#stay']
lineEmptyContext: Next context if an empty line is encountered [optional, default=value of lineEndContext]
fallthrough: Use a fallthrough context [optional]
deprecated since 5.62 but preserved to maintain compatibility in older versions of KF5
fallthroughContext: Fall through to this context [optional]
fallthroughContext: Fall through to this context [optional, default='#stay']
dynamic: Dynamic context [boolean, optional]
deprecated since always but preserved to maintain compatibility in older versions of KF5
noIndentationBasedFolding: Python uses indentation based folding. However, Python has parts where
it does not use indentation based folding (e.g. for """ strings). In this case
switch to an own context and set this attribute to true. Then the indentation
based folding will ignore this parts and not change folding markers. [optional]
TODO:
- Explain fallthrough.
- Make lineEndContext optional, defaults to '#stay'. Reasonable?
it does not use indentation based folding (e.g. for """ strings). In this case
switch to an own context and set this attribute to true. Then the indentation
based folding will ignore this parts and not change folding markers. [optional]
stopEmptyLineContextSwitchLoop: Do not continue the context switching if an empty line is encountered. [boolean, optional, default=false]
-->
<xs:element name="context">
<xs:complexType>
@@ -356,11 +331,11 @@
</xs:choice>
<xs:attribute name="name"/>
<xs:attribute name="attribute" use="required"/>
<xs:attribute name="lineEndContext" use="required"/>
<xs:attribute name="lineEndContext"/>
<xs:attribute name="lineEmptyContext"/>
<xs:attribute name="fallthrough">
<xs:simpleType>
<!-- alway true since 5.62 -->
<!-- always true since 5.62 -->
<xs:restriction base="xs:token">
<xs:enumeration value="1"/>
<xs:enumeration value="true"/>
@@ -368,8 +343,11 @@
</xs:simpleType>
</xs:attribute>
<xs:attribute name="fallthroughContext"/>
<!-- always ignored -->
<xs:attribute name="dynamic" type="xs:boolean"/>
<xs:attribute name="noIndentationBasedFolding" type="xs:boolean"/>
<!-- since 5.103 -->
<xs:attribute name="stopEmptyLineContextSwitchLoop" type="xs:boolean"/>
</xs:complexType>
</xs:element>
<!--
@@ -414,7 +392,7 @@
</xs:complexType>
</xs:element>
<!--
Detect a floating point number
Detect a floating point number (as the regular expression: (\b[0-9]+\.[0-9]*|\.[0-9]+)([eE][-+]?[0-9]+)?).
commonAttributes: Common attributes
weakDeliminator: Add weak deliminators [optional]
additionalDeliminator: Add deliminators [optional]
@@ -427,7 +405,7 @@
</xs:complexType>
</xs:element>
<!--
Detect an octal number
Detect an octal number (as the regular expression: \b0[0-7]+).
commonAttributes: Common attributes
weakDeliminator: Add weak deliminators [optional]
additionalDeliminator: Add deliminators [optional]
@@ -440,7 +418,7 @@
</xs:complexType>
</xs:element>
<!--
Detect a hexadecimal number
Detect a hexadecimal number (as a regular expression: \b0[xX][0-9a-fA-F]+).
commonAttributes: Common attributes
weakDeliminator: Add weak deliminators [optional]
additionalDeliminator: Add deliminators [optional]
@@ -453,11 +431,8 @@
</xs:complexType>
</xs:element>
<!--
Detect C-style character
Detect C-style character. Characters enclosed in a tick (Example: 'c') which may be a simple character or an escaped character (as a regular expression: '(\\([abefnrtv"'?\\.]|x[0-9a-fA-F]{1,2}|[0-7]{1,3})|[^'])')
commonAttributes: Common attributes
TODO
- Did I get this right?
-->
<xs:element name="HlCChar">
<xs:complexType>
@@ -504,12 +479,9 @@
</xs:complexType>
</xs:element>
<!--
Detect any group of characters
Detect one character of a set of specified characters.
commonAttributes: Common attributes
String: A string representing the characters to look for
TODO
- Description is not descriptive enough, I'm not sure what it exactly does:-(
String: The set of characters
-->
<xs:element name="AnyChar">
<xs:complexType>
@@ -523,9 +495,6 @@
String: The string to look for
insensitive: Whether the string is matched case INsensitive. [boolean, optional, default=false]
dynamic: Uses %1 .. %9 as placeholders for dynamic arguments [boolean, optional, default=false]
TODO
- What's default of insensitive? I'm not sure...
-->
<xs:element name="StringDetect">
<xs:complexType>
@@ -542,9 +511,6 @@
insensitive: Whether the string is matched case INsensitive. [boolean, optional, default=false]
weakDeliminator: Add weak deliminators [optional]
additionalDeliminator: Add deliminators [optional]
TODO
- What's default of insensitive? I'm not sure...
-->
<xs:element name="WordDetect">
<xs:complexType>
@@ -560,7 +526,7 @@
commonAttributes: Common attributes
String: The regular expression pattern
insensitive: Whether the text is matched case INsensitive. [boolean, optional, default=false]
minimal: Wheather to use minimal matching for wild cards in the pattern [boolean, optional, default='false']
minimal: Wheather to use minimal matching for wild cards in the pattern [boolean, optional, default=false]
dynamic: Uses %1 .. %9 as placeholders for dynamic arguments [boolean, optional, default=false]
-->
<xs:element name="RegExpr">
@@ -584,11 +550,8 @@
</xs:complexType>
</xs:element>
<!--
Detect a C-style escaped character
Detect a C-style escaped character (as a regular expression: \\([abefnrtv"'?\\.]|x[0-9a-fA-F]{1,2}|[0-7]{1,3})).
commonAttributes: Common attributes
TODO:
- Did I get this right? Only one character, or a string?
-->
<xs:element name="HlCStringChar">
<xs:complexType>
@@ -596,7 +559,7 @@
</xs:complexType>
</xs:element>
<!--
Detect a range of characters
Detect a string with defined start and end characters.
commonAttributes: Common attributes
char: The character starting the range
char1: The character terminating the range

View File

@@ -1,2 +1,3 @@
#!/bin/sh
xmllint --noout --schema language.xsd $@
schemadir=$(dirname "$0")
xmllint --noout --schema "$schemadir"/language.xsd "$@"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
<language version="7" kateversion="3.1" name="Alerts" section="Other" extensions="" mimetype="" author="Dominik Haumann (dhaumann@kde.org)" license="MIT" hidden="true">
<!DOCTYPE language>
<language version="8" kateversion="3.1" name="Alerts" section="Other" extensions="" mimetype="" author="Dominik Haumann (dhaumann@kde.org)" license="MIT" hidden="true">
<highlighting>
<list name="alerts_hi">
<item>ALERT</item>
@@ -36,6 +36,8 @@
<WordDetect attribute="Region Marker" context="#stay" String="END" endRegion="AlertRegion2" />
<keyword attribute="Alert Level 1" context="#stay" String="alerts_hi" />
<keyword attribute="Alert Level 2" context="#stay" String="alerts_mid" />
<!-- Some (Python?) linters use `noqa:` (small case w/ colon) -->
<WordDetect attribute="Alert Level 2" context="#stay" String="noqa:" />
<keyword attribute="Alert Level 3" context="#stay" String="alerts_lo" />
</context>
</contexts>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd"
<!DOCTYPE language
[
<!ENTITY tab "&#009;">
<!ENTITY funcname "([^&_fragpathseps;}=#$]|[+!@](?!\())([^&_fragpathseps;}=$]*+([+!@](?!\())?+)*+">
@@ -66,7 +66,7 @@
<language
name="Bash"
version="46"
version="51"
kateversion="5.79"
section="Scripts"
extensions="*.sh;*.bash;*.ebuild;*.eclass;*.exlib;*.exheres-0;.bashrc;.bash_profile;.bash_login;.profile;PKGBUILD;APKBUILD"
@@ -533,7 +533,7 @@
<contexts>
<context attribute="Normal Text" lineEndContext="#stay" name="Start" fallthroughContext="Command">
<IncludeRules context="BashOneLine"/>
<IncludeRules context="BashOneLine"/>
</context>
<!-- used by other syntaxes -->
@@ -1005,13 +1005,15 @@
<DetectChar attribute="Redirection" context="#pop!WordRedirection" char="&lt;"/>
</context>
<context attribute="Normal Text" lineEndContext="#pop" name="FdRedirection" fallthroughContext="#pop!FdRedirection2">
<DetectSpaces attribute="Normal Text" context="#pop!FdRedirection2"/>
<DetectSpaces attribute="Normal Text"/>
<DetectChar attribute="Comment" context="#pop!Comment" char="#"/>
</context>
<context attribute="Normal Text" lineEndContext="#pop" name="FdRedirection2" fallthroughContext="#pop!WordRedirection2">
<RegExpr attribute="File Descriptor" context="#pop!CloseFile" String="[0-9]+(?=-?&eoexpr;)"/>
</context>
<context attribute="Normal Text" lineEndContext="#pop" name="WordRedirection" fallthroughContext="#pop!WordRedirection2">
<DetectSpaces attribute="Normal Text" context="#pop!WordRedirection2"/>
<DetectSpaces attribute="Normal Text"/>
<DetectChar attribute="Comment" context="#pop!Comment" char="#"/>
</context>
<context attribute="Normal Text" lineEndContext="#pop" name="WordRedirection2" fallthroughContext="#pop">
<AnyChar context="#pop" String="&wordseps;`" lookAhead="1"/>
@@ -1019,7 +1021,8 @@
<RegExpr attribute="Path" context="PathThenPop" String="&path;"/>
</context>
<context attribute="Normal Text" lineEndContext="#pop" name="StringRedirection" fallthroughContext="#pop!StringRedirection2">
<DetectSpaces attribute="Normal Text" context="#pop!StringRedirection2"/>
<DetectSpaces attribute="Normal Text"/>
<DetectChar attribute="Comment" context="#pop!Comment" char="#"/>
</context>
<context attribute="Normal Text" lineEndContext="#pop" name="StringRedirection2">
<AnyChar context="#pop" String="&wordseps;`" lookAhead="1"/>
@@ -1046,8 +1049,9 @@
<Detect2Chars attribute="Redirection" context="#pop" char="&lt;" char1="&lt;"/><!-- always met -->
</context>
<context attribute="Normal Text" lineEndContext="#pop" name="HereDocRemainder" fallthroughContext="Command">
<IncludeRules context="Start"/>
<context attribute="Normal Text" lineEndContext="#pop" name="HereDocRemainder" fallthroughContext="CommandArg">
<AnyChar context="BashOneLine" String="&amp;|;`" lookAhead="1"/>
<IncludeRules context="CommandArgs"/>
</context>
<!-- Highlight the builtin `:` (true) and the followed redirection, then fall into `HereDocMLComment` -->
@@ -1073,7 +1077,7 @@
</context>
<context attribute="Here Doc" lineEndContext="#stay" name="HereDocNQ" dynamic="true" fallthroughContext="HereDocSubstitutions">
<RegExpr attribute="Redirection" context="#pop#pop" String="^%1$" dynamic="true" column="0"/>
<IncludeRules context="HereDocQ" />
</context>
<context attribute="Here Doc" lineEndContext="#stay" name="HereDocIQ" dynamic="true" fallthroughContext="HereDocText">
@@ -1081,27 +1085,32 @@
</context>
<context attribute="Here Doc" lineEndContext="#stay" name="HereDocINQ" dynamic="true" fallthroughContext="HereDocSubstitutions">
<RegExpr attribute="Redirection" context="#pop#pop" String="^\t*%1$" dynamic="true" column="0"/>
<IncludeRules context="HereDocIQ" />
</context>
<context attribute="Here Doc" lineEndContext="#stay" name="HereDocCmd">
<!-- Only if the redirect is before the command, but as this is too complicated,
check if the redirect is at the beginning of the line. -->
<StringDetect attribute="Redirection" context="BashOneLine" String="%1" dynamic="true" firstNonSpace="1"/>
<StringDetect attribute="Redirection" context="HereDocRemainder" String="%1" dynamic="true"/>
</context>
<context attribute="Here Doc" lineEndContext="#stay" name="HereDocQCmd" dynamic="true" fallthroughContext="HereDocText">
<StringDetect attribute="Redirection" context="HereDocRemainder" String="%1" dynamic="true"/>
<IncludeRules context="HereDocCmd"/>
<RegExpr attribute="Redirection" context="#pop#pop" String="^%2$" dynamic="true" column="0"/>
</context>
<context attribute="Here Doc" lineEndContext="#stay" name="HereDocNQCmd" dynamic="true" fallthroughContext="HereDocSubstitutions">
<StringDetect attribute="Redirection" context="HereDocRemainder" String="%1" dynamic="true"/>
<RegExpr attribute="Redirection" context="#pop#pop" String="^%2$" dynamic="true" column="0"/>
<IncludeRules context="HereDocQCmd"/>
</context>
<context attribute="Here Doc" lineEndContext="#stay" name="HereDocIQCmd" dynamic="true" fallthroughContext="HereDocText">
<StringDetect attribute="Redirection" context="HereDocRemainder" String="%1" dynamic="true"/>
<IncludeRules context="HereDocCmd"/>
<RegExpr attribute="Redirection" context="#pop#pop" String="^\t*%2$" dynamic="true" column="0"/>
</context>
<context attribute="Here Doc" lineEndContext="#stay" name="HereDocINQCmd" dynamic="true" fallthroughContext="HereDocSubstitutions">
<StringDetect attribute="Redirection" context="HereDocRemainder" String="%1" dynamic="true"/>
<RegExpr attribute="Redirection" context="#pop#pop" String="^\t*%2$" dynamic="true" column="0"/>
<IncludeRules context="HereDocIQCmd"/>
</context>
<context attribute="Here Doc" lineEndContext="#pop" name="HereDocText">
@@ -1262,6 +1271,7 @@
<!-- VarBraceStart is called as soon as ${ is encoutered -->
<context attribute="Variable" lineEndContext="#pop!VarBrace" name="VarBraceStart" fallthroughContext="#pop!VarBrace">
<StringDetect context="#pop!VarBrace" String="!}" lookAhead="1"/>
<DetectChar attribute="Parameter Expansion Operator" context="#pop!VarBracePrefix" char="!"/>
<DetectChar attribute="Parameter Expansion Operator" context="#pop!VarBrace" char="#"/>
</context>
@@ -1270,6 +1280,8 @@
<context attribute="Variable" lineEndContext="#pop" name="VarBracePrefix">
<DetectIdentifier attribute="Variable" context="#pop!VarBracePrefixSuffix"/>
<Int attribute="Variable" context="#pop!VarBracePrefixSuffix"/>
<AnyChar attribute="Parameter Expansion Operator" context="#pop!VarBracePrefixSharp" String="@*#"/>
<DetectChar attribute="Parameter Expansion" context="#pop" char="}"/>
</context>
<context attribute="Variable" lineEndContext="#pop" name="VarBracePrefixSuffix" fallthroughContext="#pop!VarError">
<DetectChar attribute="Parameter Expansion" context="#pop" char="}"/>
@@ -1277,6 +1289,10 @@
<StringDetect attribute="Parameter Expansion Operator" context="#stay" String="[@]"/>
<StringDetect attribute="Parameter Expansion Operator" context="#stay" String="[*]"/>
</context>
<context attribute="Variable" lineEndContext="#pop" name="VarBracePrefixSharp" fallthroughContext="#pop!VarError">
<DetectChar attribute="Parameter Expansion" context="#pop" char="}"/>
<DetectChar attribute="Parameter Expansion Operator" char="#"/>
</context>
<!-- VarBrace is called as soon as ${ or ${# are encoutered -->
<context attribute="Variable" lineEndContext="#stay" name="VarBrace" fallthroughContext="#pop!VarError">
@@ -1352,7 +1368,7 @@
<!-- called as soon as ${xxx@ is encoutered -->
<context attribute="Normal Text" lineEndContext="#stay" name="VarTransformation" fallthroughContext="#pop!VarError">
<DetectChar attribute="Parameter Expansion" context="#pop" char="}"/>
<AnyChar attribute="Parameter Expansion" context="#stay" String="QEPAa"/>
<AnyChar attribute="Parameter Expansion" context="#stay" String="UuLQEPAKa"/>
</context>
<context attribute="Escape" lineEndContext="#pop" name="BraceExpansion">

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
<!DOCTYPE language>
<language
version="1"
kateversion="5.0"

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd"
<!DOCTYPE language
[
<!ENTITY wordsep "(?:[][,?;()]|\.$|\.?\s|$)"> <!-- things that end a TagWord -->
<!ENTITY sl_word ".*?(?=&wordsep;)">
<!ENTITY ml_word ".*?(?=&wordsep;|\*/)">
]>
<language name="Doxygen"
version="14"
version="15"
kateversion="5.0"
section="Markup"
extensions="*.dox;*.doxygen"
@@ -586,7 +586,7 @@
<Detect2Chars attribute="Tags" context="#pop!LanguageId" char="@" char1="~" />
<keyword attribute="Error" context="#pop" String="TagEnd" />
<RegExpr attribute="Error" context="#pop" String="[@\\]f[]}]" />
<RegExpr attribute="Tags" context="#pop" String="[@\\](?:[#$%&amp;&lt;&gt;&quot;@\\.]|::|---?)(?=&wordsep;)" />
<RegExpr attribute="Escape sequence" context="#pop" String="[@\\](?:[#$%&amp;&lt;&gt;&quot;@\\.~=|]|::|---?)" />
<RegExpr attribute="Custom Tags" context="#pop" String="[@\\](?:[^@\\ \t\*]|\*(?!/))+" />
<AnyChar attribute="Comment" context="#pop" String="\@" />
</context>
@@ -598,6 +598,7 @@
</contexts>
<itemDatas>
<itemData name="Normal Text" defStyleNum="dsNormal" />
<itemData name="Escape sequence" defStyleNum="dsSpecialChar" />
<itemData name="Tags" defStyleNum="dsAnnotation" bold="1" />
<itemData name="Custom Tags" defStyleNum="dsAnnotation" />
<itemData name="Word" defStyleNum="dsCommentVar" bold="1" italic="0" />

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE language SYSTEM "language.dtd"[
<!DOCTYPE language[
<!ENTITY nmtoken "[\-\w\d\.:_]+">
<!ENTITY entref "(#[0-9]+|#[xX][0-9A-Fa-f]+|&nmtoken;);">
]>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
<!DOCTYPE language>
<!--
*************************************************************************

View File

@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd"
<!DOCTYPE language
[
<!ENTITY name "[A-Za-z_:][\w.:_-]*">
<!ENTITY attributeName "[A-Za-z_:*#\(\[][\)\]\w.:_-]*">
<!ENTITY entref "&amp;(?:#[0-9]+|#[xX][0-9A-Fa-f]+|&name;);">
]>
<language name="HTML" version="15" kateversion="5.53" section="Markup" extensions="*.htm;*.html;*.shtml;*.shtm;*.aspx" mimetype="text/html" author="Wilbert Berendsen (wilbert@kde.nl)" license="LGPL" priority="10">
<language name="HTML" version="18" kateversion="5.79" section="Markup" extensions="*.htm;*.html;*.shtml;*.shtm;*.aspx" mimetype="text/html" author="Wilbert Berendsen (wilbert@kde.nl)" license="LGPL" priority="10">
<highlighting>
<contexts>
@@ -18,53 +18,70 @@
<DetectIdentifier/>
<StringDetect attribute="Comment" context="Comment" String="&lt;!--" beginRegion="comment" />
<StringDetect attribute="CDATA" context="CDATA" String="&lt;![CDATA[" beginRegion="cdata" />
<RegExpr attribute="Doctype" context="Doctype" String="&lt;!DOCTYPE\s+" insensitive="true" beginRegion="doctype" />
<WordDetect attribute="Doctype" context="Doctype" String="&lt;!DOCTYPE" insensitive="true" beginRegion="doctype" />
<IncludeRules context="FindElements" />
<RegExpr attribute="Processing Instruction" context="PI" String="&lt;\?[\w:-]*" beginRegion="pi" />
<IncludeRules context="FindSpecialHTMLTags" />
<IncludeRules context="FindHTMLTags" />
<!-- as long as kde gives DTDs the text/html mimetype--><IncludeRules context="FindDTDRules" />
<IncludeRules context="FindEntityRefs" />
</context>
<context name="FindElements" attribute="Other Text" lineEndContext="#pop">
<RegExpr attribute="Element Symbols" context="ElementTagName" String="&lt;(?=(&name;))" />
<RegExpr attribute="Element Symbols" context="ElementTagNameClose" String="&lt;/(?=(&name;))" />
</context>
<context name="ElementTagName" attribute="Other Text" lineEndContext="#pop">
<IncludeRules context="FindHTMLTags" />
<IncludeRules context="FindSpecialHTMLTags" />
<StringDetect attribute="Element" context="#pop!El Open" String="%1" dynamic="true" />
</context>
<context name="ElementTagNameClose" attribute="Other Text" lineEndContext="#pop">
<IncludeRules context="FindHTMLTagsClose" />
<StringDetect attribute="Element" context="#pop!El Close" String="%1" dynamic="true" />
</context>
<!-- This allows you to insert HTML tags in other syntax definitions -->
<context name="FindSpecialHTMLTags" attribute="Normal Text" lineEndContext="#stay">
<RegExpr attribute="Element" context="CSS" String="&lt;style\b" insensitive="true" beginRegion="style" />
<RegExpr attribute="Element" context="JS" String="&lt;script\b" insensitive="true" beginRegion="script" />
<WordDetect attribute="Element" context="#pop!CSS" String="style" insensitive="true" beginRegion="style" />
<WordDetect attribute="Element" context="#pop!JS" String="script" insensitive="true" beginRegion="script" />
</context>
<context name="FindHTMLTags" attribute="Normal Text" lineEndContext="#stay">
<WordDetect attribute="Element" context="El Open" String="&lt;pre" insensitive="true" beginRegion="pre" />
<WordDetect attribute="Element" context="El Open" String="&lt;div" insensitive="true" beginRegion="div" />
<WordDetect attribute="Element" context="El Open" String="&lt;table" insensitive="true" beginRegion="table" />
<WordDetect attribute="Element" context="El Open" String="&lt;ul" insensitive="true" beginRegion="ul" />
<WordDetect attribute="Element" context="El Open" String="&lt;ol" insensitive="true" beginRegion="ol" />
<WordDetect attribute="Element" context="El Open" String="&lt;dl" insensitive="true" beginRegion="dl" />
<WordDetect attribute="Element" context="El Open" String="&lt;article" insensitive="true" beginRegion="article" />
<WordDetect attribute="Element" context="El Open" String="&lt;aside" insensitive="true" beginRegion="aside" />
<WordDetect attribute="Element" context="El Open" String="&lt;details" insensitive="true" beginRegion="details" />
<WordDetect attribute="Element" context="El Open" String="&lt;figure" insensitive="true" beginRegion="figure" />
<WordDetect attribute="Element" context="El Open" String="&lt;footer" insensitive="true" beginRegion="footer" />
<WordDetect attribute="Element" context="El Open" String="&lt;header" insensitive="true" beginRegion="header" />
<WordDetect attribute="Element" context="El Open" String="&lt;main" insensitive="true" beginRegion="main" />
<WordDetect attribute="Element" context="El Open" String="&lt;nav" insensitive="true" beginRegion="nav" />
<WordDetect attribute="Element" context="El Open" String="&lt;section" insensitive="true" beginRegion="section" />
<RegExpr attribute="Element" context="El Open" String="&lt;&name;" />
<WordDetect attribute="Element" context="El Close" String="&lt;/pre" insensitive="true" endRegion="pre" />
<WordDetect attribute="Element" context="El Close" String="&lt;/div" insensitive="true" endRegion="div" />
<WordDetect attribute="Element" context="El Close" String="&lt;/table" insensitive="true" endRegion="table" />
<WordDetect attribute="Element" context="El Close" String="&lt;/ul" insensitive="true" endRegion="ul" />
<WordDetect attribute="Element" context="El Close" String="&lt;/ol" insensitive="true" endRegion="ol" />
<WordDetect attribute="Element" context="El Close" String="&lt;/dl" insensitive="true" endRegion="dl" />
<WordDetect attribute="Element" context="El Close" String="&lt;/article" insensitive="true" endRegion="article" />
<WordDetect attribute="Element" context="El Close" String="&lt;/aside" insensitive="true" endRegion="aside" />
<WordDetect attribute="Element" context="El Close" String="&lt;/details" insensitive="true" endRegion="details" />
<WordDetect attribute="Element" context="El Close" String="&lt;/figure" insensitive="true" endRegion="figure" />
<WordDetect attribute="Element" context="El Close" String="&lt;/footer" insensitive="true" endRegion="footer" />
<WordDetect attribute="Element" context="El Close" String="&lt;/header" insensitive="true" endRegion="header" />
<WordDetect attribute="Element" context="El Close" String="&lt;/main" insensitive="true" endRegion="main" />
<WordDetect attribute="Element" context="El Close" String="&lt;/nav" insensitive="true" endRegion="nav" />
<WordDetect attribute="Element" context="El Close" String="&lt;/section" insensitive="true" endRegion="section" />
<RegExpr attribute="Element" context="El Close" String="&lt;/&name;" />
<WordDetect attribute="Element" context="#pop!El Open" String="pre" insensitive="true" beginRegion="pre" />
<WordDetect attribute="Element" context="#pop!El Open" String="div" insensitive="true" beginRegion="div" />
<WordDetect attribute="Element" context="#pop!El Open" String="table" insensitive="true" beginRegion="table" />
<WordDetect attribute="Element" context="#pop!El Open" String="ul" insensitive="true" beginRegion="ul" />
<WordDetect attribute="Element" context="#pop!El Open" String="ol" insensitive="true" beginRegion="ol" />
<WordDetect attribute="Element" context="#pop!El Open" String="dl" insensitive="true" beginRegion="dl" />
<WordDetect attribute="Element" context="#pop!El Open" String="article" insensitive="true" beginRegion="article" />
<WordDetect attribute="Element" context="#pop!El Open" String="aside" insensitive="true" beginRegion="aside" />
<WordDetect attribute="Element" context="#pop!El Open" String="details" insensitive="true" beginRegion="details" />
<WordDetect attribute="Element" context="#pop!El Open" String="figure" insensitive="true" beginRegion="figure" />
<WordDetect attribute="Element" context="#pop!El Open" String="footer" insensitive="true" beginRegion="footer" />
<WordDetect attribute="Element" context="#pop!El Open" String="header" insensitive="true" beginRegion="header" />
<WordDetect attribute="Element" context="#pop!El Open" String="main" insensitive="true" beginRegion="main" />
<WordDetect attribute="Element" context="#pop!El Open" String="nav" insensitive="true" beginRegion="nav" />
<WordDetect attribute="Element" context="#pop!El Open" String="section" insensitive="true" beginRegion="section" />
</context>
<context name="FindHTMLTagsClose" attribute="Normal Text" lineEndContext="#stay">
<WordDetect attribute="Element" context="#pop!El Close" String="pre" insensitive="true" endRegion="pre" />
<WordDetect attribute="Element" context="#pop!El Close" String="div" insensitive="true" endRegion="div" />
<WordDetect attribute="Element" context="#pop!El Close" String="table" insensitive="true" endRegion="table" />
<WordDetect attribute="Element" context="#pop!El Close" String="ul" insensitive="true" endRegion="ul" />
<WordDetect attribute="Element" context="#pop!El Close" String="ol" insensitive="true" endRegion="ol" />
<WordDetect attribute="Element" context="#pop!El Close" String="dl" insensitive="true" endRegion="dl" />
<WordDetect attribute="Element" context="#pop!El Close" String="article" insensitive="true" endRegion="article" />
<WordDetect attribute="Element" context="#pop!El Close" String="aside" insensitive="true" endRegion="aside" />
<WordDetect attribute="Element" context="#pop!El Close" String="details" insensitive="true" endRegion="details" />
<WordDetect attribute="Element" context="#pop!El Close" String="figure" insensitive="true" endRegion="figure" />
<WordDetect attribute="Element" context="#pop!El Close" String="footer" insensitive="true" endRegion="footer" />
<WordDetect attribute="Element" context="#pop!El Close" String="header" insensitive="true" endRegion="header" />
<WordDetect attribute="Element" context="#pop!El Close" String="main" insensitive="true" endRegion="main" />
<WordDetect attribute="Element" context="#pop!El Close" String="nav" insensitive="true" endRegion="nav" />
<WordDetect attribute="Element" context="#pop!El Close" String="section" insensitive="true" endRegion="section" />
</context>
<context name="FindEntityRefs" attribute="Other Text" lineEndContext="#stay">
@@ -79,8 +96,8 @@
</context>
<context name="FindAttributes" attribute="Other Text" lineEndContext="#stay">
<RegExpr attribute="Attribute" context="#stay" String="^&attributeName;|\s+&attributeName;" />
<DetectChar attribute="Attribute" context="Value" char="=" />
<DetectChar attribute="Attribute Separator" context="Value" char="=" />
<RegExpr attribute="Attribute" context="#stay" String="(^|\s+)&attributeName;(\s+&attributeName;)*\s*|\s+" />
</context>
<context name="FindDTDRules" attribute="Other Text" lineEndContext="#stay">
@@ -136,49 +153,40 @@
<IncludeRules context="FindPEntityRefs" />
</context>
<context name="El Open" attribute="Other Text" lineEndContext="#stay">
<Detect2Chars attribute="Element" context="#pop" char="/" char1="&gt;" />
<DetectChar attribute="Element" context="#pop" char="&gt;" />
<context name="El Open" attribute="Error" lineEndContext="#stay">
<Detect2Chars attribute="Element Symbols" context="#pop" char="/" char1="&gt;" />
<DetectChar attribute="Element Symbols" context="#pop" char="&gt;" />
<IncludeRules context="FindAttributes" />
<RegExpr attribute="Error" context="#stay" String="\S" />
</context>
<context name="El Close" attribute="Other Text" lineEndContext="#stay">
<DetectChar attribute="Element" context="#pop" char="&gt;" />
<DetectChar attribute="Element Symbols" context="#pop" char="&gt;" />
<RegExpr attribute="Error" context="#stay" String="\S" />
</context>
<context name="El Close 2" attribute="Other Text" lineEndContext="#stay">
<DetectChar attribute="Element" context="#pop#pop#pop" char="&gt;" />
<RegExpr attribute="Error" context="#stay" String="\S" />
</context>
<context name="El Close 3" attribute="Other Text" lineEndContext="#stay">
<DetectChar attribute="Element" context="#pop#pop#pop#pop" char="&gt;" />
<RegExpr attribute="Error" context="#stay" String="\S" />
</context>
<context name="CSS" attribute="Other Text" lineEndContext="#stay">
<Detect2Chars attribute="Element" context="#pop" char="/" char1="&gt;" endRegion="style" />
<DetectChar attribute="Element" context="CSS content" char="&gt;" />
<context name="CSS" attribute="Error" lineEndContext="#stay">
<Detect2Chars attribute="Element Symbols" context="#pop" char="/" char1="&gt;" endRegion="style" />
<DetectChar attribute="Element Symbols" context="CSS content" char="&gt;" />
<IncludeRules context="FindAttributes" />
<RegExpr attribute="Error" context="#stay" String="\S" />
</context>
<context name="CSS content" attribute="Other Text" lineEndContext="#stay">
<RegExpr attribute="Element" context="El Close 2" String="&lt;/style\b" insensitive="true" endRegion="style" />
<RegExpr attribute="Element Symbols" context="CSS content Close" String="&lt;/(?=style\b)" insensitive="true" />
<IncludeRules context="##CSS" includeAttrib="true"/>
</context>
<context name="CSS content Close" attribute="Other Text" lineEndContext="#stay">
<DetectIdentifier attribute="Element" context="#pop#pop#pop!El Close" endRegion="style" />
</context>
<context name="JS" attribute="Other Text" lineEndContext="#stay">
<context name="JS" attribute="Error" lineEndContext="#stay">
<RegExpr attribute="Attribute" context="Script-Type" String="(?:\s+|^)type(?=\=|\s|$)" insensitive="true"/>
<DetectChar attribute="Element" context="JS content" char="&gt;" />
<DetectChar attribute="Element Symbols" context="JS content" char="&gt;" />
<IncludeRules context="DefaultJS" />
</context>
<context name="DefaultJS" attribute="Other Text" lineEndContext="#stay">
<Detect2Chars attribute="Element" context="#pop" char="/" char1="&gt;" endRegion="script" />
<IncludeRules context="FindAttributes" />
<RegExpr attribute="Error" context="#stay" String="\S" />
<Detect2Chars attribute="Element Symbols" context="#pop" char="/" char1="&gt;" endRegion="script" />
<DetectChar attribute="Attribute Separator" context="Value" char="=" />
<RegExpr attribute="Attribute" context="#stay" String="(^|\s+)&attributeName;|\s+" />
</context>
<context name="JS content" attribute="Other Text" lineEndContext="#stay">
@@ -186,25 +194,35 @@
<IncludeRules context="Normal##JavaScript" includeAttrib="true"/>
</context>
<context name="Default JS content" attribute="Other Text" lineEndContext="#stay">
<RegExpr attribute="Element" context="El Close 2" String="&lt;/script\b" insensitive="true" endRegion="script" />
<IncludeRules context="FindScriptTagClose" />
<RegExpr attribute="Comment" context="JS comment close" String="//(?=.*&lt;/script\b)" insensitive="true" />
</context>
<context name="FindScriptTagClose" attribute="Other Text" lineEndContext="#stay">
<RegExpr attribute="Element Symbols" context="ScriptTagClose" String="&lt;/(?=script\b)" insensitive="true" />
</context>
<context name="ScriptTagClose" attribute="Other Text" lineEndContext="#stay">
<DetectIdentifier attribute="Element" context="#pop#pop#pop!El Close" endRegion="script" />
</context>
<context name="JS comment close" attribute="Comment" lineEndContext="#pop">
<RegExpr attribute="Element" context="El Close 3" String="&lt;/script\b" insensitive="true" endRegion="script" />
<RegExpr attribute="Element Symbols" context="#pop!ScriptTagClose" String="&lt;/(?=script\b)" insensitive="true" />
<DetectSpaces />
<IncludeRules context="##Comments" />
</context>
<context name="Value" attribute="Other Text" lineEndContext="#stay" fallthrough="true" fallthroughContext="Value NQ">
<context name="Value" attribute="Other Text" lineEndContext="#stay" fallthroughContext="Value NQ">
<DetectChar attribute="Value" context="Value DQ" char="&quot;" />
<DetectChar attribute="Value" context="Value SQ" char="&apos;" />
<DetectSpaces />
</context>
<context name="Value NQ" attribute="Other Text" lineEndContext="#pop#pop" fallthrough="true" fallthroughContext="#pop#pop">
<context name="Value NQ" attribute="Other Text" lineEndContext="#pop#pop" fallthroughContext="#pop#pop">
<!-- '{' and '}' are valid, but used with twig -->
<RegExpr attribute="Value" String="[^&gt;&lt;&quot;&apos;&amp;\s=`{}]+" />
<IncludeRules context="FindEntityRefs" />
<RegExpr attribute="Value" context="#stay" String="/(?!&gt;)|[^/&gt;&lt;&quot;&apos;\s]" />
<AnyChar attribute="Error" String="&quot;&apos;`=" />
<AnyChar attribute="Value" String="{}" />
</context>
<context name="Value DQ" attribute="Value" lineEndContext="#stay">
@@ -220,11 +238,11 @@
<!-- Read content from the "type" attribute to change the language to
highlight in the <script> tag. The default language is JavaScript. -->
<context name="Script-Type" attribute="Other Text" lineEndContext="#stay" fallthrough="true" fallthroughContext="#pop">
<context name="Script-Type" attribute="Other Text" lineEndContext="#stay" fallthroughContext="#pop">
<DetectSpaces />
<DetectChar attribute="Attribute" context="#pop!Script-Type Value" char="=" />
</context>
<context name="Script-Type Value" attribute="Other Text" lineEndContext="#stay" fallthrough="true" fallthroughContext="#pop!Value">
<context name="Script-Type Value" attribute="Other Text" lineEndContext="#stay" fallthroughContext="#pop!Value">
<DetectSpaces />
<!-- TypeScript -->
<StringDetect attribute="Value" context="#pop#pop!TypeScript" String="&quot;text/typescript&quot;"/>
@@ -250,8 +268,8 @@
<StringDetect attribute="Value" context="#pop#pop!Script HTML template" String="&apos;text/html&apos;"/>
</context>
<context name="JSX" attribute="Other Text" lineEndContext="#stay">
<DetectChar attribute="Element" context="JSX content" char="&gt;" />
<context name="JSX" attribute="Error" lineEndContext="#stay">
<DetectChar attribute="Element Symbols" context="JSX content" char="&gt;" />
<IncludeRules context="DefaultJS" />
</context>
<context name="JSX content" attribute="Other Text" lineEndContext="#stay">
@@ -259,8 +277,8 @@
<IncludeRules context="Normal##JavaScript React (JSX)" includeAttrib="true"/>
</context>
<context name="TypeScript" attribute="Other Text" lineEndContext="#stay">
<DetectChar attribute="Element" context="TypeScript content" char="&gt;" />
<context name="TypeScript" attribute="Error" lineEndContext="#stay">
<DetectChar attribute="Element Symbols" context="TypeScript content" char="&gt;" />
<IncludeRules context="DefaultJS" />
</context>
<context name="TypeScript content" attribute="Other Text" lineEndContext="#stay">
@@ -268,25 +286,25 @@
<IncludeRules context="Normal##TypeScript" includeAttrib="true"/>
</context>
<context name="MustacheJS" attribute="Other Text" lineEndContext="#stay">
<DetectChar attribute="Element" context="MustacheJS content" char="&gt;" />
<context name="MustacheJS" attribute="Error" lineEndContext="#stay">
<DetectChar attribute="Element Symbols" context="MustacheJS content" char="&gt;" />
<IncludeRules context="DefaultJS" />
</context>
<context name="MustacheJS content" attribute="Other Text" lineEndContext="#stay">
<RegExpr attribute="Element" context="El Close 2" String="&lt;/script\b" insensitive="true" endRegion="script" />
<IncludeRules context="FindScriptTagClose" />
<StringDetect attribute="Error" context="#stay" String="&lt;script&gt;" insensitive="true" />
<RegExpr attribute="Error" context="#stay" String="&lt;script\b" insensitive="true" />
<WordDetect attribute="Error" context="#stay" String="&lt;script" insensitive="true" />
<IncludeRules context="Base##Mustache/Handlebars (HTML)" includeAttrib="true"/>
</context>
<context name="Script HTML template" attribute="Other Text" lineEndContext="#stay">
<DetectChar attribute="Element" context="Script HTML template content" char="&gt;" />
<context name="Script HTML template" attribute="Error" lineEndContext="#stay">
<DetectChar attribute="Element Symbols" context="Script HTML template content" char="&gt;" />
<IncludeRules context="DefaultJS" />
</context>
<context name="Script HTML template content" attribute="Other Text" lineEndContext="#stay">
<RegExpr attribute="Element" context="El Close 2" String="&lt;/script\b" insensitive="true" endRegion="script" />
<IncludeRules context="FindScriptTagClose" />
<StringDetect attribute="Error" context="#stay" String="&lt;script&gt;" insensitive="true" />
<RegExpr attribute="Error" context="#stay" String="&lt;script\b" insensitive="true" />
<WordDetect attribute="Error" context="#stay" String="&lt;script" insensitive="true" />
<IncludeRules context="FindHTML" />
</context>
@@ -299,7 +317,9 @@
<itemData name="Processing Instruction" defStyleNum="dsKeyword" spellChecking="false" />
<itemData name="Doctype" defStyleNum="dsDataType" bold="1" spellChecking="false" />
<itemData name="Element" defStyleNum="dsKeyword" spellChecking="false" />
<itemData name="Element Symbols" defStyleNum="dsDataType" spellChecking="false" />
<itemData name="Attribute" defStyleNum="dsOthers" spellChecking="false" />
<itemData name="Attribute Separator" defStyleNum="dsOperator" 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 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
<language name="INI Files" section="Configuration" extensions="*.ini;*.pls;*.kcfgc;.gitattributes*;.gitconfig*;.gitmodules*;.editorconfig*" mimetype="" version="12" kateversion="5.0" author="Jan Janssen (medhefgo@web.de)" license="LGPL">
<!DOCTYPE language>
<language name="INI Files" section="Configuration" extensions="*.ini;*.cfg;*.pls;*.kcfgc;.gitattributes*;.gitconfig*;.gitmodules*;.editorconfig*" mimetype="" version="13" kateversion="5.0" author="Jan Janssen (medhefgo@web.de)" license="LGPL" priority="1">
<highlighting>
<list name="keywords">

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd"
<!DOCTYPE language
[
<!ENTITY int "(?:[0-9]++(_++[0-9]++)*+)">
<!ENTITY hex "(?:[0-9a-fA-F]++(_++[0-9a-fA-F]++)*+)">
@@ -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="11" 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="13" kateversion="5.79" 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>
@@ -3705,6 +3705,8 @@
<!-- end new classes -->
</list>
<!-- https://docs.oracle.com/javase/specs/jls/se20/html/jls-3.html#jls-Keyword -->
<list name="keywords">
<item>abstract</item>
<item>class</item>
@@ -3714,7 +3716,6 @@
<item>false</item>
<item>implements</item>
<item>instanceof</item>
<item>@interface</item>
<item>interface</item>
<item>native</item>
<item>new</item>
@@ -3730,6 +3731,11 @@
<item>transient</item>
<item>true</item>
<item>volatile</item>
<!-- contextual -->
<item>non-sealed</item>
<item>permits</item>
<item>record</item>
<item>sealed</item>
</list>
<list name="control flow">
<item>assert</item>
@@ -3748,6 +3754,7 @@
<item>throw</item>
<item>try</item>
<item>while</item>
<item>yield</item>
</list>
<list name="types">
<item>boolean</item>
@@ -3764,6 +3771,25 @@
<item>var</item>
<item>void</item>
</list>
<list name="annotations">
<!-- builtin -->
<item>@Override</item>
<item>@Deprecated</item>
<item>@SuppressWarnings</item>
<item>@SafeVarargs</item>
<item>@FunctionalInterface</item>
<item>@interface</item>
<!-- java.lang.annotation -->
<item>@Retention</item>
<item>@Documented</item>
<item>@Target</item>
<item>@Inherited</item>
<item>@Repeatable</item>
</list>
<!-- https://docs.oracle.com/javase/specs/jls/se20/html/jls-3.html -->
<contexts>
<context attribute="Normal Text" lineEndContext="#stay" name="Normal">
<DetectSpaces context="#stay"/>
@@ -3783,6 +3809,7 @@
<AnyChar context="Number" String="0123456789" lookAhead="1"/>
<StringDetect attribute="Text Block" context="TextBlock" String="&quot;&quot;&quot;"/>
<DetectChar attribute="String" context="String" char="&quot;"/>
<DetectChar context="Char" char="'" lookAhead="1"/>
@@ -3795,6 +3822,7 @@
<WordDetect attribute="Keyword" context="ImportsOrStaticImports" String="import" />
<RegExpr attribute="Function" context="#stay" String="\b[_a-zA-Z]\w*(?=[\s]*(/\*\s*\d+\s*\*/\s*)?[(])" />
<WordDetect attribute="Keyword" context="ImportsOrStaticImports" String="non-sealed" />
<DetectIdentifier attribute="Normal Text"/>
</context>
@@ -3831,6 +3859,11 @@
<RegExpr attribute="Error" context="#pop" String="\\(u+[0-9a-fA-F]*|.)?"/>
</context>
<context attribute="Text Block" lineEndContext="#stay" name="TextBlock">
<DetectChar context="StringEscapedChar" char="\" lookAhead="1"/>
<StringDetect attribute="Text Block" context="#pop" String="&quot;&quot;&quot;"/>
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="Printf" fallthroughContext="#pop">
<DetectChar attribute="Symbol" context="#pop!InPrintf" char="("/>
<DetectSpaces attribute="Normal Text" context="#stay"/>
@@ -3898,6 +3931,7 @@
<itemData name="Binary" defStyleNum="dsBaseN" spellChecking="false"/>
<itemData name="Float" defStyleNum="dsFloat" spellChecking="false"/>
<itemData name="Char" defStyleNum="dsChar" spellChecking="false"/>
<itemData name="Text Block" defStyleNum="dsString"/>
<itemData name="String" defStyleNum="dsString"/>
<itemData name="String Char" defStyleNum="dsSpecialChar" spellChecking="false"/>
<itemData name="PrintfString" defStyleNum="dsString"/>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
<language name="Javadoc" version="6" kateversion="5.62" section="Markup" extensions="" license="LGPL" author="Alfredo Luiz Foltran Fialho (alfoltran@ig.com.br)">
<!DOCTYPE language>
<language name="Javadoc" version="7" kateversion="5.79" section="Markup" extensions="" license="LGPL" author="Alfredo Luiz Foltran Fialho (alfoltran@ig.com.br)">
<highlighting>
<contexts>
<context name="Start" attribute="Normal Text" lineEndContext="#stay">

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
<!DOCTYPE language>
<!--
***************************************************************************
** Writing a Kate Highlighting XML File
@@ -13,7 +13,7 @@
** https://www.json.org/json-en.html
***************************************************************************
-->
<language name="JSON" section="Markup" version="7" kateversion="2.4" extensions="*.json;.kateproject;.arcconfig;*.geojson;*.gltf;*.theme" mimetype="application/json" author="Sebastian Pipping (sebastian@pipping.org)" license="GPL">
<language name="JSON" section="Markup" version="8" kateversion="2.4" extensions="*.json;.kateproject;.arcconfig;*.geojson;*.gltf;*.theme" mimetype="application/json" author="Sebastian Pipping (sebastian@pipping.org)" license="GPL">
<highlighting>
<list name="Constants">
<item>null</item>
@@ -40,7 +40,12 @@
<context name="String_Key" lineEndContext="#stay" attribute="Style_String_Key">
<DetectChar char="&quot;" context="#pop" attribute="Style_String_Key" />
<RegExpr String="\\(?:[&quot;\\/bfnrt]|u[0-9a-fA-f]{4})" context="#stay" attribute="Style_String_Key_Char" />
<DetectChar char="\" context="String_Key_Char" lookAhead="1"/>
</context>
<context name="String_Key_Char" lineEndContext="#stay" attribute="Style_Normal">
<RegExpr String="\\(?:[&quot;\\/bfnrt]|u[0-9a-fA-f]{4})" context="#pop" attribute="Style_String_Key_Char" />
<RegExpr String="\\(u[0-9a-fA-f]+|.)?" context="#pop" attribute="Style_Error" />
</context>
<context name="Value" lineEndContext="#stay" attribute="Style_Error" >
@@ -57,13 +62,18 @@
<keyword String="Constants" context="#stay" attribute="Style_Keyword" />
<RegExpr String="-?[0-9]+\.[0-9]+(?:[eE][+-]?[0-9]+)?" context="#stay" attribute="Style_Float" />
<RegExpr String="-?[0-9]+(?:[eE][+-]?[0-9]+)?" context="#stay" attribute="Style_Decimal" />
<RegExpr String="-?\b([1-9][0-9]*\.[0-9]+(?:[eE][+-]?[0-9]+)?)" context="#stay" attribute="Style_Float" />
<RegExpr String="-?\b(0\b|[1-9][0-9]*(?:[eE][+-]?[0-9]+)?)" context="#stay" attribute="Style_Decimal" />
</context>
<context name="String_Value" lineEndContext="#stay" attribute="Style_String_Value">
<DetectChar char="&quot;" context="#pop" attribute="Style_String_Value" />
<RegExpr String="\\(?:[&quot;\\/bfnrt]|u[0-9a-fA-f]{4})" context="#stay" attribute="Style_String_Value_Char" />
<DetectChar char="\" context="String_Key_Value" lookAhead="1" />
</context>
<context name="String_Key_Value" lineEndContext="#stay" attribute="Style_Normal">
<RegExpr String="\\(?:[&quot;\\/bfnrt]|u[0-9a-fA-f]{4})" context="#pop" attribute="Style_String_Value_Char" />
<RegExpr String="\\(u[0-9a-fA-f]+|.)?" context="#pop" attribute="Style_Error" />
</context>
<context name="Array" lineEndContext="#stay" attribute="Style_Error">

View File

@@ -22,7 +22,7 @@
Example: **bold text and _italic and bold text_**
__bold and ~~strikeout and bold~~__
-->
<!DOCTYPE language SYSTEM "language.dtd"
<!DOCTYPE language
[
<!-- NOTE: To correctly detect bold, italic or strike out text, use minimal="true" in RegExpr rules -->
<!ENTITY contentregex_ast "(?:(?:[^\*\s\\]|\\.)(?:[^\\]|\\.)*)?(?:[^\*\s\\]|\\\S)">
@@ -72,6 +72,10 @@
<!ENTITY linebreakregex " $">
<!-- strikethrough text, pandoc style -->
<!ENTITY strikeoutregex "[~]{2}[^~](?:.*[^~])?[~]{2}">
<!-- highlight text -->
<!ENTITY highlightregex "[=]{2}[^=](?:.*[^=])?[=]{2}">
<!-- emoji -->
<!ENTITY emojiregex ":([-+]1|\w+):">
<!-- start of fenced code block -->
<!ENTITY fcode "(`{3,}|~{3,})">
<!-- end of line & empty line -->
@@ -90,7 +94,7 @@
<!ENTITY checkbox "\[[ x]\](?=\s)">
]>
<language name="Markdown" version="24" kateversion="5.79" section="Markup" extensions="*.md;*.mmd;*.markdown" priority="15" author="Darrin Yeager, Claes Holmerson" license="GPL,BSD">
<language name="Markdown" version="30" kateversion="5.79" section="Markup" extensions="*.md;*.mmd;*.markdown;*.md.html" mimetype="text/markdown" priority="15" author="Darrin Yeager, Claes Holmerson" license="GPL,BSD">
<highlighting>
<contexts>
<!-- Start of the Markdown document: find metadata or code block -->
@@ -137,9 +141,12 @@
<DetectChar context="find-strong-normal" char="*" lookAhead="true"/>
<DetectChar context="find-emphasis-normal" char="_" lookAhead="true"/>
<RegExpr attribute="Strikethrough Text" minimal="true" String="&strikeoutregex;"/>
<RegExpr attribute="Highlight Text" minimal="true" String="&highlightregex;"/>
<!-- Common -->
<IncludeRules context="inc"/>
<RegExpr attribute="Normal Text: Link" String="&implicitlink;"/>
<!-- Table -->
<DetectChar attribute="Table" char="|" context="table" firstNonSpace="true" lookAhead="1"/>
</context>
<!-- Find indented code blocks. These are only allowed after an empty line or on the first line -->
<context name="find-code-block" attribute="Normal Text" lineEndContext="#stay" lineEmptyContext="#stay" fallthroughContext="#pop">
@@ -148,6 +155,16 @@
<RegExpr attribute="Comment" context="comment" String="^\s*&startcomment;|\s*&startcomment;(?=.*&endcomment;)" beginRegion="comment"/>
</context>
<!-- Table in Normal Text Document -->
<context name="table" attribute="Normal Text" lineEndContext="#pop" lineEmptyContext="#pop!find-code-block">
<IncludeRules context="find-table-element"/>
<IncludeRules context="Normal Text"/>
</context>
<context name="find-table-element" attribute="Normal Text" lineEndContext="#pop">
<RegExpr attribute="Table" String="(\|(\s*:?---+:?)?)++"/>
</context>
<context name="find-header" attribute="Normal Text" lineEndContext="#pop">
<RegExpr attribute="Header H1" context="#pop!close-H2-region" String="^#\s" column="0" endRegion="H1" beginRegion="H1" lookAhead="true"/>
<RegExpr attribute="Header H2" context="#pop!close-H3-region" String="^##\s" column="0" endRegion="H2" beginRegion="H2" lookAhead="true"/>
@@ -207,6 +224,7 @@
<RegExpr attribute="Normal Text" context="#pop!find-code-block" String="&emptyline;" column="0"/>
<StringDetect attribute="Comment" context="#pop!find-code-block" String="&startcomment;" column="0" lookAhead="true"/>
<IncludeRules context="default-blockquote-2"/>
<IncludeRules context="find-table-element"/>
</context>
<!-- Blockquote within a list -->
<context name="blockquote-list" attribute="Blockquote: Normal Text" lineEndContext="#stay" lineEmptyContext="#pop">
@@ -226,6 +244,7 @@
<!-- Strong, emphasis, strong-emphasis and strikethrough text -->
<AnyChar context="find-strong-emphasis-blockquote" String="*_" lookAhead="true"/>
<RegExpr attribute="Blockquote: Strikethrough Text" minimal="true" String="&strikeoutregex;"/>
<RegExpr attribute="Blockquote: Highlight Text" minimal="true" String="&highlightregex;"/>
<!-- Common -->
<IncludeRules context="inc"/>
<RegExpr attribute="Blockquote: Link" String="&implicitlink;"/>
@@ -254,6 +273,8 @@
<RegExpr context="#pop" String="^\s*\S" column="0" lookAhead="true"/>
<!-- Highlight checkbox at the start of the item (task list) -->
<RegExpr attribute="List: Checkbox" context="content-list" String="\s*&checkbox;"/>
<!-- Highlight checkbox at the start of the item (task list) -->
<RegExpr attribute="Table" context="content-list-table" String="\s*\|"/>
</context>
<!-- 1. numlist (one digit) -->
<context name="numlist" attribute="List: Normal Text" lineEndContext="#stay" fallthroughContext="content-list">
@@ -284,13 +305,14 @@
to check the indentation of the text and determine if the content of the list ends. -->
<context name="content-list" attribute="List: Normal Text" lineEndContext="#stay" lineEmptyContext="#pop">
<RegExpr context="#pop" String="&emptyline;" column="0"/>
<!-- Blockquote and horzontal rule (check indentation) -->
<!-- Blockquote and horizontal rule (check indentation) -->
<RegExpr context="#pop" String="^\s*(?:&gt;|&rulerregex;)" column="0" lookAhead="true"/>
<!-- End with header or new list/numlist -->
<RegExpr context="#pop#pop" String="^(?:\s*(?:&listbullet;|[\d]+\.)\s|#{1,6}\s)" column="0" lookAhead="true"/>
<!-- Strong, emphasis, strong-emphasis and strikethrough text -->
<AnyChar context="find-strong-emphasis-list" String="*_" lookAhead="true"/>
<RegExpr attribute="List: Strikethrough Text" minimal="true" String="&strikeoutregex;"/>
<RegExpr attribute="List: Highlight Text" minimal="true" String="&highlightregex;"/>
<!-- Common -->
<IncludeRules context="inc"/>
<RegExpr attribute="List: Link" String="&implicitlink;"/>
@@ -303,6 +325,12 @@
<AnyChar attribute="List: Normal Text" context="#pop" String="*_"/>
</context>
<!-- Table in List -->
<context name="content-list-table" attribute="List: Normal Text" lineEndContext="#stay" lineEmptyContext="#pop">
<IncludeRules context="find-table-element"/>
<IncludeRules context="content-list"/>
</context>
<!-- Comments -->
<context name="comment" attribute="Comment" lineEndContext="#stay">
<StringDetect attribute="Comment" context="#pop" String="&endcomment;" endRegion="comment"/>
@@ -312,42 +340,42 @@
<!-- Fenced Code Blocks -->
<context name="find-lang-fenced-code" attribute="Normal Text" lineEndContext="#pop">
<!-- Apply syntax highlighting to fenced code blocks for some languages -->
<RegExpr attribute="Fenced Code" context="#pop!code" String="&fcode;&end;"/>
<RegExpr attribute="Fenced Code" context="#pop!bash-code" String="&fcode;\s*(?:bash(?:rc|_profile|_login|_logout)?|shell|sh|profile|PKGBUILD|APKBUILD|ebuild|eclass|nix)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!zsh-code" String="&fcode;\s*(?:zsh)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!cpp-code" String="&fcode;\s*(?:[ch]pp|[ch]\+\+|[ch]xx|h?cc|hh|cuh?|ino|pde|moc)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!csharp-code" String="&fcode;\s*(?:cs|csharp|c\#)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!cmake-code" String="&fcode;\s*(?:cmake|CMakeLists(?:\.txt)?)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!css-code" String="&fcode;\s*css&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!c-code" String="&fcode;\s*[ch]&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!doxygen-code" String="&fcode;\s*doxygen&end;" insensitive="true"/> <!-- Block comment of Doxygen -->
<RegExpr attribute="Fenced Code" context="#pop!email-code" String="&fcode;\s*(?:email|emlx?|mbo?x)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!go-code" String="&fcode;\s*go(?:lang)?&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!hamlet-code" String="&fcode;\s*[wxs]?hamlet&end;" insensitive="true"/> <!-- Included in the Haskell definition -->
<RegExpr attribute="Fenced Code" context="#pop!haskell-code" String="&fcode;\s*(?:haskell|c?hs|hs\-boot)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!html-code" String="&fcode;\s*(?:[sx]?html?|inc|tmpl|tpl)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!java-code" String="&fcode;\s*(?:java|bsh)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!javascript-code" String="&fcode;\s*(?:javascript|m?js|es6|kwinscript|julius)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!jsx-code" String="&fcode;\s*(?:jsx|tsx|(?:java|type)script\-react)&end;" insensitive="true"/> <!-- Included in the HTML definition. Also apply for TSX. -->
<RegExpr attribute="Fenced Code" context="#pop!json-code" String="&fcode;\s*(?:json5?|gltf)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!yaml-code" String="&fcode;\s*(?:ya?ml)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!matlab-code" String="&fcode;\s*matlab&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!markdown-code" String="&fcode;\s*(?:markdown|m?md)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!mustache-code" String="&fcode;\s*(?:handlebars|hbs|mustache|mst|ractive|hogan|hulk)&end;" insensitive="true"/> <!-- Included in the HTML definition -->
<RegExpr attribute="Fenced Code" context="#pop!perl-code" String="&fcode;\s*(?:perl|p[lm]|pod|psgi|vcl)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!php-code" String="&fcode;\s*(?:php[3457t]?|wml|phtml?|aw|ctp)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!python-code" String="&fcode;\s*(?:python[23]?|py[23w]?|[rc]py|sconstruct|gypi?)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!qml-code" String="&fcode;\s*qml(?:types)?&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!r-code" String="&fcode;\s*(?:r|rprofile|rscript)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!raku-code" String="&fcode;\s*(?:raku(?:mod|doc|test)?|perl6|p[lm]?6|pod6|nqp)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!rest-code" String="&fcode;\s*(?:rst|rest|restructuredtext)&end;" insensitive="true"/> <!-- Included in the CMake definition -->
<RegExpr attribute="Fenced Code" context="#pop!ruby-code" String="&fcode;\s*(?:ruby|rbx?|rjs|rake|f?cgi|gemspec|irbrc|ru|prawn|Appraisals|(?:Rake|Cap|Chef|Gem|Guard|Hobo|Vagrant||Rant|Berks|Thor|Puppet)file|rxml|(?:xml|js)\.erb)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!rust-code" String="&fcode;\s*(?:rust|rs)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!mysql-code" String="&fcode;\s*(?:mysql|sql|ddl)&end;" insensitive="true"/> <!-- Included in the PHP definition -->
<RegExpr attribute="Fenced Code" context="#pop!nim-code" String="&fcode;\s*(?:nims?)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!typescript-code" String="&fcode;\s*(?:typescript|ts)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!xml-code" String="&fcode;\s*(?:xml|xsd|xspf|tld|jsp|c?pt|dtml|rss|opml|svg|daml|rdf|ui|kcfg|qrc|wsdl|scxml|xbel|dae|sch|brd|docbook)&end;" insensitive="true"/>
<RegExpr attribute="Fenced Code" context="#pop!code" String="&fcode;.*$"/>
<RegExpr attribute="Fenced Code" context="#pop!code" String="&fcode;&end;" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!bash-code" String="&fcode;\s*(?:bash(?:rc|_profile|_login|_logout)?|shell|sh|profile|PKGBUILD|APKBUILD|ebuild|eclass|nix)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!zsh-code" String="&fcode;\s*(?:zsh)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!cpp-code" String="&fcode;\s*(?:[ch]pp|[ch]\+\+|[ch]xx|h?cc|hh|cuh?|ino|pde|moc)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!csharp-code" String="&fcode;\s*(?:cs|csharp|c\#)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!cmake-code" String="&fcode;\s*(?:cmake|CMakeLists(?:\.txt)?)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!css-code" String="&fcode;\s*css&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!c-code" String="&fcode;\s*[ch]&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!doxygen-code" String="&fcode;\s*doxygen&end;" insensitive="true" beginRegion="code-block"/> <!-- Block comment of Doxygen -->
<RegExpr attribute="Fenced Code" context="#pop!email-code" String="&fcode;\s*(?:email|emlx?|mbo?x)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!go-code" String="&fcode;\s*go(?:lang)?&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!hamlet-code" String="&fcode;\s*[wxs]?hamlet&end;" insensitive="true" beginRegion="code-block"/> <!-- Included in the Haskell definition -->
<RegExpr attribute="Fenced Code" context="#pop!haskell-code" String="&fcode;\s*(?:haskell|c?hs|hs\-boot)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!html-code" String="&fcode;\s*(?:[sx]?html?|inc|tmpl|tpl)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!java-code" String="&fcode;\s*(?:java|bsh)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!javascript-code" String="&fcode;\s*(?:javascript|m?js|es6|kwinscript|julius)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!jsx-code" String="&fcode;\s*(?:jsx|tsx|(?:java|type)script\-react)&end;" insensitive="true" beginRegion="code-block"/> <!-- Included in the HTML definition. Also apply for TSX. -->
<RegExpr attribute="Fenced Code" context="#pop!json-code" String="&fcode;\s*(?:json5?|gltf)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!yaml-code" String="&fcode;\s*(?:ya?ml)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!matlab-code" String="&fcode;\s*matlab&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!markdown-code" String="&fcode;\s*(?:markdown|m?md)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!mustache-code" String="&fcode;\s*(?:handlebars|hbs|mustache|mst|ractive|hogan|hulk)&end;" insensitive="true" beginRegion="code-block"/> <!-- Included in the HTML definition -->
<RegExpr attribute="Fenced Code" context="#pop!perl-code" String="&fcode;\s*(?:perl|p[lm]|pod|psgi|vcl)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!php-code" String="&fcode;\s*(?:php[3457t]?|wml|phtml?|aw|ctp)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!python-code" String="&fcode;\s*(?:python[23]?|py[23w]?|[rc]py|sconstruct|gypi?)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!qml-code" String="&fcode;\s*qml(?:types)?&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!r-code" String="&fcode;\s*(?:r|rprofile|rscript)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!raku-code" String="&fcode;\s*(?:raku(?:mod|doc|test)?|perl6|p[lm]?6|pod6|nqp)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!rest-code" String="&fcode;\s*(?:rst|rest|restructuredtext)&end;" insensitive="true" beginRegion="code-block"/> <!-- Included in the CMake definition -->
<RegExpr attribute="Fenced Code" context="#pop!ruby-code" String="&fcode;\s*(?:ruby|rbx?|rjs|rake|f?cgi|gemspec|irbrc|ru|prawn|Appraisals|(?:Rake|Cap|Chef|Gem|Guard|Hobo|Vagrant||Rant|Berks|Thor|Puppet)file|rxml|(?:xml|js)\.erb)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!rust-code" String="&fcode;\s*(?:rust|rs)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!mysql-code" String="&fcode;\s*(?:mysql|sql|ddl)&end;" insensitive="true" beginRegion="code-block"/> <!-- Included in the PHP definition -->
<RegExpr attribute="Fenced Code" context="#pop!nim-code" String="&fcode;\s*(?:nims?)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!typescript-code" String="&fcode;\s*(?:typescript|ts)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!xml-code" String="&fcode;\s*(?:xml|xsd|xspf|tld|jsp|c?pt|dtml|rss|opml|svg|daml|rdf|ui|kcfg|qrc|wsdl|scxml|xbel|dae|sch|brd|docbook)&end;" insensitive="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="#pop!code" String="&fcode;.*$" beginRegion="code-block"/>
</context>
<context name="code" attribute="Code" lineEndContext="#stay"> <!-- Unknown language -->
<RegExpr attribute="Fenced Code" context="#pop" String="%1[~`]*(?=&end;)" firstNonSpace="true" dynamic="true" endRegion="code-block"/>
@@ -450,13 +478,13 @@
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="qml-code">
<IncludeRules context="code"/>
<IncludeRules context="##QML" includeAttrib="true"/>
<IncludeRules context="Normal##QML" includeAttrib="true"/>
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="r-code">
<IncludeRules context="code"/>
<IncludeRules context="##R Script" includeAttrib="true"/>
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="raku-code">
<context attribute="Normal Text" lineEndContext="#stay" name="raku-code" fallthroughContext="term##Raku">
<IncludeRules context="code"/>
<IncludeRules context="base##Raku" includeAttrib="true"/>
</context>
@@ -494,7 +522,7 @@
<!-- Code -->
<RegExpr attribute="Code" String="`[^`]+`(?!`)|`{2}[^`](?:.*?[^`])?`{2}(?!`)|`{3}[^`](?:.*?[^`])?`{3}(?!`)|`{4}[^`](?:.*?[^`])?`{4}(?!`)|`{5,}[^`](?:.*?[^`])?`{5,}"/>
<!-- Find Fenced Code Block -->
<RegExpr attribute="Fenced Code" context="find-lang-fenced-code" String="`{3,}(?=[^`]*$)|~{3,}(?=[^~]*$)" firstNonSpace="true" lookAhead="true" beginRegion="code-block"/>
<RegExpr attribute="Fenced Code" context="find-lang-fenced-code" String="`{3,}(?=[^`]*$)|~{3,}(?=[^~]*$)" firstNonSpace="true" lookAhead="true"/>
<!-- Comment -->
<StringDetect attribute="Comment" context="comment" String="&startcomment;" beginRegion="comment"/>
<!-- Links and References -->
@@ -505,6 +533,8 @@
<RegExpr attribute="Reference Image" String="&refimageregex;"/>
<RegExpr attribute="Auto-Link" context="autolink" String="&autolinkregex;" lookAhead="true"/>
<RegExpr attribute="Mailto-Link" context="mailtolink" String="&mailtolinkregex;"/>
<!-- Emoji -->
<RegExpr attribute="Emoji" String="&emojiregex;"/>
<!-- Line Break -->
<RegExpr attribute="Line Break" minimal="true" String="&linebreakregex;"/>
<!-- Backslash Escapes -->
@@ -523,6 +553,7 @@
<Detect2Chars attribute="Backslash Escape" char="\" char1="-"/>
<Detect2Chars attribute="Backslash Escape" char="\" char1="."/>
<Detect2Chars attribute="Backslash Escape" char="\" char1="!"/>
<Detect2Chars attribute="Backslash Escape" char="\" char1="|"/>
<Detect2Chars attribute="Backslash Escape" char="\" char1="&lt;"/>
<Detect2Chars attribute="Backslash Escape" char="\" char1="&gt;"/>
<Detect2Chars attribute="Backslash Escape" char="\" char1="&amp;"/>
@@ -531,8 +562,7 @@
<RegExpr context="find-html-block" String="&lt;/?&htmlname;(?:[\s&gt;]|/&gt;|$)" lookAhead="true"/>
</context>
<context name="find-html-block" attribute="Normal Text" lineEndContext="#pop" fallthroughContext="#pop">
<IncludeRules context="FindSpecialHTMLTags##HTML"/>
<IncludeRules context="FindHTMLTags##HTML"/>
<IncludeRules context="FindElements##HTML"/>
</context>
<!-- Links and email: <https://example.com>, <example@kde.org> -->
@@ -606,6 +636,7 @@
<itemData name="Strong Text" defStyleNum="dsNormal" bold="true"/>
<itemData name="Strong-Emphasis Text" defStyleNum="dsNormal" italic="true" bold="true"/>
<itemData name="Strikethrough Text" defStyleNum="dsNormal" strikeOut="true"/>
<itemData name="Highlight Text" defStyleNum="dsAlert"/>
<itemData name="Normal Text: Link" defStyleNum="dsNormal" underline="true" spellChecking="false"/>
<itemData name="Horizontal Rule" defStyleNum="dsNormal" bold="true" spellChecking="false"/>
<itemData name="Line Break" defStyleNum="dsNormal" underline="true" color="#999999" spellChecking="false"/>
@@ -621,6 +652,7 @@
<itemData name="Blockquote: Strong Text" defStyleNum="dsAttribute" bold="true"/>
<itemData name="Blockquote: Strong-Emphasis Text" defStyleNum="dsAttribute" italic="true" bold="true"/>
<itemData name="Blockquote: Strikethrough Text" defStyleNum="dsAttribute" strikeOut="true"/>
<itemData name="Blockquote: Highlight Text" defStyleNum="dsAlert"/>
<itemData name="Blockquote: Link" defStyleNum="dsAttribute" underline="true" spellChecking="false"/>
<itemData name="List" defStyleNum="dsSpecialString" bold="1" spellChecking="false"/>
<itemData name="Number List" defStyleNum="dsSpecialString" spellChecking="false"/>
@@ -629,11 +661,14 @@
<itemData name="List: Strong Text" defStyleNum="dsNormal" bold="true"/>
<itemData name="List: Strong-Emphasis Text" defStyleNum="dsNormal" italic="true" bold="true"/>
<itemData name="List: Strikethrough Text" defStyleNum="dsNormal" strikeOut="true"/>
<itemData name="List: Highlight Text" defStyleNum="dsAlert"/>
<itemData name="List: Link" defStyleNum="dsNormal" underline="true" spellChecking="false"/>
<itemData name="List: Checkbox" defStyleNum="dsVariable" spellChecking="false"/>
<itemData name="Comment" defStyleNum="dsComment"/>
<itemData name="Code" defStyleNum="dsInformation"/>
<itemData name="Fenced Code" defStyleNum="dsInformation" spellChecking="false"/>
<itemData name="Table" defStyleNum="dsPreprocessor"/>
<itemData name="Emoji" defStyleNum="dsSpecialChar" spellChecking="false"/>
<itemData name="Auto-Link" defStyleNum="dsOthers" spellChecking="false"/>
<itemData name="Link" defStyleNum="dsOthers" underline="true" spellChecking="false"/>
<itemData name="Mailto-Link" defStyleNum="dsOthers" spellChecking="false"/>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd"
<!DOCTYPE language
[
<!ENTITY space " ">
<!ENTITY end "&#59;">

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
<!DOCTYPE language>
<!--
This file is part of the KDE project
Copyright (C) 2001, 2002, 2003, 2004 Anders Lund <anders@alweb.dk>

View File

@@ -1,48 +1,54 @@
<!DOCTYPE language SYSTEM "language.dtd">
<!DOCTYPE language [
<!ENTITY varscope "(?:global|local|private|script|using|workflow|alias|env|function|variable)">
<!ENTITY varname "(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)">
]>
<language
name="PowerShell"
version="13"
kateversion="5.0"
version="14"
kateversion="5.79"
extensions="*.ps1;*.psm1;*.psd1"
section="Scripts"
author="Motoki Kashihara (motoki8791@gmail.com); Michael Lombardi (Michael.T.Lombardi@outlook.com)"
casesensitive="0"
license="MIT">
<highlighting>
<list name="keywords">
<item>Begin</item>
<list name="control-flow">
<item>Exit</item>
<item>Process</item>
<item>Break</item>
<item>Filter</item>
<item>Return</item>
<item>Catch</item>
<item>Finally</item>
<item>Sequence</item>
<item>Class</item>
<item>For</item>
<item>Switch</item>
<item>Continue</item>
<item>ForEach</item>
<item>Throw</item>
<item>Try</item>
<item>Do</item>
<item>If</item>
<item>Until</item>
<item>Else</item>
<item>ElseIf</item>
<item>While</item>
</list>
<list name="keywords">
<item>Begin</item>
<item>Filter</item>
<item>Sequence</item>
<item>Data</item>
<item>From</item>
<item>Trap</item>
<item>Define</item>
<item>Function</item>
<item>Try</item>
<item>Do</item>
<item>If</item>
<item>Until</item>
<item>DynamicParam</item>
<item>In</item>
<item>Using</item>
<item>Else</item>
<item>InlineScript</item>
<item>Var</item>
<item>ElseIf</item>
<item>Parallel</item>
<item>While</item>
<item>End</item>
<item>Param</item>
<item>Workflow</item>
@@ -75,69 +81,6 @@
<item>ulong</item>
<item>ushort</item>
</list>
<!-- TODO: Seems unused?!
<list name="operators">
<item>-split</item>
<item>-isplit</item>
<item>-csplit</item>
<item>-join</item>
<item>-is</item>
<item>-isnot</item>
<item>-as</item>
<item>-eq</item>
<item>-ieq</item>
<item>-ceq</item>
<item>-ne</item>
<item>-ine</item>
<item>-cne</item>
<item>-gt</item>
<item>-igt</item>
<item>-cgt</item>
<item>-ge</item>
<item>-ige</item>
<item>-cge</item>
<item>-lt</item>
<item>-ilt</item>
<item>-clt</item>
<item>-le</item>
<item>-ile</item>
<item>-cle</item>
<item>-like</item>
<item>-ilike</item>
<item>-clike</item>
<item>-notlike</item>
<item>-inotlike</item>
<item>-cnotlike</item>
<item>-match</item>
<item>-imatch</item>
<item>-cmatch</item>
<item>-notmatch</item>
<item>-inotmatch</item>
<item>-cnotmatch</item>
<item>-contains</item>
<item>-icontains</item>
<item>-ccontains</item>
<item>-notcontains</item>
<item>-inotcontains</item>
<item>-cnotcontains</item>
<item>-replace</item>
<item>-ireplace</item>
<item>-creplace</item>
<item>-band</item>
<item>-bor</item>
<item>-bxor</item>
<item>-and</item>
<item>-or</item>
<item>-xor</item>
<item>.</item>
<item>&amp;</item>
<item>=</item>
<item>+=</item>
<item>-=</item>
<item>*=</item>
<item>/=</item>
<item>%=</item>
</list>-->
<list name="cmdlets">
<item>Add-Content</item>
<item>Add-ADComputerServiceAccount</item>
@@ -847,11 +790,23 @@
<item>\%</item>
<item>\?</item>
</list>
<list name="special-variables">
<!-- https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-7.3#scope-modifiers -->
<item>$Global:</item>
<item>$Local:</item>
<item>$Private:</item>
<item>$Script:</item>
<item>$Using:</item>
<item>$Workflow:</item>
<item>$Alias:</item>
<item>$Env:</item>
<item>$Function:</item>
<item>$Variable:</item>
<item>$_</item>
<item>$True</item>
<item>$False</item>
<item>$Env</item>
<item>$Null</item>
<item>$^</item>
<item>$$</item>
@@ -873,75 +828,176 @@
<item>$Host</item>
<item>$OFS</item>
</list>
<!-- https://learn.microsoft.com/en-us/powershell/scripting/developer/help/comment-based-help-keywords?view=powershell-7.3 -->
<list name="comment-based-help">
<item>.SYNOPSIS</item>
<item>.DESCRIPTION</item>
<item>.PARAMETER</item>
<item>.EXAMPLE</item>
<item>.INPUTS</item>
<item>.OUTPUTS</item>
<item>.NOTES</item>
<item>.LINK</item>
<item>.COMPONENT</item>
<item>.ROLE</item>
<item>.FUNCTIONALITY</item>
<item>.FORWARDHELPTARGETNAME</item>
<item>.FORWARDHELPCATEGORY</item>
<item>.REMOTEHELPRUNSPACE</item>
<item>.EXTERNALHELP</item>
</list>
<contexts>
<context attribute="Normal Text" lineEndContext="#stay" name="Normal">
<DetectSpaces attribute="Normal Text"/>
<IncludeRules context="FindSpecialSymbol"/>
<DetectChar attribute="Symbol" context="Attribute" char="["/>
<IncludeRules context="FindSpecialOtherSymbol"/>
<keyword attribute="Keyword" context="#stay" String="keywords"/>
<keyword attribute="Data Type" context="#stay" String="types" />
<IncludeRules context="Cmdlet" />
<DetectChar attribute="String" context="String" char="&quot;"/>
<DetectChar attribute="String" context="StringQ" char="'"/>
<Detect2Chars attribute="HereString" context="HereStringer" char="@" char1="&quot;" beginRegion="StringRegion"/>
<keyword attribute="Control Flow" context="#stay" String="control-flow"/>
<keyword attribute="Function" context="#stay" String="cmdlets"/>
<IncludeRules context="FindIdentifiant"/>
<IncludeRules context="FindEscape"/>
</context>
<context attribute="Attribute" name="Attribute">
<DetectSpaces attribute="Normal Text"/>
<keyword attribute="Data Type" context="#stay" String="types"/>
<IncludeRules context="FindIdentifiant"/>
<DetectChar attribute="Symbol" context="#pop" char="]"/>
<IncludeRules context="FindSpecialSymbol"/>
<IncludeRules context="FindSpecialOtherSymbol"/>
<IncludeRules context="FindEscape"/>
</context>
<context attribute="Normal Text" name="FindSpecialSymbol">
<DetectChar attribute="String" context="StringDQ" char="&quot;"/>
<DetectChar attribute="String" context="StringSQ" char="'"/>
<StringDetect attribute="HereString" context="HereStringDQ" String="@&quot;" beginRegion="StringRegion"/>
<StringDetect attribute="HereString" context="HereStringSQ" String="@'" beginRegion="StringRegion"/>
<StringDetect attribute="Symbol" String="@("/>
<DetectChar attribute="Comment" context="Commentar 1" char="#"/>
<Detect2Chars attribute="Comment" context="Commentar 2" char="&lt;" char1="#" beginRegion="CommentRegion"/>
<StringDetect attribute="Comment" context="Commentar 2" String="&lt;#" beginRegion="CommentRegion"/>
<DetectChar attribute="Symbol" context="#stay" char="{" beginRegion="block1"/>
<DetectChar attribute="Symbol" context="#stay" char="}" endRegion="block1"/>
<RegExpr attribute="Keyword" context="#stay" String="\b\$(global|script)(?=\s+(:))"/>
<RegExpr attribute="Variable" context="#stay" String="\$+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*" />
<keyword attribute="Special Variable" context="#stay" String="special-variables"/>
<DetectChar attribute="Symbol" context="Member" char="." />
<AnyChar attribute="Symbol" context="#stay" String=":!%&amp;()+,-/*&lt;=&gt;?[]|~^&#59;"/>
<DetectChar attribute="Symbol" context="Member" char="."/>
</context>
<context attribute="String Char" lineEndContext="#stay" name="StringEscape">
<RegExpr attribute="String Char" String="`[`&quot;0abefnrtv\$]|`u\{[0-9A-Fa-f]+\}" context="#stay"/>
<context attribute="Normal Text" name="FindSpecialOtherSymbol">
<RegExpr attribute="Operator" String="(?&lt;=^|[\s(){}])-([ic]?(split|eq|ne|gt|ge|lt|le|like|notlike|match|notmatch|contains|notcontains|replace)|b?(and|or|xor)|join|not|isnot|is|as)(?=[\s(){}$]|$)"/>
<AnyChar attribute="Symbol" context="#stay" String=":!%&amp;()+,-/*&lt;=&gt;?[]|~^;"/>
<IncludeRules context="FindVariable"/>
</context>
<context attribute="String" lineEndContext="#pop" name="String">
<IncludeRules context="StringEscape"/>
<Detect2Chars attribute="Variable Substitution" context="#stay" char="$" char1="_" />
<Detect2Chars attribute="Variable Substitution" context="VarSubst" char="$" char1="{" />
<LineContinue attribute="String" context="#pop"/>
<context attribute="Normal Text" name="FindEscape">
<RegExpr attribute="String Char" String="`u\{[0-9A-Fa-f]+\}|`."/>
<RegExpr attribute="Escape" String="(?&lt;=\s)`"/>
</context>
<context attribute="Normal Text" name="FindVariable">
<StringDetect attribute="Variable Substitution" context="VarSubst" String="${" />
<StringDetect attribute="Symbol" context="VarCmd" String="$(" />
<RegExpr attribute="Variable" context="VariableScopeModifier" String="\$(?=&varscope;:)" insensitive="1"/>
<RegExpr attribute="Variable" String="\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*|[?^$])"/>
</context>
<context attribute="Normal Text" name="FindIdentifiant">
<RegExpr attribute="Number" context="NumericSuffix" String="\b(0b[01]+|0x[0-9a-fA-F]+|([0-9]+(\.[0-9]*)?|\.[0-9]+)(e([-+][0-9]+|[0-9]*))?)(?=(u?[ysl]|[und])?([kmgtp]b)?\b)" insensitive="1"/>
<RegExpr String="[-\w]+"/>
</context>
<context attribute="Numeric Suffix" name="NumericSuffix" fallthroughContext="#pop">
<DetectIdentifier attribute="Numeric Suffix" context="#pop"/>
</context>
<!-- $( -->
<context attribute="Normal Text" name="VarCmd">
<DetectChar attribute="Symbol" context="#pop" char=")"/>
<IncludeRules context="Normal"/>
</context>
<!-- ${ -->
<context attribute="Variable" name="VarSubst" fallthroughContext="VarNameSubst">
<DetectChar attribute="Variable Substitution" context="#pop" char="}"/>
<RegExpr attribute="Scope Modifier" context="VariableName" String="&varscope;:" insensitive="1"/>
</context>
<context attribute="Variable" name="VarNameSubst">
<DetectChar attribute="Variable Substitution" context="#pop#pop" char="}"/>
</context>
<!-- $xxx:varname -->
<context attribute="Normal Text" name="VariableScopeModifier" lineEndContext="#pop">
<DetectChar attribute="Symbol" context="#pop!VariableName" char=":"/>
<DetectIdentifier attribute="Scope Modifier"/>
</context>
<context attribute="Normal Text" name="VariableName" lineEndContext="#pop">
<RegExpr attribute="Variable" context="#pop" String="&varname;(:&varname;)*"/>
</context>
<context attribute="String" name="StringDQ">
<IncludeRules context="FindVariable"/>
<RegExpr attribute="String Char" String="`u\{[0-9A-Fa-f]+\}|`.|`$|&quot;&quot;"/>
<DetectChar attribute="String" context="#pop" char="&quot;"/>
</context>
<context attribute="String" lineEndContext="#pop" name="StringQ">
<IncludeRules context="StringEscape"/>
<LineContinue attribute="String" context="#pop"/>
<context attribute="String" name="StringSQ">
<StringDetect attribute="String Char" String="''"/>
<DetectChar attribute="String" context="#pop" char="'"/>
</context>
<context attribute="Variable Substitution" lineEndContext="#pop" name="VarSubst">
<DetectIdentifier />
<DetectChar attribute="Variable Substitution" context="#pop" char="}" />
<context attribute="HereString" lineEndContext="#stay" name="HereStringDQ">
<IncludeRules context="FindVariable"/>
<StringDetect attribute="HereString" context="#pop" String="&quot;@" endRegion="StringRegion" column="0"/>
</context>
<context attribute="HereString" lineEndContext="#stay" name="HereStringer">
<Detect2Chars attribute="HereString" context="#pop" char="&quot;" char1="@" endRegion="StringRegion"/>
<context attribute="HereString" lineEndContext="#stay" name="HereStringSQ">
<StringDetect attribute="HereString" context="#pop" String="'@" endRegion="StringRegion" column="0"/>
</context>
<context attribute="Normal Text" lineEndContext="#pop" name="Member" fallthrough="true" fallthroughContext="#pop">
<RegExpr attribute="Function" context="#pop" String="\b[_\w][_\w\d]*(?=[\s]*)" />
<context attribute="Normal Text" lineEndContext="#pop" name="Member" fallthroughContext="#pop">
<RegExpr attribute="Function" context="#pop" String="[_[:alpha:]]\w*" />
</context>
<context attribute="Comment" lineEndContext="#pop" name="Commentar 1">
<DetectSpaces />
<IncludeRules context="##Comments"/>
</context>
<context attribute="Comment" lineEndContext="#stay" name="Commentar 2">
<DetectSpaces />
<Detect2Chars attribute="Comment" context="#pop" char="#" char1="&gt;" endRegion="CommentRegion"/>
<!-- no delimiter except spaces -->
<keyword context="CommentHelp" String="comment-based-help" weakDeliminator="!%&amp;()*+,-./:;$lt;=>?[\]^{|}~" firstNonSpace="1" lookAhead="1" insensitive="0"/>
<IncludeRules context="##Comments"/>
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="Cmdlet">
<keyword attribute="Function" context="#stay" String="cmdlets"/>
<context attribute="Comment-Based Help Keyword" lineEndContext="#pop" name="CommentHelp">
<DetectChar attribute="Symbol" char="."/>
<DetectIdentifier attribute="Comment-Based Help Keyword" context="CommentHelpParam"/>
</context>
<context attribute="Comment-Based Help Paramater" lineEndContext="#pop#pop" name="CommentHelpParam">
</context>
</contexts>
<itemDatas>
<itemData name="Normal Text" defStyleNum="dsNormal" spellChecking="false"/>
<itemData name="Attribute" defStyleNum="dsAttribute" spellChecking="false"/>
<itemData name="Escape" defStyleNum="dsChar" spellChecking="false"/>
<itemData name="Keyword" defStyleNum="dsKeyword" spellChecking="false"/>
<itemData name="Control Flow" defStyleNum="dsControlFlow" spellChecking="false"/>
<itemData name="Function" defStyleNum="dsFunction" spellChecking="false"/>
<itemData name="Data Type" defStyleNum="dsDataType" spellChecking="false"/>
<itemData name="String" defStyleNum="dsString"/>
<itemData name="String Char" defStyleNum="dsChar" spellChecking="false"/>
<itemData name="HereString" defStyleNum="dsVerbatimString"/>
<itemData name="Number" defStyleNum="dsDecVal" spellChecking="false"/>
<itemData name="Numeric Suffix" defStyleNum="dsDataType" spellChecking="false"/>
<itemData name="Comment" defStyleNum="dsComment"/>
<itemData name="Comment-Based Help Keyword" defStyleNum="dsDocumentation" spellChecking="false"/>
<itemData name="Comment-Based Help Paramater" defStyleNum="dsSpecialString" spellChecking="false"/>
<itemData name="Symbol" defStyleNum="dsOperator" spellChecking="false"/>
<itemData name="Operator" defStyleNum="dsOperator" spellChecking="false"/>
<itemData name="Variable" defStyleNum="dsVariable" spellChecking="false"/>
<itemData name="Special Variable" defStyleNum="dsVariable" spellChecking="false" bold="1"/>
<itemData name="Variable Substitution" defStyleNum="dsString" spellChecking="false" />
<itemData name="Scope Modifier" defStyleNum="dsVariable" spellChecking="false" bold="1"/>
<itemData name="Variable Substitution" defStyleNum="dsPreprocessor" spellChecking="false"/>
</itemDatas>
</highlighting>
<general>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
<!DOCTYPE language>
<language name="QDoc Configuration"
version="3"
kateversion="5.0"

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
<!DOCTYPE language>
<!--
Ruby syntax highlighting definition for Kate.
@@ -31,7 +31,7 @@
<!-- Hold the "language" opening tag on a single line, as mentioned in "language.dtd". -->
<language name="Ruby" section="Scripts"
version="17" kateversion="5.0"
version="18" kateversion="5.0"
extensions="*.rb;*.rjs;*.rxml;*.xml.erb;*.js.erb;*.rake;Rakefile;Gemfile;*.gemspec;Vagrantfile"
mimetype="application/x-ruby"
style="ruby" indenter="ruby"
@@ -360,6 +360,7 @@
<Detect2Chars attribute="String" char="\" char1="\" context="#stay"/>
<Detect2Chars attribute="String" char="\" char1="&quot;" context="#stay"/>
<RegExpr attribute="Substitution" String="#@{1,2}" context="Short Subst"/>
<Detect2Chars attribute="Substitution" char="#" char1="$" context="Short Subst"/>
<Detect2Chars attribute="Substitution" char="#" char1="{" context="Subst"/>
<DetectChar char="&quot;" attribute="String" context="check_div_1_pop"/>
</context>
@@ -374,6 +375,7 @@
<Detect2Chars attribute="String" char="\" char1="\" context="#stay"/>
<Detect2Chars attribute="String" char="\" char1="`" context="#stay"/>
<RegExpr attribute="Substitution" String="#@{1,2}" context="Short Subst"/>
<Detect2Chars attribute="Substitution" char="#" char1="$" context="Short Subst"/>
<Detect2Chars attribute="Substitution" char="#" char1="{" context="Subst"/>
<DetectChar char="`" attribute="Command" context="check_div_1_pop"/>
</context>
@@ -387,6 +389,7 @@
<context name="RegEx 1" attribute="Regular Expression" lineEndContext="#stay">
<Detect2Chars attribute="Regular Expression" char="\" char1="/" context="#stay"/>
<RegExpr attribute="Substitution" String="#@{1,2}" context="Short Subst"/>
<Detect2Chars attribute="Substitution" char="#" char1="$" context="Short Subst"/>
<Detect2Chars attribute="Substitution" char="#" char1="{" context="Subst"/>
<RegExpr attribute="Regular Expression" String="/[uiomxn]*" context="check_div_1_pop"/>
</context>
@@ -401,6 +404,7 @@
<context name="Short Subst" attribute="Substitution" lineEndContext="#pop">
<!-- Check for e.g.: "#@var#@@xy" -->
<RegExpr attribute="Substitution" String="#@{1,2}" context="#stay"/>
<Detect2Chars attribute="Substitution" char="#" char1="$" context="#stay"/>
<RegExpr attribute="Substitution" String="\w(?!\w)" context="#pop"/>
</context>
@@ -459,6 +463,7 @@
<!-- rules for heredoc types -->
<context name="heredoc_rules" attribute="Normal Text" lineEndContext="#stay">
<RegExpr attribute="Substitution" String="#@{1,2}" context="Short Subst"/>
<Detect2Chars attribute="Substitution" char="#" char1="$" context="Short Subst"/>
<Detect2Chars attribute="Substitution" char="#" char1="{" context="Subst"/>
</context>
@@ -595,6 +600,7 @@
<context name="dq_string_rules" attribute="String" lineEndContext="#stay" >
<Detect2Chars attribute="String" char="\" char1="\" context="#stay"/>
<RegExpr attribute="Substitution" String="#@{1,2}" context="Short Subst"/>
<Detect2Chars attribute="Substitution" char="#" char1="$" context="Short Subst"/>
<Detect2Chars attribute="Substitution" char="#" char1="{" context="Subst"/>
</context>
@@ -789,6 +795,7 @@
<context name="shell_command_rules" attribute="Command" lineEndContext="#stay" >
<Detect2Chars attribute="Command" char="\" char1="\" context="#stay"/>
<RegExpr attribute="Substitution" String="#@{1,2}" context="Short Subst"/>
<Detect2Chars attribute="Substitution" char="#" char1="$" context="Short Subst"/>
<Detect2Chars attribute="Substitution" char="#" char1="{" context="Subst"/>
</context>
@@ -855,6 +862,7 @@
<context name="regexpr_rules" attribute="Regular Expression" lineEndContext="#stay" >
<Detect2Chars attribute="Regular Expression" char="\" char1="\" context="#stay"/>
<RegExpr attribute="Substitution" String="#@{1,2}" context="Short Subst"/>
<Detect2Chars attribute="Substitution" char="#" char1="$" context="Short Subst"/>
<Detect2Chars attribute="Substitution" char="#" char1="{" context="Subst"/>
</context>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
<!DOCTYPE language>
<!-- ***** THIS FILE WAS GENERATED BY A SCRIPT - DO NOT EDIT *****
cd data/generators
# increase version of spdx-comments.xml.tpl then

View File

@@ -0,0 +1,183 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language
[
<!ENTITY more "(_[0-9]++)*+">
<!ENTITY int "(0|[1-9][0-9]*+&more;)">
<!ENTITY frac "\.[0-9]+&more;">
<!ENTITY exp "[eE][+-]?[0-9]+&more;">
<!ENTITY offset "[+-][0-9][0-9]:[0-9][0-9]">
<!ENTITY time "[0-9][0-9]:[0-9][0-9]:[0-9][0-9](\.[0-9]+)?">
<!ENTITY datetime "[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]([T ]&time;(&offset;|Z)?)?|&time;">
]>
<!-- https://github.com/toml-lang/toml -->
<!-- https://toml.io/en/v1.0.0 -->
<language
name="TOML"
section="Configuration"
extensions="Cargo.lock;*.toml;*.rc;*.conf;*.cfg;*.cf;*.cnf;*.ini;mirrorlist"
mimetype="text/x-toml;application/toml"
version="13"
kateversion="5.0"
author="flying-sheep@web.de"
license="LGPLv2+"
priority="-1"
>
<highlighting>
<list name="bools">
<item>true</item>
<item>false</item>
</list>
<contexts>
<context attribute="Error" lineEndContext="#stay" name="Toml">
<DetectSpaces attribute="Whitespace"/>
<Detect2Chars attribute="TableHeader" context="NestedTableHeader" char="[" char1="[" endRegion="Table"/>
<DetectChar attribute="TableHeader" context="TableHeader" char="[" endRegion="Table"/>
<DetectChar attribute="Assignment" context="Value" char="="/>
<DetectChar char="#" attribute="Comment" context="Comment"/>
<IncludeRules context="FindKey"/>
</context>
<context attribute="Key" lineEndContext="#stay" name="FindKey">
<DetectChar attribute="Key" char="."/>
<RegExpr attribute="Key" context="#stay" String="[A-Za-z0-9_-]+"/>
<DetectChar attribute="Key" context="QuotedKey" char="&quot;"/>
<DetectChar attribute="Key" context="LitQuotedKey" char="'"/>
</context>
<!-- table headers -->
<context attribute="TableHeader" fallthrough="true" fallthroughContext="#pop" lineEndContext="#pop" name="TableHeader">
<DetectChar attribute="TableHeader" context="#pop" char="]" beginRegion="Table"/>
<IncludeRules context="TableHeaderCommon"/>
</context>
<context attribute="TableHeader" fallthrough="true" fallthroughContext="#pop" lineEndContext="#pop" name="NestedTableHeader">
<Detect2Chars attribute="TableHeader" context="#pop" char="]" char1="]" beginRegion="Table"/>
<IncludeRules context="TableHeaderCommon"/>
</context>
<context attribute="TableHeader" lineEndContext="#pop" name="TableHeaderCommon">
<DetectSpaces attribute="Whitespace"/>
<DetectChar attribute="TableHeader" char="."/>
<RegExpr attribute="TableHeader" context="#stay" String="[A-Za-z0-9_-]+"/>
<DetectChar attribute="TableHeader" context="QuotedKey" char="&quot;"/>
<DetectChar attribute="TableHeader" context="LitQuotedKey" char="'"/>
</context>
<!-- values -->
<context attribute="Error" lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop" name="Value">
<DetectSpaces attribute="Whitespace"/>
<WordDetect attribute="Boolean true" context="#pop" String="true"/>
<WordDetect attribute="Boolean false" context="#pop" String="false"/>
<StringDetect attribute="String" context="#pop!MultilineString" String="&quot;&quot;&quot;"/>
<DetectChar attribute="String" context="#pop!String" char="&quot;"/>
<StringDetect attribute="String" context="#pop!LitMultilineString" String="'''"/>
<DetectChar attribute="String" context="#pop!LitString" char="'"/>
<DetectChar attribute="Array" context="#pop!Array" char="["/>
<DetectChar attribute="InlineTable" context="#pop!InlineTable" char="{"/>
<RegExpr attribute="Date" context="#pop" String="&datetime;"/>
<RegExpr attribute="Int" context="#pop" String="[+-]?(0x[0-9a-fA-F]+(_[0-9a-fA-F]+)*|0o[0-7]+(_[0-7]+)*|0b[01]+(_[01]+)*|&int;(?!(\.|[eE][+-]?)[0-9]))"/>
<RegExpr attribute="Float" context="#pop" String="[+-]?(&int;(&frac;(&exp;)?|&exp;)|inf|nan)"/>
</context>
<context attribute="Comment" lineEndContext="#pop" name="Comment">
<DetectSpaces/>
<IncludeRules context="##Comments"/>
<DetectIdentifier/>
</context>
<!-- Quoted keys and Strings-->
<context attribute="Key" lineEndContext="#pop" name="QuotedKey">
<DetectChar attribute="Key" context="#pop" char="&quot;"/>
<IncludeRules context="FindEscapedChar"/>
</context>
<context attribute="String" lineEndContext="#pop" name="String">
<DetectChar attribute="String" context="#pop" char="&quot;"/>
<IncludeRules context="FindEscapedChar"/>
</context>
<context attribute="String" lineEndContext="#stay" name="MultilineString">
<StringDetect attribute="String" context="#pop" String="&quot;&quot;&quot;&quot;&quot;"/>
<StringDetect attribute="String" context="#pop" String="&quot;&quot;&quot;&quot;"/>
<StringDetect attribute="String" context="#pop" String="&quot;&quot;&quot;"/>
<LineContinue attribute="Escape" context="#stay"/>
<IncludeRules context="FindEscapedChar"/>
</context>
<context attribute="String" lineEndContext="#pop" name="FindEscapedChar">
<RegExpr attribute="Escape" String="\\[btnfr&quot;\\]|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}" context="#stay"/>
<RegExpr attribute="Error" String="\\[uU][0-9a-fA-F]*|\\." context="#stay"/>
</context>
<context attribute="Key" lineEndContext="#pop" name="LitQuotedKey">
<DetectChar attribute="Key" context="#pop" char="'"/>
</context>
<context attribute="LitString" lineEndContext="#pop" name="LitString">
<DetectChar attribute="String" context="#pop" char="'"/>
</context>
<context attribute="LitString" lineEndContext="#stay" name="LitMultilineString">
<StringDetect attribute="String" context="#pop" String="'''''"/>
<StringDetect attribute="String" context="#pop" String="''''"/>
<StringDetect attribute="String" context="#pop" String="'''"/>
</context>
<!-- Arrays -->
<context attribute="Array" lineEndContext="#stay" name="Array" fallthrough="true" fallthroughContext="InArray">
<DetectSpaces attribute="Whitespace"/>
<DetectChar context="#pop" attribute="Array" char="]"/>
<DetectChar attribute="Comment" context="Comment" char="#"/>
<DetectChar context="InArray" attribute="NextEntry" char=","/>
</context>
<context attribute="Error" lineEndContext="#stay" name="InArray">
<DetectChar context="#pop#pop" attribute="Array" char="]"/>
<DetectChar context="#stay" attribute="Error" char=","/>
<DetectChar attribute="Comment" context="Comment" char="#"/>
<IncludeRules context="Value"/>
</context>
<context attribute="InlineTable" lineEndContext="#stay" name="InlineTable">
<DetectChar attribute="Assignment" context="Value" char="="/>
<DetectChar char="#" attribute="Comment" context="Comment"/>
<DetectChar context="#pop" attribute="InlineTable" char="}"/>
<DetectChar context="#stay" attribute="NextEntry" char=","/>
<IncludeRules context="FindKey"/>
</context>
</contexts>
<itemDatas>
<itemData name="Whitespace" defStyleNum="dsNormal"/>
<itemData name="Key" defStyleNum="dsDataType"/>
<itemData name="TableHeader" defStyleNum="dsKeyword"/>
<itemData name="Assignment" defStyleNum="dsOperator"/>
<itemData name="Comment" defStyleNum="dsComment"/>
<itemData name="Date" defStyleNum="dsBaseN"/>
<itemData name="Float" defStyleNum="dsFloat"/>
<itemData name="Int" defStyleNum="dsDecVal"/>
<itemData name="Boolean true" defStyleNum="dsConstant"/>
<itemData name="Boolean false" defStyleNum="dsConstant"/>
<itemData name="String" defStyleNum="dsString"/>
<itemData name="LitString" defStyleNum="dsVerbatimString"/>
<itemData name="Escape" defStyleNum="dsSpecialChar"/>
<itemData name="Array" defStyleNum="dsOperator"/>
<itemData name="InlineTable" defStyleNum="dsOperator"/>
<itemData name="NextEntry" defStyleNum="dsOperator"/>
<itemData name="Error" defStyleNum="dsError"/>
</itemDatas>
</highlighting>
<general>
<comments>
<comment name="singleLine" start="#" position="afterwhitespace"/>
</comments>
</general>
</language>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
<!DOCTYPE language>
<language name="Valgrind Suppression" section="Other" extensions="*.supp;" mimetype="" version="4" kateversion="5.0" author="Milian Wolff (mail@milianw.de)" license="LGPL">
<highlighting>
<contexts>

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd"
<!DOCTYPE language
[
<!-- names must start with a letter, ideogram or underscore. \w matches any
word character *or* a number, hence the lookahead -->
<!ENTITY name "(?![0-9])[\w_:][\w.:_-]*">
<!ENTITY entref "&amp;(?:#[0-9]+|#[xX][0-9A-Fa-f]+|&name;);">
]>
<language name="XML" version="18" 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;application/vnd.oasis.opendocument.text-flat-xml;application/vnd.oasis.opendocument.graphics-flat-xml;application/vnd.oasis.opendocument.presentation-flat-xml;application/vnd.oasis.opendocument.spreadsheet-flat-xml;application/gpx+xml" casesensitive="1" indenter="xml" author="Wilbert Berendsen (wilbert@kde.nl)" license="LGPL">
<language name="XML" version="20" kateversion="5.0" section="Markup" extensions="*.page;*.docbook;*.xml;*ui.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;application/vnd.oasis.opendocument.text-flat-xml;application/vnd.oasis.opendocument.graphics-flat-xml;application/vnd.oasis.opendocument.presentation-flat-xml;application/vnd.oasis.opendocument.spreadsheet-flat-xml;application/gpx+xml" casesensitive="1" indenter="xml" author="Wilbert Berendsen (wilbert@kde.nl)" license="LGPL">
<highlighting>
<contexts>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
<!DOCTYPE language>
<!--
========================================================================
YACC.XML supports syntax highlighting for Yacc/Bison source under Kate.

View File

@@ -0,0 +1,642 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language
[
<!ENTITY null "(?:null|Null|NULL|~)">
<!ENTITY bool "(?:y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF)">
<!ENTITY int "(?:0|[\-\+]?[1-9][0-9_]*)">
<!ENTITY intOther "[\-\+]?0(?:x_*[0-9a-fA-F][0-9a-fA-F_]*|o?_*[0-7][0-7_]*|b_*[01][01_]*)"> <!-- Hex, Octal, Binary -->
<!ENTITY intBase60 "[\-\+]?[1-9][0-9_]*(?:\:[0-5]?[0-9])+">
<!ENTITY allInt "(?:&intBase60;|&intOther;|&int;)">
<!ENTITY float "[\-\+]?(?:[0-9][0-9_]*\.[0-9\._]*|\._*[0-9][0-9\._]*)(?:[eE][\-\+]?[0-9]+)?">
<!ENTITY floatExp "[\-\+]?[0-9][0-9_]*[eE][\-\+]?[0-9]+">
<!ENTITY floatBase60 "[\-\+]?[0-9][0-9_]*(?:\:[0-5]?[0-9])+\.[0-9_]*">
<!ENTITY inf "[\-\+]?\.(?:inf|Inf|INF)\b">
<!ENTITY nan "\.(?:nan|NaN|NAN)\b">
<!ENTITY allFloat "(?:&float;|&floatExp;|&floatBase60;|&inf;|&nan;)">
<!ENTITY endValue "(?:\s*$|\s+#)">
<!ENTITY endValueInline "\s*[:,\[\]\{\}]">
<!ENTITY space "[ ]">
<!-- Key quoted -->
<!ENTITY keyDQ "&quot;(?:\\.|[^&quot;])+&quot;\s*">
<!ENTITY keySQ "'(?:[^']|'')+'\s*">
<!-- Literal/folded operator -->
<!ENTITY literalOp "[\|&gt;][\-\+]?">
<!-- Key after "?" or "-", used to detect literal/folded operator -->
<!ENTITY keyAfterOp "(?:[^&quot;'#\-\?\s][^:#]*|\-(?:[^\s:#][^:#]*)?|&keyDQ;|&keySQ;)">
<!ENTITY dataTypes "!!\S+">
<!ENTITY alias "&amp;\S+">
<!ENTITY reference "\*\S+">
<!ENTITY dpointsHashAttrPreInline1 "[^\s&quot;'#\-,\}\s][^:#,\}]*(?=\:(?:\s|$))">
<!ENTITY dpointsHashAttrPreInline2 "\-(?:[^\s:#,\}][^:#,\}]*)?(?=\:(?:\s|$))">
<!ENTITY dpointsHashAttrPreInline3 "&keyDQ;(?=\:(?:\s|$))">
<!ENTITY dpointsHashAttrPreInline4 "&keySQ;(?=\:(?:\s|$))">
<!ENTITY dpointsListAttrPreInline1 "[^&quot;'#\-,\]\s][^:#,\]]*(?=\:(?:\s|$))">
<!ENTITY dpointsListAttrPreInline2 "\-(?:[^\s:#,\]][^:#,\]]*)?(?=\:(?:\s|$))">
<!ENTITY dpointsListAttrPreInline3 "&keyDQ;(?=\:(?:\s|$))">
<!ENTITY dpointsListAttrPreInline4 "&keySQ;(?=\:(?:\s|$))">
<!ENTITY dpointsAttrPre1 "[^&quot;'#\-\s][^:#]*(?=\:(?:\s|$))">
<!ENTITY dpointsAttrPre2 "\-(?:[^\s:#][^:#]*)?(?=\:(?:\s|$))">
<!ENTITY dpointsAttrPre3 "&keyDQ;(?=\:(?:\s|$))">
<!ENTITY dpointsAttrPre4 "&keySQ;(?=\:(?:\s|$))">
]>
<!-- Author: Dr Orlovsky MA <maxim@orlovsky.info> //-->
<!-- Modifications (YAML 1.2), values & support for literal/folded style:
Nibaldo González S. <nibgonz@gmail.com>
These modifications are under the MIT license. //-->
<language name="YAML" version="11" kateversion="5.0" section="Markup"
extensions="*.yaml;*.yml" mimetype="text/yaml" priority="9"
author="Dr Orlovsky MA (dr.orlovsky@gmail.com), Nibaldo González (nibgonz@gmail.com)" license="LGPL">
<highlighting>
<contexts>
<context attribute="Attribute" lineEndContext="#stay" name="normal" >
<StringDetect attribute="Document Header" context="header" String="---" column="0"/>
<RegExpr attribute="End of Document" context="EOD" String="^\.\.\.$" column="0"/>
<DetectChar attribute="Directive" context="directive" char="%" column="0"/>
<RegExpr attribute="Comment" context="comment" String="(?:^|\s+)#" />
<!-- Literal/Folded Style -->
<IncludeRules context="find-literal-block" />
<RegExpr attribute="Operator" firstNonSpace="true" context="dash" String="\-(?=\s|$)" />
<DetectChar attribute="Operator" firstNonSpace="true" context="mapping-key" char="?" />
<DetectChar attribute="Operator" firstNonSpace="true" context="list" char="[" beginRegion="List" />
<DetectChar attribute="Operator" firstNonSpace="true" context="hash" char="{" beginRegion="Hash" />
<RegExpr attribute="Data Types" firstNonSpace="true" context="after-data" String="&dataTypes;" />
<RegExpr attribute="Alias" firstNonSpace="true" context="after-data" String="&alias;" />
<RegExpr attribute="Reference" firstNonSpace="true" context="after-data" String="&reference;" />
<RegExpr attribute="Key" context="dpoints-attribute-pre" String="&dpointsAttrPre1;|&dpointsAttrPre2;|&dpointsAttrPre3;|&dpointsAttrPre4;"/>
<RegExpr attribute="Key Points Operator" context="attribute-pre" String=":(?=\s|$)"/>
<DetectChar attribute="String" firstNonSpace="true" context="string" char="'" beginRegion="String" />
<DetectChar attribute="String" firstNonSpace="true" context="stringx" char="&quot;" beginRegion="String" />
<IncludeRules context="values-firstnonspace" />
<DetectSpaces/>
</context>
<context attribute="Normal Text" lineEndContext="#pop" name="mapping-key" fallthrough="true" fallthroughContext="#pop">
<RegExpr attribute="Comment" context="#pop!comment" String="(?:^|\s+)#" />
<DetectSpaces />
<RegExpr attribute="Operator" context="#pop!dash" String="\-(?=\s|$)" />
<RegExpr attribute="Data Types" context="#pop!after-data" String="&dataTypes;" />
<RegExpr attribute="Alias" context="#pop!after-data" String="&alias;" />
<RegExpr attribute="Reference" context="#pop!after-data" String="&reference;" />
<DetectChar attribute="Operator" context="#pop!list" char="[" beginRegion="List" />
<DetectChar attribute="Operator" context="#pop!hash" char="{" beginRegion="Hash" />
<DetectChar attribute="String" context="#pop!string" char="'" beginRegion="String" />
<DetectChar attribute="String" context="#pop!stringx" char="&quot;" beginRegion="String" />
</context>
<context attribute="Normal Text" lineEndContext="#pop" name="dash" fallthrough="true" fallthroughContext="#pop">
<RegExpr attribute="Comment" context="comment" String="(?:^|\s+)#" />
<DetectSpaces/>
<RegExpr attribute="Data Types" context="#stay" String="&dataTypes;" />
<RegExpr attribute="Alias" context="#stay" String="&alias;" />
<RegExpr attribute="Reference" context="#stay" String="&reference;" />
<IncludeRules context="values" />
<DetectChar attribute="Operator" context="#pop!mapping-key" char="?" />
<RegExpr attribute="Operator" context="#stay" String="\-(?=\s|$)" />
<DetectChar attribute="Operator" context="#pop!list" char="[" beginRegion="List" />
<DetectChar attribute="Operator" context="#pop!hash" char="{" beginRegion="Hash" />
<DetectChar attribute="String" context="#pop!string" char="'" beginRegion="String" />
<DetectChar attribute="String" context="#pop!stringx" char="&quot;" beginRegion="String" />
</context>
<!-- Highlight lists, hashes and strings after a data type, reference or alias -->
<context attribute="Normal Text" lineEndContext="#pop" name="after-data" fallthrough="true" fallthroughContext="#pop">
<RegExpr attribute="Comment" context="#pop!comment" String="(?:^|\s+)#" />
<DetectSpaces />
<RegExpr attribute="Data Types" context="#stay" String="&dataTypes;" />
<RegExpr attribute="Alias" context="#stay" String="&alias;" />
<RegExpr attribute="Reference" context="#stay" String="&reference;" />
<DetectChar attribute="Operator" context="list" char="[" beginRegion="List" />
<DetectChar attribute="Operator" context="hash" char="{" beginRegion="Hash" />
<DetectChar attribute="String" context="string" char="'" beginRegion="String" />
<DetectChar attribute="String" context="stringx" char="&quot;" beginRegion="String" />
</context>
<context attribute="Document Header" lineEndContext="#pop" name="header">
<RegExpr attribute="Comment" context="comment" String="(?:^|\s+)#" />
<RegExpr attribute="Literal/Folded Operator" context="header-literal-operator" String="\s&literalOp;(?=&endValue;)" lookAhead="true" />
</context>
<context attribute="Document Header" lineEndContext="#pop#pop" name="header-literal-operator" fallthrough="true" fallthroughContext="#pop">
<DetectSpaces />
<RegExpr attribute="Literal/Folded Operator" context="#pop#pop!literal-block-simple" String="&literalOp;" beginRegion="Literal" />
</context>
<context attribute="End of Document" lineEndContext="#stay" name="EOD">
</context>
<context attribute="Directive" lineEndContext="#pop" name="directive">
</context>
<context attribute="Attribute" lineEndContext="#pop#pop" name="attribute">
<RegExpr attribute="Comment" context="comment" String="(?:^|\s+)#" />
</context>
<context attribute="Attribute" lineEndContext="#stay" name="list-attribute-inline">
<AnyChar attribute="Operator" context="#pop#pop" lookAhead="true" String=",]" />
<RegExpr attribute="Comment" context="comment" String="(?:^|\s+)#" />
</context>
<context attribute="Attribute" lineEndContext="#stay" name="hash-attribute-inline">
<AnyChar attribute="Operator" context="#pop#pop" lookAhead="true" String=",}" />
<RegExpr attribute="Comment" context="comment" String="(?:^|\s+)#" />
</context>
<!-- Attribute -->
<context attribute="Attribute" lineEndContext="#pop" name="dpoints-attribute-pre" fallthrough="true" fallthroughContext="#pop!attribute-pre">
<DetectChar attribute="Key Points Operator" context="#pop!attribute-pre" char=":" /> <!-- Highlight two points after Key -->
</context>
<context attribute="Attribute" lineEndContext="#pop" name="attribute-pre" fallthrough="true" fallthroughContext="attribute">
<RegExpr attribute="Comment" context="comment" String="(?:^|\s+)#" />
<DetectSpaces/>
<DetectChar attribute="Operator" context="#stay" char="?" />
<RegExpr attribute="Data Types" context="#stay" String="&dataTypes;" />
<DetectChar attribute="Operator" context="list" char="[" beginRegion="List" />
<DetectChar attribute="Operator" context="hash" char="{" beginRegion="Hash" />
<DetectChar attribute="String" context="attribute-string" char="'" beginRegion="String" />
<DetectChar attribute="String" context="attribute-stringx" char="&quot;" beginRegion="String" />
<RegExpr attribute="Alias" context="#stay" String="&alias;(?=\s+[\[\{])" />
<RegExpr attribute="Reference" context="#stay" String="&reference;(?=\s+[\[\{])" />
<RegExpr attribute="Alias" context="attribute" String="&alias;" />
<RegExpr attribute="Reference" context="attribute" String="&reference;" />
<IncludeRules context="values" />
<RegExpr attribute="Literal/Folded Operator" context="#stay" String="&literalOp;(?=&endValue;)" />
</context>
<context attribute="Attribute" lineEndContext="#pop" name="default-attribute-pre-inline">
<RegExpr attribute="Comment" context="comment" String="(?:^|\s+)#" />
<DetectSpaces/>
<DetectChar attribute="Operator" context="#stay" char="?" />
<RegExpr attribute="Data Types" context="#stay" String="&dataTypes;" />
<DetectChar attribute="Operator" context="list" char="[" beginRegion="List" />
<DetectChar attribute="Operator" context="hash" char="{" beginRegion="Hash" />
<DetectChar attribute="String" context="attribute-string-inline" char="'" beginRegion="String" />
<DetectChar attribute="String" context="attribute-stringx-inline" char="&quot;" beginRegion="String" />
<RegExpr attribute="Alias" context="#stay" String="&alias;(?=\s+[\[\{])" />
<RegExpr attribute="Reference" context="#stay" String="&reference;(?=\s+[\[\{])" />
</context>
<!-- Attribute Inline, Within List -->
<context attribute="Attribute" lineEndContext="#pop" name="dpoints-list-attribute-pre-inline" fallthrough="true" fallthroughContext="#pop!list-attribute-pre-inline">
<DetectChar attribute="Key Points Operator" context="#pop!list-attribute-pre-inline" char=":" /> <!-- Highlight two points after Key -->
</context>
<context attribute="Attribute" lineEndContext="#pop" name="list-attribute-pre-inline" fallthrough="true" fallthroughContext="list-attribute-inline">
<IncludeRules context="default-attribute-pre-inline" />
<RegExpr attribute="Alias" context="list-attribute-inline" String="&alias;" />
<RegExpr attribute="Reference" context="list-attribute-inline" String="&reference;" />
<AnyChar attribute="Operator" context="#pop" lookAhead="true" String=",]" />
<IncludeRules context="values-inline" />
</context>
<!-- Attribute Inline, Within Hash -->
<context attribute="Attribute" lineEndContext="#pop" name="dpoints-hash-attribute-pre-inline" fallthrough="true" fallthroughContext="#pop!hash-attribute-pre-inline">
<DetectChar attribute="Key Points Operator" context="#pop!hash-attribute-pre-inline" char=":" /> <!-- Highlight two points after Key -->
</context>
<context attribute="Attribute" lineEndContext="#pop" name="hash-attribute-pre-inline" fallthrough="true" fallthroughContext="hash-attribute-inline">
<IncludeRules context="default-attribute-pre-inline" />
<RegExpr attribute="Alias" context="hash-attribute-inline" String="&alias;" />
<RegExpr attribute="Reference" context="hash-attribute-inline" String="&reference;" />
<AnyChar attribute="Operator" context="#pop" lookAhead="true" String=",}" />
<IncludeRules context="values-inline" />
</context>
<!-- List -->
<!-- Context "find-values-list" highlights values and then sends to "list-element" -->
<context attribute="List" lineEndContext="#stay" name="list" fallthrough="true" fallthroughContext="#pop!find-values-list" noIndentationBasedFolding="true">
<RegExpr attribute="Comment" context="comment" String="(?:^|\s+)#" />
<DetectSpaces />
<DetectChar attribute="Operator" context="#pop!find-values-list" char="?" />
</context>
<context attribute="List" lineEndContext="#stay" name="list-element" noIndentationBasedFolding="true">
<RegExpr attribute="Comment" context="comment" String="(?:^|\s+)#" />
<DetectChar attribute="Operator" context="#pop" char="]" endRegion="List" />
<DetectChar attribute="Operator" context="list" char="[" beginRegion="List" />
<DetectChar attribute="Operator" context="hash" char="{" beginRegion="Hash" />
<RegExpr attribute="Key" context="dpoints-list-attribute-pre-inline" String="&dpointsListAttrPreInline1;|&dpointsListAttrPreInline2;|&dpointsListAttrPreInline3;|&dpointsListAttrPreInline4;"/>
<RegExpr attribute="Key Points Operator" context="list-attribute-pre-inline" String=":(?=\s|$)" firstNonSpace="true" />
<RegExpr attribute="Data Types" context="#stay" String="&dataTypes;" />
<RegExpr attribute="Alias" context="#stay" String="&alias;" />
<RegExpr attribute="Reference" context="#stay" String="&reference;" />
<DetectChar attribute="String" context="string" char="'" beginRegion="String" />
<DetectChar attribute="String" context="stringx" char="&quot;" beginRegion="String" />
<DetectChar attribute="Operator" context="#pop!list" char="," />
<IncludeRules context="values-list" />
</context>
<!-- Hash -->
<context attribute="Hash" lineEndContext="#stay" name="hash" fallthrough="true" fallthroughContext="#pop!hash-element" noIndentationBasedFolding="true">
<RegExpr attribute="Comment" context="comment" String="(?:^|\s+)#" />
<DetectSpaces />
<DetectChar attribute="Operator" context="#pop!hash-element" char="?" />
</context>
<context attribute="Hash" lineEndContext="#stay" name="hash-element" noIndentationBasedFolding="true">
<RegExpr attribute="Comment" context="comment" String="(?:^|\s+)#" />
<DetectSpaces/>
<RegExpr attribute="Key" context="dpoints-hash-attribute-pre-inline" String="&dpointsHashAttrPreInline1;|&dpointsHashAttrPreInline2;|&dpointsHashAttrPreInline3;|&dpointsHashAttrPreInline4;"/>
<RegExpr attribute="Key Points Operator" context="hash-attribute-pre-inline" String=":(?=\s|$)"/>
<DetectChar attribute="Operator" context="#pop" char="}" endRegion="Hash" />
<DetectChar attribute="Operator" context="#pop!hash" char="," />
<!-- This improves highlighting in keys with multiple lines -->
<RegExpr attribute="Data Types" context="#stay" String="&dataTypes;" />
<RegExpr attribute="Alias" context="#stay" String="&alias;" />
<RegExpr attribute="Reference" context="#stay" String="&reference;" />
<DetectChar attribute="String" context="string" char="'" beginRegion="String" />
<DetectChar attribute="String" context="stringx" char="&quot;" beginRegion="String" />
</context>
<!-- Strings -->
<context attribute="String" lineEndContext="#stay" name="attribute-string" noIndentationBasedFolding="true">
<DetectIdentifier />
<IncludeRules context="escaped-char-singleq" />
<DetectChar attribute="String" context="attribute-end" char="'" endRegion="String" />
</context>
<context attribute="String" lineEndContext="#stay" name="attribute-stringx" noIndentationBasedFolding="true">
<DetectIdentifier />
<IncludeRules context="escaped-char-doubleq" />
<DetectChar attribute="String" context="attribute-end" char="&quot;" endRegion="String" />
</context>
<context attribute="String" lineEndContext="#stay" name="attribute-string-inline" noIndentationBasedFolding="true">
<DetectIdentifier />
<IncludeRules context="escaped-char-singleq" />
<DetectChar attribute="String" context="attribute-end-inline" char="'" endRegion="String" />
</context>
<context attribute="String" lineEndContext="#stay" name="attribute-stringx-inline" noIndentationBasedFolding="true">
<DetectIdentifier />
<IncludeRules context="escaped-char-doubleq" />
<DetectChar attribute="String" context="attribute-end-inline" char="&quot;" endRegion="String" />
</context>
<context attribute="Error" lineEndContext="#pop#pop#pop" name="attribute-end">
<RegExpr attribute="Comment" context="comment" String="(?:^|\s+)#" />
<DetectSpaces attribute="Normal Text" context="#stay"/>
</context>
<context attribute="Error" lineEndContext="#pop#pop#pop" name="attribute-end-inline">
<RegExpr attribute="Comment" context="comment" String="(?:^|\s+)#" />
<DetectSpaces attribute="Normal Text" context="#stay"/>
<AnyChar context="#pop#pop#pop" lookAhead="true" String="}],"/>
</context>
<context attribute="String" lineEndContext="#stay" name="string" noIndentationBasedFolding="true">
<DetectIdentifier />
<IncludeRules context="escaped-char-singleq" />
<DetectChar attribute="String" context="#pop" char="'" endRegion="String" />
</context>
<context attribute="String" lineEndContext="#stay" name="stringx" noIndentationBasedFolding="true">
<DetectIdentifier />
<IncludeRules context="escaped-char-doubleq" />
<DetectChar attribute="String" context="#pop" char="&quot;" endRegion="String" />
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="escaped-char-doubleq">
<RegExpr attribute="Escaped Character" context="#stay" String="\\(?:[\s0abtnvfre&quot;/\\N_Lp]|x[a-fA-F0-9]{2}|u[a-fA-F0-9]{4}|U[a-fA-F0-9]{8})"/>
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="escaped-char-singleq">
<Detect2Chars attribute="Escaped Character" context="#stay" char="'" char1="'" />
</context>
<context attribute="Comment" lineEndContext="#pop" name="comment">
<DetectSpaces />
<IncludeRules context="##Comments" />
</context>
<!-- Values -->
<context attribute="Normal Text" lineEndContext="#stay" name="values">
<RegExpr attribute="Null" context="#stay" String="&null;(?=&endValue;)"/>
<RegExpr attribute="Boolean" context="#stay" String="&bool;(?=&endValue;)"/>
<RegExpr attribute="Float" context="#stay" String="&allFloat;(?=&endValue;)"/>
<RegExpr attribute="Integer" context="#stay" String="&allInt;(?=&endValue;)"/>
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="values-firstnonspace">
<RegExpr attribute="Null" firstNonSpace="true" context="#stay" String="&null;(?=&endValue;)"/>
<RegExpr attribute="Boolean" firstNonSpace="true" context="#stay" String="&bool;(?=&endValue;)"/>
<RegExpr attribute="Float" firstNonSpace="true" context="#stay" String="&allFloat;(?=&endValue;)"/>
<RegExpr attribute="Integer" firstNonSpace="true" context="#stay" String="&allInt;(?=&endValue;)"/>
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="values-inline">
<RegExpr attribute="Null" context="#stay" String="&null;(?=&endValueInline;|&endValue;)"/>
<RegExpr attribute="Boolean" context="#stay" String="&bool;(?=&endValueInline;|&endValue;)"/>
<RegExpr attribute="Float" context="#stay" String="&allFloat;(?=&endValueInline;|&endValue;)"/>
<RegExpr attribute="Integer" context="#stay" String="&allInt;(?=&endValueInline;|&endValue;)"/>
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="values-list">
<RegExpr attribute="Null" context="#stay" String="(?:\s|^)&null;(?=&endValueInline;|&endValue;)"/>
<RegExpr attribute="Boolean" context="#stay" String="(?:\s|^)&bool;(?=&endValueInline;|&endValue;)"/>
<RegExpr attribute="Float" context="#stay" String="(?:\s|^)&allFloat;(?=&endValueInline;|&endValue;)"/>
<RegExpr attribute="Integer" context="#stay" String="(?:\s|^)&allInt;(?=&endValueInline;|&endValue;)"/>
</context>
<!-- If the value is found immediately at the beginning of the list item -->
<context attribute="Normal Text" lineEndContext="#pop!list-element" name="find-values-list" fallthrough="true" fallthroughContext="#pop!list-element">
<RegExpr attribute="Null" context="#pop!list-element" String="&null;(?=&endValueInline;|&endValue;)"/>
<RegExpr attribute="Boolean" context="#pop!list-element" String="&bool;(?=&endValueInline;|&endValue;)"/>
<RegExpr attribute="Float" context="#pop!list-element" String="&allFloat;(?=&endValueInline;|&endValue;)"/>
<RegExpr attribute="Integer" context="#pop!list-element" String="&allInt;(?=&endValueInline;|&endValue;)"/>
</context>
<!-- Literal/Folded Style: http://yaml.org/spec/1.2/spec.html#id2795688 -->
<context attribute="Normal Text" lineEndContext="#stay" name="find-literal-block">
<!-- Do not allow indentation with tabs: -->
<RegExpr attribute="Alert" context="#stay" column="0"
String="^&space;*\t+\s*(?=(?:(?:&keyDQ;|&keySQ;|[^#])*[^#\w\|&lt;&gt;&quot;'])?&literalOp;&endValue;)" />
<!-- CASE 1: The literal/folded operator is the first character of a line.
The text after a space is considered literal.
Ex:
> |
> ^Start the literal text
-->
<RegExpr attribute="Literal/Folded Operator" context="literal-block-simple" column="0"
String="^&literalOp;(?=&endValue;)" beginRegion="Literal" />
<!-- CASE 2: Only the literal/folded operator is present in a line, after a space (the indentation
is captured). The text with the same indentation of the operator will be highlighted as literal.
Ex:
> key:
> |
> ^Start the literal text
However, in this case, the correct way is to use the indentation of the block, not the
indentation of the the operator. The problem is that it is difficult to capture.
> key1:
> key2:
> key3:
> |
> ^Block indentation (correct literal text)
-->
<RegExpr attribute="Literal/Folded Operator" context="literal-block-only-operator" column="0"
String="^(&space;+)&literalOp;(?=&endValue;)" beginRegion="Literal" />
<!-- CASE 3: There is a Key before the literal/folded operator (Key indentation is captured).
The text with the Key's indentation plus a space is considered literal.
Ex:
> key: |
> ^Start the literal text
> key: !!type >-
> ^Start the folded text
-->
<RegExpr attribute="Key Points Operator" context="literal-block-key" column="0"
String="^(&space;*)\:(?=\s+(?:(?:&keyDQ;|&keySQ;|[^#])*[^#\w\|&lt;&gt;&quot;'])?&literalOp;&endValue;)" />
<RegExpr attribute="Key" context="literal-block-key" column="0"
String="^(&space;*)(?:[^&quot;'#\-\?\s][^:#]*|\-(?:[^\s:#][^:#]*)?|&keyDQ;|&keySQ;)(?=\:\s+(?:(?:&keyDQ;|&keySQ;|[^#])*[^#\w\|&lt;&gt;&quot;'])?&literalOp;&endValue;)" />
<!-- CASE 4: Is there an operator "?" or "-" at the beginning of the line.
NOTE: Nested characters "-" and "?" are considered as part of the indentation.
Therefore, the indentation of the Key or the last operator "?" or "-" is captured.
Ex:
> ? |
> ^Start the literal Text
> ? - - |
> ^Start the literal text
> - Key: |
> ^Start the literal text
> ? - - - - Key: |
> ^Start the literal text
-->
<RegExpr context="start-literal-block-withdash" lookAhead="true" column="0"
String="^&space;*(?:\?&space;*|\-&space;+){1,6}(?:(?:&keyDQ;|&keySQ;|[^#\-\?\s]|\-[^\s#])(?:(?:&keyDQ;|&keySQ;|[^#])*[^#\w\|&lt;&gt;&quot;'])?)?&literalOp;&endValue;" />
<!-- CASE 5: Literal/folded operator after a data type or other content.
Ex:
> !!type |
> ^Start the literal text
> key1:
> key2:
> !!type |
> ^Start the literal text
-->
<RegExpr context="start-literal-block-other" lookAhead="true" column="0"
String="^&space;*(?:(?:[&amp;\*]|!!)\S+\s+)+&literalOp;&endValue;" />
</context>
<!-- If the line with the literal operator starts with the "-" or "?" operator.
NOTE: The indentation capture is limited to 6 nested operators. -->
<context attribute="Normal Text" lineEndContext="#pop" name="start-literal-block-withdash" noIndentationBasedFolding="true">
<!-- With Key: Capture the Key indentation -->
<RegExpr attribute="Operator" context="#pop!literal-block-key-withdash-s2" String="^(&space;*)[\?\-](&space;*)(?=&keyAfterOp;:\s)" column="0"/>
<RegExpr attribute="Operator" context="#pop!literal-block-key-withdash-s3" String="^(&space;*)[\?\-](&space;*)[\?\-](&space;*)(?=&keyAfterOp;:\s)" column="0"/>
<RegExpr attribute="Operator" context="#pop!literal-block-key-withdash-s4" String="^(&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-](&space;*)(?=&keyAfterOp;:\s)" column="0"/>
<RegExpr attribute="Operator" context="#pop!literal-block-key-withdash-s5" String="^(&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-](&space;*)(?=&keyAfterOp;:\s)" column="0"/>
<RegExpr attribute="Operator" context="#pop!literal-block-key-withdash-s6" String="^(&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-](&space;*)(?=&keyAfterOp;:\s)" column="0"/>
<RegExpr attribute="Operator" context="#pop!literal-block-key-withdash-s7" String="^(&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-](&space;*)(?=&keyAfterOp;:\s)" column="0"/>
<!-- Without Key: Capture the indentation of the last operator "?" or "-" -->
<RegExpr attribute="Operator" context="#pop!literal-block-withdash-s1" String="^(&space;*)[\?\-]\s*(?=[^#\-\?\s]|\-[^\s#])" column="0"/>
<RegExpr attribute="Operator" context="#pop!literal-block-withdash-s2" String="^(&space;*)[\?\-](&space;*)[\?\-]\s*(?=[^#\-\?\s]|\-[^\s#])" column="0"/>
<RegExpr attribute="Operator" context="#pop!literal-block-withdash-s3" String="^(&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-]\s*(?=[^#\-\?\s]|\-[^\s#])" column="0"/>
<RegExpr attribute="Operator" context="#pop!literal-block-withdash-s4" String="^(&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-]\s*(?=[^#\-\?\s]|\-[^\s#])" column="0"/>
<RegExpr attribute="Operator" context="#pop!literal-block-withdash-s5" String="^(&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-]\s*(?=[^#\-\?\s]|\-[^\s#])" column="0"/>
<RegExpr attribute="Operator" context="#pop!literal-block-withdash-s6" String="^(&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-](&space;*)[\?\-]\s*(?=[^#\-\?\s]|\-[^\s#])" column="0"/>
</context>
<!-- Capture the indentation of data type, reference or alias -->
<context attribute="Normal Text" lineEndContext="#pop" name="start-literal-block-other" noIndentationBasedFolding="true">
<!-- The text with the same indentation will be considered literal -->
<RegExpr attribute="Data Types" context="#pop!literal-block-after-data" String="^(&space;+)&dataTypes;" column="0" />
<RegExpr attribute="Alias" context="#pop!literal-block-after-data" String="^(&space;+)&alias;" column="0" />
<RegExpr attribute="Reference" context="#pop!literal-block-after-data" String="^(&space;+)&reference;" column="0" />
<!-- The text after a space will be considered literal (empty text is captured) -->
<RegExpr attribute="Data Types" context="#pop!literal-block-withdash-s1" String="^()&dataTypes;" column="0" />
<RegExpr attribute="Alias" context="#pop!literal-block-withdash-s1" String="^()&alias;" column="0" />
<RegExpr attribute="Reference" context="#pop!literal-block-withdash-s1" String="^()&reference;" column="0" />
</context>
<!-- Highlight data/attribute before the literal operator (Note that if there is a line
break within a string or bracket, the literal line will not be highlighted). -->
<context attribute="Attribute" lineEndContext="#pop#pop" name="before-literal-operator" noIndentationBasedFolding="true">
<RegExpr attribute="Literal/Folded Operator" context="#pop!end-literal-operator" String="&literalOp;(?=&endValue;)" beginRegion="Literal" />
<RegExpr attribute="Error" context="#pop#pop" String="(?:[&amp;\*]|!!)\S*&literalOp;(?=&endValue;)" />
<RegExpr attribute="Data Types" context="#stay" String="&dataTypes;" />
<RegExpr attribute="Alias" context="#stay" String="&alias;" />
<RegExpr attribute="Reference" context="#stay" String="&reference;" />
<DetectChar attribute="Operator" context="list" char="[" beginRegion="List" />
<DetectChar attribute="Operator" context="hash" char="{" beginRegion="Hash" />
<DetectChar attribute="String" context="string" char="'" beginRegion="String" />
<DetectChar attribute="String" context="stringx" char="&quot;" beginRegion="String" />
</context>
<context attribute="Normal Text" lineEndContext="#pop#pop" name="dpoints-key-before-literal-operator" fallthrough="true" fallthroughContext="#pop#pop" noIndentationBasedFolding="true">
<DetectChar attribute="Key Points Operator" context="#pop!key-before-literal-operator" char=":" />
</context>
<context attribute="Attribute" lineEndContext="#pop#pop" name="key-before-literal-operator" noIndentationBasedFolding="true">
<IncludeRules context="before-literal-operator" />
<DetectChar attribute="Operator" context="#stay" char="?" />
</context>
<context attribute="Attribute" lineEndContext="#pop" name="end-literal-operator" noIndentationBasedFolding="true">
<RegExpr attribute="Comment" context="#pop!comment" String="(?:^|\s+)#" />
</context>
<!-- Common rules for the content of the literal blocks -->
<context attribute="Normal Text" lineEndContext="#stay" name="literal-block-default" noIndentationBasedFolding="true">
<!-- End literal/folded block -->
<RegExpr attribute="Normal Text" context="#pop" String="^\s*\S" lookAhead="true" column="0" endRegion="Literal" />
<!-- Find literal/folded operator -->
<RegExpr context="before-literal-operator" String="\S" lookAhead="true" />
</context>
<context attribute="Normal Text" lineEndContext="#pop" name="literal-block-key-default" noIndentationBasedFolding="true">
<!-- End literal/folded block -->
<RegExpr attribute="Normal Text" context="#pop" String="^\s*\S" lookAhead="true" column="0" endRegion="Literal" />
<!-- Detect Key before the literal/folded operator -->
<RegExpr attribute="Key" context="dpoints-key-before-literal-operator" String="&keyAfterOp;(?=:\s)" />
<RegExpr attribute="Normal Text" context="#pop" String="\S" lookAhead="true" endRegion="Literal" />
</context>
<!-- Content of the literal block: -->
<!-- If the literal operator is starting the line (after a space, use block indentation) -->
<context attribute="Normal Text" lineEndContext="#stay" name="literal-block-only-operator" dynamic="true" noIndentationBasedFolding="true">
<RegExpr attribute="Literal/Folded Block" context="#stay" String="^%1.*$" dynamic="true" column="0" />
<RegExpr attribute="Normal Text" context="#pop" String="^\s*\S" lookAhead="true" column="0" endRegion="Literal" />
<RegExpr attribute="Comment" context="comment" String="(?:^|\s)#" />
<RegExpr context="#pop" String="\S" lookAhead="true" endRegion="Literal" />
</context>
<!-- If the literal operator is the first character of a line (or after header) -->
<context attribute="Normal Text" lineEndContext="#stay" name="literal-block-simple" noIndentationBasedFolding="true">
<RegExpr attribute="Literal/Folded Block" context="#stay" String="^\s.*$" column="0" />
<RegExpr attribute="Normal Text" context="#pop" String="^\s*\S" lookAhead="true" column="0" endRegion="Literal" />
<RegExpr attribute="Comment" context="comment" String="(?:^|\s)#" />
</context>
<!-- If there is a data type or other content before the liretal operator (use block indentation) -->
<context attribute="Normal Text" lineEndContext="#stay" name="literal-block-after-data" dynamic="true" noIndentationBasedFolding="true">
<RegExpr attribute="Literal/Folded Block" context="#stay" String="^%1.*$" dynamic="true" column="0" />
<RegExpr attribute="Normal Text" context="#pop" String="^\s*\S" lookAhead="true" column="0" endRegion="Literal" />
<RegExpr context="before-literal-operator" String="\S" lookAhead="true" />
</context>
<!-- If there is a key before the literal operator -->
<context attribute="Normal Text" lineEndContext="#stay" name="literal-block-key" dynamic="true" noIndentationBasedFolding="true">
<RegExpr attribute="Literal/Folded Block" context="#stay" String="^%1\s.*$" dynamic="true" column="0" />
<RegExpr attribute="Normal Text" context="#pop" String="^\s*\S" lookAhead="true" column="0" endRegion="Literal" />
<!-- Attribute of the Key (the Key was previously highlighted) -->
<RegExpr attribute="Key Points Operator" context="key-before-literal-operator" String=":\s" />
<RegExpr context="key-before-literal-operator" String="\S" lookAhead="true" />
</context>
<!-- If there are dashes/"?" before the literal operator -->
<context attribute="Normal Text" lineEndContext="#stay" name="literal-block-withdash-s1" dynamic="true" noIndentationBasedFolding="true">
<RegExpr attribute="Literal/Folded Block" context="#stay" String="^%1\s.*$" dynamic="true" column="0" />
<IncludeRules context="literal-block-default" />
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="literal-block-withdash-s2" dynamic="true" noIndentationBasedFolding="true">
<RegExpr attribute="Literal/Folded Block" context="#stay" String="^%1%2&space;\s.*$" dynamic="true" column="0" />
<IncludeRules context="literal-block-default" />
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="literal-block-withdash-s3" dynamic="true" noIndentationBasedFolding="true">
<RegExpr attribute="Literal/Folded Block" context="#stay" String="^%1%2%3&space;{2}\s.*$" dynamic="true" column="0" />
<IncludeRules context="literal-block-default" />
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="literal-block-withdash-s4" dynamic="true" noIndentationBasedFolding="true">
<RegExpr attribute="Literal/Folded Block" context="#stay" String="^%1%2%3%4&space;{3}\s.*$" dynamic="true" column="0" />
<IncludeRules context="literal-block-default" />
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="literal-block-withdash-s5" dynamic="true" noIndentationBasedFolding="true">
<RegExpr attribute="Literal/Folded Block" context="#stay" String="^%1%2%3%4%5&space;{4}\s.*$" dynamic="true" column="0" />
<IncludeRules context="literal-block-default" />
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="literal-block-withdash-s6" dynamic="true" noIndentationBasedFolding="true">
<RegExpr attribute="Literal/Folded Block" context="#stay" String="^%1%2%3%4%5%6&space;{5}\s.*$" dynamic="true" column="0" />
<IncludeRules context="literal-block-default" />
</context>
<!-- If there are dashes/"?" and a Key before the literal operator -->
<context attribute="Normal Text" lineEndContext="#stay" name="literal-block-key-withdash-s2" dynamic="true" noIndentationBasedFolding="true">
<RegExpr attribute="Literal/Folded Block" context="#stay" String="^%1%2&space;\s.*$" dynamic="true" column="0" />
<IncludeRules context="literal-block-key-default" />
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="literal-block-key-withdash-s3" dynamic="true" noIndentationBasedFolding="true">
<RegExpr attribute="Literal/Folded Block" context="#stay" String="^%1%2%3&space;{2}\s.*$" dynamic="true" column="0" />
<IncludeRules context="literal-block-key-default" />
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="literal-block-key-withdash-s4" dynamic="true" noIndentationBasedFolding="true">
<RegExpr attribute="Literal/Folded Block" context="#stay" String="^%1%2%3%4&space;{3}\s.*$" dynamic="true" column="0" />
<IncludeRules context="literal-block-key-default" />
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="literal-block-key-withdash-s5" dynamic="true" noIndentationBasedFolding="true">
<RegExpr attribute="Literal/Folded Block" context="#stay" String="^%1%2%3%4%5&space;{4}\s.*$" dynamic="true" column="0" />
<IncludeRules context="literal-block-key-default" />
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="literal-block-key-withdash-s6" dynamic="true" noIndentationBasedFolding="true">
<RegExpr attribute="Literal/Folded Block" context="#stay" String="^%1%2%3%4%5%6&space;{5}\s.*$" dynamic="true" column="0" />
<IncludeRules context="literal-block-key-default" />
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="literal-block-key-withdash-s7" dynamic="true" noIndentationBasedFolding="true">
<RegExpr attribute="Literal/Folded Block" context="#stay" String="^%1%2%3%4%5%6%7&space;{6}\s.*$" dynamic="true" column="0" />
<IncludeRules context="literal-block-key-default" />
</context>
</contexts>
<itemDatas>
<itemData name="Normal Text" defStyleNum="dsAttribute" />
<itemData name="Attribute" defStyleNum="dsAttribute" />
<itemData name="List" defStyleNum="dsAttribute" />
<itemData name="Hash" defStyleNum="dsAttribute" />
<itemData name="Comment" defStyleNum="dsComment" />
<itemData name="End of Document" defStyleNum="dsComment" />
<itemData name="Document Header" defStyleNum="dsPreprocessor" />
<itemData name="Data Types" defStyleNum="dsOthers" />
<itemData name="Alias" defStyleNum="dsOthers" />
<itemData name="Reference" defStyleNum="dsOthers" />
<itemData name="Key" defStyleNum="dsFunction" bold="1" />
<itemData name="Directive" defStyleNum="dsPreprocessor" />
<itemData name="Key Points Operator" defStyleNum="dsKeyword" />
<itemData name="Operator" defStyleNum="dsKeyword" />
<itemData name="String" defStyleNum="dsString" />
<itemData name="Escaped Character" defStyleNum="dsSpecialChar" />
<itemData name="Literal/Folded Operator" defStyleNum="dsChar" bold="1" />
<itemData name="Literal/Folded Block" defStyleNum="dsNormal" />
<itemData name="Null" defStyleNum="dsChar" />
<itemData name="Boolean" defStyleNum="dsChar" />
<itemData name="Integer" defStyleNum="dsDecVal" />
<itemData name="Float" defStyleNum="dsFloat" />
<itemData name="Error" defStyleNum="dsError" />
<itemData name="Alert" defStyleNum="dsAlert" backgroundColor="#EF9A9A" />
</itemDatas>
</highlighting>
<general>
<folding indentationsensitive="1" />
<emptyLines>
<emptyLine regexpr="(?:\s+|\s*#.*)"/>
</emptyLines>
<comments>
<comment name="singleLine" start="#" position="afterwhitespace" />
</comments>
<keywords casesensitive="1"/>
</general>
</language>
<!-- kate: replace-tabs on; tab-width 2; indent-width 2; -->

View File

@@ -1,174 +0,0 @@
{
"metadata" : {
"revision" : 3,
"name" : "Default"
},
"text-styles": {
"Normal" : {
"text-color" : "#1f1c1b",
"selected-text-color" : "#ffffff",
"bold" : false,
"italic" : false,
"underline" : false,
"strike-through" : false
},
"Keyword" : {
"text-color" : "#1f1c1b",
"selected-text-color" : "#ffffff",
"bold" : true
},
"Function" : {
"text-color" : "#644a9b",
"selected-text-color" : "#452886"
},
"Variable" : {
"text-color" : "#0057ae",
"selected-text-color" : "#00316e"
},
"ControlFlow" : {
"text-color" : "#1f1c1b",
"selected-text-color" : "#ffffff",
"bold" : true
},
"Operator" : {
"text-color" : "#1f1c1b",
"selected-text-color" : "#ffffff"
},
"BuiltIn" : {
"text-color" : "#644a9b",
"selected-text-color" : "#452886",
"bold" : true
},
"Extension" : {
"text-color" : "#0095ff",
"selected-text-color" : "#ffffff",
"bold" : true
},
"Preprocessor" : {
"text-color" : "#006e28",
"selected-text-color" : "#006e28"
},
"Attribute" : {
"text-color" : "#0057ae",
"selected-text-color" : "#00316e"
},
"Char" : {
"text-color" : "#924c9d",
"selected-text-color" : "#6c2477"
},
"SpecialChar" : {
"text-color" : "#3daee9",
"selected-text-color" : "#fcfcfc"
},
"String" : {
"text-color" : "#bf0303",
"selected-text-color" : "#9c0e0e"
},
"VerbatimString" : {
"text-color" : "#bf0303",
"selected-text-color" : "#9c0e0e"
},
"SpecialString" : {
"text-color" : "#ff5500",
"selected-text-color" : "#ff5500"
},
"Import" : {
"text-color" : "#ff5500",
"selected-text-color" : "#ff5500"
},
"DataType" : {
"text-color" : "#0057ae",
"selected-text-color" : "#00316e"
},
"DecVal" : {
"text-color" : "#b08000",
"selected-text-color" : "#805c00"
},
"BaseN" : {
"text-color" : "#b08000",
"selected-text-color" : "#805c00"
},
"Float" : {
"text-color" : "#b08000",
"selected-text-color" : "#805c00"
},
"Constant" : {
"text-color" : "#aa5500",
"selected-text-color" : "#5e2f00"
},
"Comment" : {
"text-color" : "#898887",
"selected-text-color" : "#5e5d5d"
},
"Documentation" : {
"text-color" : "#607880",
"selected-text-color" : "#46585e"
},
"Annotation" : {
"text-color" : "#ca60ca",
"selected-text-color" : "#a44ea4"
},
"CommentVar" : {
"text-color" : "#0095ff",
"selected-text-color" : "#ffffff"
},
"RegionMarker" : {
"text-color" : "#0057ae",
"selected-text-color" : "#00316e",
"background-color" : "#e0e9f8"
},
"Information" : {
"text-color" : "#b08000",
"selected-text-color" : "#805c00"
},
"Warning" : {
"text-color" : "#bf0303",
"selected-text-color" : "#9c0e0e"
},
"Alert" : {
"text-color" : "#bf0303",
"selected-text-color" : "#9c0e0e",
"background-color" : "#f7e6e6",
"bold" : true
},
"Error" : {
"text-color" : "#bf0303",
"selected-text-color" : "#9c0e0e",
"underline" : true
},
"Others" : {
"text-color" : "#006e28",
"selected-text-color" : "#006e28"
}
},
"editor-colors": {
"background-color" : "#ffffff",
"code-folding" : "#94caef",
"bracket-matching" : "#ffff00",
"current-line" : "#f8f7f6",
"icon-border" : "#f0f0f0",
"indentation-line" : "#d2d2d2",
"line-numbers" : "#a0a0a0",
"current-line-number" : "#1e1e1e",
"mark-bookmark" : "#0000ff",
"mark-breakpoint-active" : "#ff0000",
"mark-breakpoint-reached" : "#ffff00",
"mark-breakpoint-disabled" : "#ff00ff",
"mark-execution" : "#a0a0a4",
"mark-warning" : "#00ff00",
"mark-error" : "#ff0000",
"modified-lines" : "#fdbc4b",
"replace-highlight" : "#00ff00",
"saved-lines" : "#2ecc71",
"search-highlight" : "#ffff00",
"selection" : "#94caef",
"separator" : "#898887",
"spell-checking" : "#bf0303",
"tab-marker" : "#d2d2d2",
"template-background" : "#d6d2d0",
"template-placeholder" : "#baf8ce",
"template-focused-placeholder" : "#76da98",
"template-read-only-placeholder" : "#f6e6e6",
"word-wrap-marker" : "#ededed"
}
}

View File

@@ -1,26 +1,26 @@
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource prefix="/org.kde.syntax-highlighting/themes">
<file>atom-one-dark.theme</file>
<file>atom-one-light.theme</file>
<file>breeze-dark.theme</file>
<file>breeze-light.theme</file>
<file>ayu-dark.theme</file>
<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>
<file>gruvbox-light.theme</file>
<file>monokai.theme</file>
<file>nord.theme</file>
<file>oblivion.theme</file>
<file>printing.theme</file>
<file>radical.theme</file>
<file>solarized-dark.theme</file>
<file>solarized-light.theme</file>
<file>vim-dark.theme</file>
</qresource>
<RCC>
<qresource prefix="/org.kde.syntax-highlighting/themes">
<file>atom-one-dark.theme</file>
<file>atom-one-light.theme</file>
<file>ayu-dark.theme</file>
<file>ayu-light.theme</file>
<file>ayu-mirage.theme</file>
<file>breeze-dark.theme</file>
<file>breeze-light.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>
<file>gruvbox-light.theme</file>
<file>homunculus.theme</file>
<file>monokai.theme</file>
<file>nord.theme</file>
<file>oblivion.theme</file>
<file>printing.theme</file>
<file>radical.theme</file>
<file>solarized-dark.theme</file>
<file>solarized-light.theme</file>
<file>vim-dark.theme</file>
</qresource>
</RCC>

View File

@@ -1,9 +1,9 @@
add_subdirectory(indexer)
if(TARGET Qt${QT_MAJOR_VERSION}::Gui)
if(TARGET Qt6::Gui)
add_subdirectory(lib)
add_subdirectory(cli)
endif()
if(TARGET Qt${QT_MAJOR_VERSION}::Quick)
if(TARGET Qt6::Quick)
add_subdirectory(quick)
endif()

View File

@@ -8,4 +8,4 @@ sed -i -e 's/^i18nc/QT_TRANSLATE_NOOP/' rc.cpp
grep --no-filename '"name"' ../data/themes/*.theme | \
sed -r -e 's/"name"/QT_TRANSLATE_NOOP("Theme", /; s/://; s/,?$/);/' >> rc.cpp
$EXTRACT_TR_STRINGS `find . -name \*.cpp -o -name \*.h -o -name \*.ui -o -name \*.qml` -o $podir/syntaxhighlighting5_qt.pot
$EXTRACT_TR_STRINGS `find . -name \*.cpp -o -name \*.h -o -name \*.ui -o -name \*.qml` -o $podir/syntaxhighlighting6_qt.pot

View File

@@ -1,5 +1,5 @@
add_executable(kate-syntax-highlighter kate-syntax-highlighter.cpp)
ecm_mark_nongui_executable(kate-syntax-highlighter)
target_link_libraries(kate-syntax-highlighter KF5SyntaxHighlighting)
add_executable(ksyntaxhighlighter6 ksyntaxhighlighter.cpp)
ecm_mark_nongui_executable(ksyntaxhighlighter6)
target_link_libraries(ksyntaxhighlighter6 KF6SyntaxHighlighting)
install(TARGETS kate-syntax-highlighter ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
install(TARGETS ksyntaxhighlighter6 ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})

View File

@@ -26,7 +26,6 @@ static void applyHighlighter(Highlighter &highlighter,
QCommandLineParser &parser,
bool fromFileName,
const QString &inFileName,
const QCommandLineOption &stdinOption,
const QCommandLineOption &outputName,
const Ts &...highlightParams)
{
@@ -38,30 +37,36 @@ static void applyHighlighter(Highlighter &highlighter,
if (fromFileName) {
highlighter.highlightFile(inFileName, highlightParams...);
} else if (parser.isSet(stdinOption)) {
} else {
QFile inFile;
inFile.open(stdin, QIODevice::ReadOnly);
highlighter.highlightData(&inFile, highlightParams...);
} else {
parser.showHelp(1);
}
}
static Theme theme(const Repository &repo, const QString &themeName, Repository::DefaultTheme t)
{
if (themeName.isEmpty()) {
return repo.defaultTheme(t);
}
return repo.theme(themeName);
}
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
QCoreApplication::setApplicationName(QStringLiteral("kate-syntax-highlighter"));
QCoreApplication::setApplicationName(QStringLiteral("ksyntaxhighlighter"));
QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org"));
QCoreApplication::setOrganizationName(QStringLiteral("KDE"));
QCoreApplication::setApplicationVersion(QStringLiteral(SyntaxHighlighting_VERSION_STRING));
Repository repo;
QCoreApplication::setApplicationVersion(QStringLiteral(KSYNTAXHIGHLIGHTING_VERSION_STRING));
QCommandLineParser parser;
parser.setApplicationDescription(app.translate("SyntaxHighlightingCLI", "Command line syntax highlighter using Kate syntax definitions."));
parser.setApplicationDescription(app.translate("SyntaxHighlightingCLI", "Command line syntax highlighter using KSyntaxHighlighting syntax definitions."));
parser.addHelpOption();
parser.addVersionOption();
parser.addPositionalArgument(app.translate("SyntaxHighlightingCLI", "source"), app.translate("SyntaxHighlightingCLI", "The source file to highlight."));
parser.addPositionalArgument(
app.translate("SyntaxHighlightingCLI", "source"),
app.translate("SyntaxHighlightingCLI", "The source file to highlight. If absent, read the file from stdin and the --syntax option must be used."));
QCommandLineOption listDefs(QStringList() << QStringLiteral("l") << QStringLiteral("list"),
app.translate("SyntaxHighlightingCLI", "List all available syntax definitions."));
@@ -85,8 +90,7 @@ int main(int argc, char **argv)
QCommandLineOption themeName(QStringList() << QStringLiteral("t") << QStringLiteral("theme"),
app.translate("SyntaxHighlightingCLI", "Color theme to use for highlighting."),
app.translate("SyntaxHighlightingCLI", "theme"),
repo.defaultTheme(Repository::LightTheme).name());
app.translate("SyntaxHighlightingCLI", "theme"));
parser.addOption(themeName);
QCommandLineOption outputFormatOption(
@@ -99,7 +103,7 @@ int main(int argc, char **argv)
QCommandLineOption traceOption(QStringList() << QStringLiteral("syntax-trace"),
app.translate("SyntaxHighlightingCLI",
"Add information to debug a syntax file. Only works with --output-format=ansi or ansi256Colors. Possible "
"values are format, region, context and stackSize."),
"values are format, region, context, stackSize and all."),
app.translate("SyntaxHighlightingCLI", "type"));
parser.addOption(traceOption);
@@ -107,18 +111,20 @@ int main(int argc, char **argv)
app.translate("SyntaxHighlightingCLI", "Disable ANSI background for the default color."));
parser.addOption(noAnsiEditorBg);
QCommandLineOption unbufferedAnsi(QStringList() << QStringLiteral("U") << QStringLiteral("unbuffered"),
app.translate("SyntaxHighlightingCLI", "For ansi and ansi256Colors formats, flush the output buffer on each line."));
parser.addOption(unbufferedAnsi);
QCommandLineOption titleOption(
QStringList() << QStringLiteral("T") << QStringLiteral("title"),
app.translate("SyntaxHighlightingCLI", "Set HTML page's title\n(default: the filename or \"Kate Syntax Highlighter\" if reading from stdin)."),
app.translate("SyntaxHighlightingCLI", "Set HTML page's title\n(default: the filename or \"KSyntaxHighlighter\" if reading from stdin)."),
app.translate("SyntaxHighlightingCLI", "title"));
parser.addOption(titleOption);
QCommandLineOption stdinOption(QStringList() << QStringLiteral("stdin"),
app.translate("SyntaxHighlightingCLI", "Read file from stdin. The -s option must also be used."));
parser.addOption(stdinOption);
parser.process(app);
Repository repo;
if (parser.isSet(listDefs)) {
for (const auto &def : repo.definitions()) {
std::cout << qPrintable(def.name()) << std::endl;
@@ -177,7 +183,7 @@ int main(int argc, char **argv)
return 1;
}
QString outputFormat = parser.value(outputFormatOption);
const QString outputFormat = parser.value(outputFormatOption);
if (0 == outputFormat.compare(QLatin1String("html"), Qt::CaseInsensitive)) {
QString title;
if (parser.isSet(titleOption)) {
@@ -186,8 +192,8 @@ int main(int argc, char **argv)
HtmlHighlighter highlighter;
highlighter.setDefinition(def);
highlighter.setTheme(repo.theme(parser.value(themeName)));
applyHighlighter(highlighter, parser, fromFileName, inFileName, stdinOption, outputName, title);
highlighter.setTheme(theme(repo, parser.value(themeName), Repository::LightTheme));
applyHighlighter(highlighter, parser, fromFileName, inFileName, outputName, title);
} else {
auto AnsiFormat = AnsiHighlighter::AnsiFormat::TrueColor;
if (0 == outputFormat.compare(QLatin1String("ansi256Colors"), Qt::CaseInsensitive)) {
@@ -197,18 +203,22 @@ int main(int argc, char **argv)
return 2;
}
auto debugOptions = AnsiHighlighter::TraceOptions();
AnsiHighlighter::Options options{};
options |= parser.isSet(noAnsiEditorBg) ? AnsiHighlighter::Option::NoOptions : AnsiHighlighter::Option::UseEditorBackground;
options |= parser.isSet(unbufferedAnsi) ? AnsiHighlighter::Option::Unbuffered : AnsiHighlighter::Option::NoOptions;
if (parser.isSet(traceOption)) {
const auto options = parser.values(traceOption);
for (auto const &option : options) {
const auto traceOptions = parser.values(traceOption);
for (auto const &option : traceOptions) {
if (option == QStringLiteral("format")) {
debugOptions |= AnsiHighlighter::TraceOption::Format;
options |= AnsiHighlighter::Option::TraceFormat;
} else if (option == QStringLiteral("region")) {
debugOptions |= AnsiHighlighter::TraceOption::Region;
options |= AnsiHighlighter::Option::TraceRegion;
} else if (option == QStringLiteral("context")) {
debugOptions |= AnsiHighlighter::TraceOption::Context;
options |= AnsiHighlighter::Option::TraceContext;
} else if (option == QStringLiteral("stackSize")) {
debugOptions |= AnsiHighlighter::TraceOption::StackSize;
options |= AnsiHighlighter::Option::TraceStackSize;
} else if (option == QStringLiteral("all")) {
options |= AnsiHighlighter::Option::TraceAll;
} else {
std::cerr << "Unknown trace name." << std::endl;
return 2;
@@ -218,8 +228,8 @@ int main(int argc, char **argv)
AnsiHighlighter highlighter;
highlighter.setDefinition(def);
highlighter.setTheme(repo.theme(parser.value(themeName)));
applyHighlighter(highlighter, parser, fromFileName, inFileName, stdinOption, outputName, AnsiFormat, !parser.isSet(noAnsiEditorBg), debugOptions);
highlighter.setTheme(theme(repo, parser.value(themeName), Repository::DarkTheme));
applyHighlighter(highlighter, parser, fromFileName, inFileName, outputName, AnsiFormat, options);
}
return 0;

View File

@@ -4,13 +4,8 @@ if(CMAKE_CROSSCOMPILING AND KATEHIGHLIGHTINGINDEXER_EXECUTABLE)
add_executable(katehighlightingindexer IMPORTED GLOBAL)
set_target_properties(katehighlightingindexer PROPERTIES IMPORTED_LOCATION ${KATEHIGHLIGHTINGINDEXER_EXECUTABLE})
elseif(CMAKE_CROSSCOMPILING)
if (NOT KF5_HOST_TOOLING)
message(FATAL_ERROR "Please provide a prefix with a native Qt build and pass -DKF5_HOST_TOOLING=path")
endif()
# search native tooling prefix
string(FIND ${KF5_HOST_TOOLING} /lib idx)
string(SUBSTRING ${KF5_HOST_TOOLING} 0 ${idx} NATIVE_PREFIX)
include(ECMQueryQt)
ecm_query_qt(NATIVE_PREFIX QT_HOST_PREFIX)
message(STATUS "Building katehighlightingindexer against ${NATIVE_PREFIX}")
include(ExternalProject)
@@ -19,7 +14,7 @@ elseif(CMAKE_CROSSCOMPILING)
CMAKE_ARGS -DKSYNTAXHIGHLIGHTING_USE_GUI=OFF
-DECM_DIR=${ECM_DIR} -DCMAKE_PREFIX_PATH=${NATIVE_PREFIX}
-DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}
-DQT_MAJOR_VERSION=${QT_MAJOR_VERSION}
-DQT_MAJOR_VERSION=6
INSTALL_COMMAND ""
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/native_katehighlightingindexer-prefix/src/native_katehighlightingindexer-build/bin/katehighlightingindexer
)
@@ -31,9 +26,11 @@ else()
# host build
add_executable(katehighlightingindexer katehighlightingindexer.cpp ../lib/worddelimiters.cpp)
ecm_mark_nongui_executable(katehighlightingindexer)
if(Qt5XmlPatterns_FOUND AND NOT ECM_ENABLE_SANITIZERS)
target_link_libraries(katehighlightingindexer Qt5::XmlPatterns)
if(XercesC_FOUND)
add_definitions(-DHAS_XERCESC)
kde_target_enable_exceptions(katehighlightingindexer PRIVATE)
target_link_libraries(katehighlightingindexer Qt6::Core XercesC::XercesC)
else()
target_link_libraries(katehighlightingindexer Qt${QT_MAJOR_VERSION}::Core)
target_link_libraries(katehighlightingindexer Qt6::Core)
endif()
endif()

View File

@@ -12,12 +12,167 @@
#include <QFileInfo>
#include <QMutableMapIterator>
#include <QRegularExpression>
#include <QScopeGuard>
#include <QVariant>
#include <QXmlStreamReader>
#ifdef QT_XMLPATTERNS_LIB
#include <QXmlSchema>
#include <QXmlSchemaValidator>
#ifdef HAS_XERCESC
#include <xercesc/framework/XMLGrammarPoolImpl.hpp>
#include <xercesc/parsers/SAX2XMLReaderImpl.hpp>
#include <xercesc/sax/ErrorHandler.hpp>
#include <xercesc/sax/SAXParseException.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUni.hpp>
#include <xercesc/framework/XMLGrammarPoolImpl.hpp>
#include <xercesc/validators/common/Grammar.hpp>
using namespace xercesc;
/*
* Ideas taken from:
*
* author : Boris Kolpackov <boris@codesynthesis.com>
* copyright : not copyrighted - public domain
*
* This program uses Xerces-C++ SAX2 parser to load a set of schema files
* and then to validate a set of XML documents against these schemas. To
* build this program you will need Xerces-C++ 3.0.0 or later. For more
* information, see:
*
* http://www.codesynthesis.com/~boris/blog/2010/03/15/validating-external-schemas-xerces-cxx/
*/
/**
* Error handler object used during xml schema validation.
*/
class CustomErrorHandler : public ErrorHandler
{
public:
/**
* Constructor
* @param messages Pointer to the error message string to fill.
*/
CustomErrorHandler(QString *messages)
: m_messages(messages)
{
}
/**
* Check global success/fail state.
* @return True if there was a failure, false otherwise.
*/
bool failed() const
{
return m_failed;
}
private:
/**
* Severity classes for error messages.
*/
enum severity { s_warning, s_error, s_fatal };
/**
* Wrapper for warning exceptions.
* @param e Exception to handle.
*/
void warning(const SAXParseException &e) override
{
m_failed = true; // be strict, warnings are evil, too!
handle(e, s_warning);
}
/**
* Wrapper for error exceptions.
* @param e Exception to handle.
*/
void error(const SAXParseException &e) override
{
m_failed = true;
handle(e, s_error);
}
/**
* Wrapper for fatal error exceptions.
* @param e Exception to handle.
*/
void fatalError(const SAXParseException &e) override
{
m_failed = true;
handle(e, s_fatal);
}
/**
* Reset the error status to "no error".
*/
void resetErrors() override
{
m_failed = false;
}
/**
* Generic handler for error/warning/fatal error message exceptions.
* @param e Exception to handle.
* @param s Enum value encoding the message severtity.
*/
void handle(const SAXParseException &e, severity s)
{
// get id to print
const XMLCh *xid(e.getPublicId());
if (!xid)
xid = e.getSystemId();
m_messages << QString::fromUtf16(xid) << ":" << e.getLineNumber() << ":" << e.getColumnNumber() << " " << (s == s_warning ? "warning: " : "error: ")
<< QString::fromUtf16(e.getMessage()) << Qt::endl;
}
private:
/**
* Storage for created error messages in this handler.
*/
QTextStream m_messages;
/**
* Global error state. True if there was an error, false otherwise.
*/
bool m_failed = false;
};
void init_parser(SAX2XMLReaderImpl &parser)
{
// Commonly useful configuration.
//
parser.setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
parser.setFeature(XMLUni::fgSAX2CoreNameSpacePrefixes, true);
parser.setFeature(XMLUni::fgSAX2CoreValidation, true);
// Enable validation.
//
parser.setFeature(XMLUni::fgXercesSchema, true);
parser.setFeature(XMLUni::fgXercesSchemaFullChecking, true);
parser.setFeature(XMLUni::fgXercesValidationErrorAsFatal, true);
// Use the loaded grammar during parsing.
//
parser.setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true);
// Don't load schemas from any other source (e.g., from XML document's
// xsi:schemaLocation attributes).
//
parser.setFeature(XMLUni::fgXercesLoadSchema, false);
// Xerces-C++ 3.1.0 is the first version with working multi import
// support.
//
parser.setFeature(XMLUni::fgXercesHandleMultipleImports, true);
}
#endif
#include "../lib/worddelimiters_p.h"
@@ -152,12 +307,10 @@ public:
success = false;
}
QSet<const Keywords *> referencedKeywords;
QSet<ItemDatas::Style> usedAttributeNames;
QSet<ItemDatas::Style> ignoredAttributeNames;
success = checkKeywordsList(definition, referencedKeywords) && success;
success =
checkContexts(definition, referencedKeywords, usedAttributeNames, ignoredAttributeNames, usedContexts, unreachableIncludedRules) && success;
success = checkKeywordsList(definition) && success;
success = checkContexts(definition, usedAttributeNames, ignoredAttributeNames, usedContexts, unreachableIncludedRules) && success;
// search for non-existing itemDatas.
const auto invalidNames = usedAttributeNames - definition.itemDatas.styleNames;
@@ -362,7 +515,7 @@ private:
QString content;
int line;
friend uint qHash(const Item &item, uint seed = 0)
friend size_t qHash(const Item &item, size_t seed = 0)
{
return qHash(item.content, seed);
}
@@ -373,7 +526,7 @@ private:
}
};
QVector<Item> keywords;
QList<Item> keywords;
QSet<Item> includes;
bool parseElement(const QString &filename, QXmlStreamReader &xml)
@@ -486,7 +639,7 @@ private:
QString weakDeliminator;
// rules included by IncludeRules (without IncludeRule)
QVector<const Rule *> includedRules;
QList<const Rule *> includedRules;
// IncludeRules included by IncludeRules
QSet<const Rule *> includedIncludeRules;
@@ -683,9 +836,10 @@ private:
ContextName lineEndContext;
ContextName lineEmptyContext;
ContextName fallthroughContext;
QVector<Rule> rules;
QList<Rule> rules;
XmlBool dynamic{};
XmlBool fallthrough{};
XmlBool stopEmptyLineContextSwitchLoop{};
bool parseElement(const QString &filename, QXmlStreamReader &xml)
{
@@ -697,12 +851,17 @@ private:
Parser parser{filename, xml, attr, success};
XmlBool noIndentationBasedFolding{};
const bool isExtracted = parser.extractString(name, QStringLiteral("name")) || parser.extractString(attribute, QStringLiteral("attribute"))
// clang-format off
const bool isExtracted = parser.extractString(name, QStringLiteral("name"))
|| parser.extractString(attribute, QStringLiteral("attribute"))
|| parser.extractString(lineEndContext.name, QStringLiteral("lineEndContext"))
|| parser.extractString(lineEmptyContext.name, QStringLiteral("lineEmptyContext"))
|| parser.extractString(fallthroughContext.name, QStringLiteral("fallthroughContext"))
|| parser.extractXmlBool(dynamic, QStringLiteral("dynamic")) || parser.extractXmlBool(fallthrough, QStringLiteral("fallthrough"))
|| parser.extractXmlBool(dynamic, QStringLiteral("dynamic"))
|| parser.extractXmlBool(fallthrough, QStringLiteral("fallthrough"))
|| parser.extractXmlBool(stopEmptyLineContextSwitchLoop, QStringLiteral("stopEmptyLineContextSwitchLoop"))
|| parser.extractXmlBool(noIndentationBasedFolding, QStringLiteral("noIndentationBasedFolding"));
// clang-format on
success = parser.checkIfExtracted(isExtracted);
}
@@ -717,11 +876,6 @@ private:
success = false;
}
if (lineEndContext.name.isEmpty()) {
qWarning() << filename << "line" << xml.lineNumber() << "missing attribute: lineEndContext";
success = false;
}
return success;
}
};
@@ -747,7 +901,7 @@ private:
QString name;
int line;
friend uint qHash(const Style &style, uint seed = 0)
friend size_t qHash(const Style &style, size_t seed = 0)
{
return qHash(style.name, seed);
}
@@ -802,7 +956,6 @@ private:
const Context *firstContext = nullptr;
QString filename;
WordDelimiters wordDelimiters;
XmlBool casesensitive{};
Version kateVersion{};
QString kateVersionStr;
QString languageName;
@@ -865,7 +1018,7 @@ private:
void resolveIncludeRules()
{
QSet<const Context *> usedContexts;
QVector<const Context *> contexts;
QList<const Context *> contexts;
QMutableMapIterator<QString, Definition> def(m_definitions);
while (def.hasNext()) {
@@ -936,7 +1089,7 @@ private:
QSet<const Context *> extractUsedContexts() const
{
QSet<const Context *> usedContexts;
QVector<const Context *> contexts;
QList<const Context *> contexts;
QMapIterator<QString, Definition> def(m_definitions);
while (def.hasNext()) {
@@ -982,13 +1135,12 @@ private:
};
struct IncludedRuleUnreachableBy {
QVector<RuleAndInclude> unreachableBy;
QList<RuleAndInclude> unreachableBy;
bool alwaysUnreachable = true;
};
//! Check contexts and rules
bool checkContexts(const Definition &definition,
QSet<const Keywords *> &referencedKeywords,
QSet<ItemDatas::Style> &usedAttributeNames,
QSet<ItemDatas::Style> &ignoredAttributeNames,
const QSet<const Context *> &usedContexts,
@@ -1018,7 +1170,7 @@ private:
usedAttributeNames.insert({context.attribute, context.line});
}
success = checkfallthrough(definition, context) && success;
success = checkContextAttribute(definition, context) && success;
success = checkUreachableRules(definition.filename, context, unreachableIncludedRules) && success;
success = suggestRuleMerger(definition.filename, context) && success;
@@ -1032,7 +1184,7 @@ private:
}
success = checkLookAhead(rule) && success;
success = checkStringDetect(rule) && success;
success = checkKeyword(definition, rule, referencedKeywords) && success;
success = checkKeyword(definition, rule) && success;
success = checkRegExpr(filename, rule, context) && success;
success = checkDelimiters(definition, rule) && success;
}
@@ -1047,12 +1199,13 @@ private:
//! - dynamic=true but no place holder used?
//! - is not . with lookAhead="1"
//! - is not ^... without column ou firstNonSpace attribute
//! - is not equivalent to DetectSpaces, DetectChar, Detect2Chars, StringDetect, DetectIdentifier, RangeDetect
//! - is not equivalent to DetectSpaces, DetectChar, Detect2Chars, StringDetect, DetectIdentifier, RangeDetect, LineContinue or AnyChar
//! - has no unused captures
//! - has no unnecessary quantifier with lookAhead
bool checkRegExpr(const QString &filename, const Context::Rule &rule, const Context &context) const
{
if (rule.type == Context::Rule::Type::RegExpr) {
// ignore empty regex because the error is raised during xml parsing
if (rule.type == Context::Rule::Type::RegExpr && !rule.string.isEmpty()) {
const QRegularExpression regexp(rule.string);
if (!checkRegularExpression(rule.filename, regexp, rule.line)) {
return false;
@@ -1092,13 +1245,21 @@ private:
// is RangeDetect
static const QRegularExpression isRange(QStringLiteral("^\\^?" REG_CHAR "(?:"
"\\.\\*[?*]?" REG_CHAR "|"
"\\[\\^(" REG_ESCAPE_CHAR "|.)\\]\\*[?*]?\\1"
"\\.\\*[?+]?" REG_CHAR "|"
"\\[\\^(" REG_ESCAPE_CHAR "|.)\\]\\*[?+]?\\1"
")$"));
if ((rule.lookAhead == XmlBool::True || rule.minimal == XmlBool::True || rule.string.contains(QStringLiteral(".*?"))
|| rule.string.contains(QStringLiteral("[^")))
&& reg.contains(isRange)) {
qWarning() << filename << "line" << rule.line << "RegExpr should be replaced by RangeDetect:" << rule.string;
qWarning() << rule.filename << "line" << rule.line << "RegExpr should be replaced by RangeDetect:" << rule.string;
return false;
}
// is AnyChar
static const QRegularExpression isAnyChar(QStringLiteral(R"(^(\^|\((\?:)?)*\[(?!\^)[-\]]?(\\[^0BDPSWbdpswoux]|[^-\]\\])*\]\)*$)"));
if (rule.string.contains(isAnyChar)) {
auto extra = (reg[0] == QLatin1Char('^') || reg[1] == QLatin1Char('^')) ? "with column=\"0\"" : "";
qWarning() << rule.filename << "line" << rule.line << "RegExpr should be replaced by AnyChar:" << rule.string << extra;
return false;
}
@@ -1106,7 +1267,7 @@ private:
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;
qWarning() << rule.filename << "line" << rule.line << "RegExpr should be replaced by LineContinue:" << rule.string << extra;
return false;
}
@@ -1124,7 +1285,7 @@ private:
if (rule.lookAhead == XmlBool::True && rule.minimal != XmlBool::True && reg.contains(isMinimal) && !reg.contains(hasNotGreedy)
&& (!rule.context.context || !rule.context.context->hasDynamicRule || regexp.captureCount() == 0)
&& (reg.back() != QLatin1Char('$') || reg.contains(QLatin1Char('|')))) {
qWarning() << filename << "line" << rule.line
qWarning() << rule.filename << "line" << rule.line
<< "RegExpr should be have minimal=\"1\" or use lazy operator (i.g, '.*' -> '.*?'):" << rule.string;
return false;
}
@@ -1160,8 +1321,8 @@ private:
return false;
}
// column="0" or firstNonSpace="1"
if (rule.column == -1 && rule.firstNonSpace != XmlBool::True) {
// column="0"
if (rule.column == -1) {
// ^ without |
// (^sas*) -> ok
// (^sa|s*) -> ko
@@ -1204,7 +1365,7 @@ private:
}
if (replace) {
qWarning() << rule.filename << "line" << rule.line << "column=\"0\" or firstNonSpace=\"1\" missing with RegExpr:" << rule.string;
qWarning() << rule.filename << "line" << rule.line << "column=\"0\" missing with RegExpr:" << rule.string;
return false;
}
}
@@ -1306,11 +1467,8 @@ private:
if (!useCapture) {
// is DetectIdentifier
static const QRegularExpression isInsensitiveDetectIdentifier(
QStringLiteral(R"(^(\((\?:)?)?\[((a-z|_){2}|(A-Z|_){2})\]([+][*?]?)?\[((0-9|a-z|_){3}|(0-9|A-Z|_){3})\][*][*?]?(\))?$)"));
static const QRegularExpression isSensitiveDetectIdentifier(
QStringLiteral(R"(^(\((\?:)?)?\[(a-z|A-Z|_){3}\]([+][*?]?)?\[(0-9|a-z|A-Z|_){4}\][*][*?]?(\))?$)"));
auto &isDetectIdentifier = (rule.insensitive == XmlBool::True) ? isInsensitiveDetectIdentifier : isSensitiveDetectIdentifier;
static const QRegularExpression isDetectIdentifier(
QStringLiteral(R"(^(\((\?:)?|\^)*\[(\\p\{L\}|_){2}\]([+][?+]?)?\[(\\p\{N\}|\\p\{L\}|_){3}\][*][?+]?\)*$)"));
if (rule.string.contains(isDetectIdentifier)) {
qWarning() << rule.filename << "line" << rule.line << "RegExpr should be replaced by DetectIdentifier:" << rule.string;
return false;
@@ -1357,7 +1515,7 @@ private:
static const QRegularExpression unnecessaryQuantifier2(QStringLiteral(R"([*+?]([.][*+?]{0,2})?[)]*$)"));
auto &unnecessaryQuantifier = useCapture ? unnecessaryQuantifier1 : unnecessaryQuantifier2;
if (rule.lookAhead == XmlBool::True && rule.minimal != XmlBool::True && reg.contains(unnecessaryQuantifier)) {
qWarning() << filename << "line" << rule.line
qWarning() << rule.filename << "line" << rule.line
<< "Last quantifier is not necessary (i.g., 'xyz*' -> 'xy', 'xyz+.' -> 'xyz.'):" << rule.string;
return false;
}
@@ -1418,19 +1576,13 @@ private:
return true;
}
//! Search for rules with lookAhead="true" and context="#stay".
//! This would cause an infinite loop.
bool checkfallthrough(const Definition &definition, const Context &context) const
//! Check fallthrough and fallthroughContext.
//! Check kateversion for stopEmptyLineContextSwitchLoop.
bool checkContextAttribute(const Definition &definition, const Context &context) const
{
bool success = true;
if (!context.fallthroughContext.name.isEmpty()) {
if (context.fallthroughContext.stay) {
qWarning() << definition.filename << "line" << context.line << "possible infinite loop due to fallthroughContext=\"#stay\" in context "
<< context.name;
success = false;
}
const bool mandatoryFallthroughAttribute = definition.kateVersion < Version{5, 62};
if (context.fallthrough == XmlBool::True && !mandatoryFallthroughAttribute) {
qWarning() << definition.filename << "line" << context.line << "fallthrough attribute is unnecessary with kateversion >= 5.62 in context"
@@ -1444,6 +1596,12 @@ private:
}
}
if (context.stopEmptyLineContextSwitchLoop != XmlBool::Unspecified && definition.kateVersion < Version{5, 103}) {
qWarning() << definition.filename << "line" << context.line
<< "stopEmptyLineContextSwitchLoop attribute is only valid with kateversion >= 5.103 in context" << context.name;
success = false;
}
return success;
}
@@ -1478,15 +1636,12 @@ private:
return false;
}
//! Search for rules with lookAhead="true" and context="#stay".
//! This would cause an infinite loop.
bool checkKeyword(const Definition &definition, const Context::Rule &rule, QSet<const Keywords *> &referencedKeywords) const
//! Check that keyword rule reference an existing keyword list.
bool checkKeyword(const Definition &definition, const Context::Rule &rule) const
{
if (rule.type == Context::Rule::Type::keyword) {
auto it = definition.keywordsList.find(rule.string);
if (it != definition.keywordsList.end()) {
referencedKeywords.insert(&*it);
} else {
if (it == definition.keywordsList.end()) {
qWarning() << rule.filename << "line" << rule.line << "reference of non-existing keyword list:" << rule.string;
return false;
}
@@ -1504,13 +1659,7 @@ private:
return true;
}
//! Check that StringDetect contains more that 2 characters
//! Fix with following command:
//! \code
//! sed -E
//! '/StringDetect/{/dynamic="(1|true)|insensitive="(1|true)/!{s/StringDetect(.*)String="(.|&lt;|&gt;|&quot;|&amp;)(.|&lt;|&gt;|&quot;|&amp;)"/Detect2Chars\1char="\2"
//! char1="\3"/;t;s/StringDetect(.*)String="(.|&lt;|&gt;|&quot;|&amp;)"/DetectChar\1char="\2"/}}' -i file.xml...
//! \endcode
//! Check that StringDetect contains a placeHolder when dynamic="1"
bool checkStringDetect(const Context::Rule &rule) const
{
if (rule.type == Context::Rule::Type::StringDetect) {
@@ -1527,7 +1676,7 @@ private:
}
//! Check \<include> and delimiter in a keyword list
bool checkKeywordsList(const Definition &definition, QSet<const Keywords *> &referencedKeywords) const
bool checkKeywordsList(const Definition &definition) const
{
bool success = true;
@@ -1542,7 +1691,7 @@ private:
<< "<include> is only available since version \"5.53\". Please, increase kateversion.";
success = false;
}
success = checkKeywordInclude(definition, include, referencedKeywords) && success;
success = checkKeywordInclude(definition, include) && success;
}
// Check that keyword list items do not have deliminator character
@@ -1562,16 +1711,13 @@ private:
}
//! Search for non-existing keyword include.
bool checkKeywordInclude(const Definition &definition, const Keywords::Items::Item &include, QSet<const Keywords *> &referencedKeywords) const
bool checkKeywordInclude(const Definition &definition, const Keywords::Items::Item &include) const
{
bool containsKeywordName = true;
int const idx = include.content.indexOf(QStringLiteral("##"));
if (idx == -1) {
auto it = definition.keywordsList.find(include.content);
containsKeywordName = (it != definition.keywordsList.end());
if (containsKeywordName) {
referencedKeywords.insert(&*it);
}
} else {
auto defName = include.content.mid(idx + 2);
auto listName = include.content.left(idx);
@@ -1644,10 +1790,10 @@ private:
}
/// Search RuleAndInclude associated with the characters of @p s.
/// \return an empty QVector when at least one character is not found.
QVector<RuleAndInclude> find(QStringView s) const
/// \return an empty QList when at least one character is not found.
QList<RuleAndInclude> find(QStringView s) const
{
QVector<RuleAndInclude> result;
QList<RuleAndInclude> result;
for (QChar c : s) {
if (!find(c)) {
@@ -1731,8 +1877,8 @@ private:
}
/// Search RuleAndInclude associated with the characters of @p s.
/// \return an empty QVector when at least one character is not found.
QVector<RuleAndInclude> find(QStringView s) const
/// \return an empty QList when at least one character is not found.
QList<RuleAndInclude> find(QStringView s) const
{
for (int i = 0; i < m_size; ++i) {
auto result = m_charTables[i]->find(s);
@@ -1743,7 +1889,7 @@ private:
return result;
}
}
return QVector<RuleAndInclude>();
return QList<RuleAndInclude>();
}
/// Associates @p c with a rule.
@@ -1785,7 +1931,7 @@ private:
// Iterates over all the rules, including those in includedRules
struct RuleIterator {
RuleIterator(const QVector<ObservableRule> &rules, const ObservableRule &endRule)
RuleIterator(const QList<ObservableRule> &rules, const ObservableRule &endRule)
: m_end(&endRule - rules.data())
, m_rules(rules)
{
@@ -1830,10 +1976,10 @@ private:
private:
int m_i = 0;
int m_i2;
int m_end;
const QVector<ObservableRule> &m_rules;
const QVector<const Context::Rule *> *m_includedRules = nullptr;
int m_i2 = 0;
const int m_end;
const QList<ObservableRule> &m_rules;
const QList<const Context::Rule *> *m_includedRules = nullptr;
};
// Dot regex container that satisfies firstNonSpace and column.
@@ -1915,7 +2061,7 @@ private:
DotRegex dotRegex;
QVector<ObservableRule> observedRules;
QList<ObservableRule> observedRules;
observedRules.reserve(context.rules.size());
for (const Context::Rule &rule : context.rules) {
const Context::Rule *includeRule = nullptr;
@@ -1937,7 +2083,7 @@ private:
for (auto &observedRule : observedRules) {
const Context::Rule &rule = *observedRule.rule;
bool isUnreachable = false;
QVector<RuleAndInclude> unreachableBy;
QList<RuleAndInclude> unreachableBy;
// declare rule as unreachable if ruleAndInclude is not empty
auto updateUnreachable1 = [&](RuleAndInclude ruleAndInclude) {
@@ -1948,7 +2094,7 @@ private:
};
// declare rule as unreachable if ruleAndIncludes is not empty
auto updateUnreachable2 = [&](const QVector<RuleAndInclude> &ruleAndIncludes) {
auto updateUnreachable2 = [&](const QList<RuleAndInclude> &ruleAndIncludes) {
if (!ruleAndIncludes.isEmpty()) {
isUnreachable = true;
unreachableBy.append(ruleAndIncludes);
@@ -2030,6 +2176,8 @@ private:
case Context::Rule::Type::Float:
updateUnreachable2(CharTableArray(detectChars, rule).find(QStringLiteral("0123456789.")));
updateUnreachable1(floatRule.setRule(rule));
// check that Float is before Int
updateUnreachable1(Rule4(intRule).setRule(rule));
break;
// check if hidden by another DetectIdentifier rule
@@ -2629,12 +2777,32 @@ int main(int argc, char *argv[])
return 1;
}
#ifdef QT_XMLPATTERNS_LIB
// open schema
QXmlSchema schema;
if (!schema.load(QUrl::fromLocalFile(app.arguments().at(2)))) {
#ifdef HAS_XERCESC
// care for proper init and cleanup
XMLPlatformUtils::Initialize();
auto cleanup = qScopeGuard(XMLPlatformUtils::Terminate);
/*
* parse XSD first time and cache it
*/
XMLGrammarPoolImpl xsd(XMLPlatformUtils::fgMemoryManager);
// create parser for the XSD
SAX2XMLReaderImpl parser(XMLPlatformUtils::fgMemoryManager, &xsd);
init_parser(parser);
QString messages;
CustomErrorHandler eh(&messages);
parser.setErrorHandler(&eh);
// load grammar into the pool, on error just abort
const auto xsdFile = app.arguments().at(2);
if (!parser.loadGrammar((const char16_t *)xsdFile.utf16(), Grammar::SchemaGrammarType, true) || eh.failed()) {
qWarning("Failed to parse XSD %s: %s", qPrintable(xsdFile), qPrintable(messages));
return 2;
}
// lock the pool, no later modifications wanted!
xsd.lockPool();
#endif
const QString hlFilenamesListing = app.arguments().value(3);
@@ -2665,10 +2833,20 @@ int main(int argc, char *argv[])
continue;
}
#ifdef QT_XMLPATTERNS_LIB
// validate against schema
QXmlSchemaValidator validator(schema);
if (!validator.validate(&hlFile, QUrl::fromLocalFile(hlFile.fileName()))) {
#ifdef HAS_XERCESC
// create parser
SAX2XMLReaderImpl parser(XMLPlatformUtils::fgMemoryManager, &xsd);
init_parser(parser);
QString messages;
CustomErrorHandler eh(&messages);
parser.setErrorHandler(&eh);
// parse the XML file
parser.parse((const char16_t *)hlFile.fileName().utf16());
// report issues
if (eh.failed()) {
qWarning("Failed to validate XML %s: %s", qPrintable(hlFile.fileName()), qPrintable(messages));
anyError = 4;
continue;
}
@@ -2708,6 +2886,10 @@ int main(int argc, char *argv[])
// add boolean one
hl[QStringLiteral("hidden")] = attrToBool(xml.attributes().value(QLatin1String("hidden")));
// keep some strings as UTF-8 for faster translations
hl[QStringLiteral("nameUtf8")] = hl[QStringLiteral("name")].toString().toUtf8();
hl[QStringLiteral("sectionUtf8")] = hl[QStringLiteral("section")].toString().toUtf8();
// remember hl
hls[QFileInfo(hlFile).fileName()] = hl;

View File

@@ -1,8 +1,14 @@
add_library(KF5SyntaxHighlighting)
add_library(KF6SyntaxHighlighting)
ecm_create_qm_loader(syntax_highlighting_QM_LOADER syntaxhighlighting5_qt)
set_target_properties(KF6SyntaxHighlighting PROPERTIES
VERSION ${KSYNTAXHIGHLIGHTING_VERSION}
SOVERSION ${KSYNTAXHIGHLIGHTING_SOVERSION}
EXPORT_NAME SyntaxHighlighting
)
target_sources(KF5SyntaxHighlighting PRIVATE
ecm_create_qm_loader(syntax_highlighting_QM_LOADER syntaxhighlighting6_qt)
target_sources(KF6SyntaxHighlighting PRIVATE
abstracthighlighter.cpp
context.cpp
contextswitch.cpp
@@ -25,7 +31,7 @@ target_sources(KF5SyntaxHighlighting PRIVATE
${syntax_highlighting_QM_LOADER}
$<TARGET_OBJECTS:SyntaxHighlightingData>
)
ecm_qt_declare_logging_category(KF5SyntaxHighlighting
ecm_qt_declare_logging_category(KF6SyntaxHighlighting
HEADER ksyntaxhighlighting_logging.h
IDENTIFIER KSyntaxHighlighting::Log
CATEGORY_NAME kf.syntaxhighlighting
@@ -34,25 +40,21 @@ ecm_qt_declare_logging_category(KF5SyntaxHighlighting
EXPORT KSYNTAXHIGHLIGHTING
)
ecm_generate_export_header(KF5SyntaxHighlighting
ecm_generate_export_header(KF6SyntaxHighlighting
BASE_NAME KSyntaxHighlighting
GROUP_BASE_NAME KF
VERSION ${KF_VERSION}
USE_VERSION_HEADER
DEPRECATED_BASE_VERSION 0
DEPRECATION_VERSIONS 5.87
DEPRECATION_VERSIONS
EXCLUDE_DEPRECATED_BEFORE_AND_AT ${EXCLUDE_DEPRECATED_BEFORE_AND_AT}
)
set_target_properties(KF5SyntaxHighlighting PROPERTIES
VERSION ${SyntaxHighlighting_VERSION}
SOVERSION ${SyntaxHighlighting_SOVERSION}
EXPORT_NAME SyntaxHighlighting
)
target_link_libraries(KF5SyntaxHighlighting
target_link_libraries(KF6SyntaxHighlighting
PUBLIC
Qt${QT_MAJOR_VERSION}::Gui
Qt6::Gui
PRIVATE
Qt${QT_MAJOR_VERSION}::Network
Qt6::Network
)
set(Forwarding_Header_Names
@@ -74,12 +76,12 @@ ecm_generate_headers(CamelCase_HEADERS
OUTPUT_DIR ${CMAKE_BINARY_DIR}/KSyntaxHighlighting/KSyntaxHighlighting
)
target_include_directories(KF5SyntaxHighlighting
target_include_directories(KF6SyntaxHighlighting
INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR_KF}/KSyntaxHighlighting>"
PUBLIC "$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/KSyntaxHighlighting;>"
)
install(TARGETS KF5SyntaxHighlighting EXPORT KF5SyntaxHighlightingTargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
install(TARGETS KF6SyntaxHighlighting EXPORT KF6SyntaxHighlightingTargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES
${CamelCase_HEADERS}
@@ -90,17 +92,17 @@ install(FILES
if(BUILD_QCH)
ecm_add_qch(
KF5SyntaxHighlighting_QCH
KF6SyntaxHighlighting_QCH
NAME KSyntaxHighlighting
BASE_NAME KF5SyntaxHighlighting
BASE_NAME KF6SyntaxHighlighting
VERSION ${KF_VERSION}
ORG_DOMAIN org.kde
SOURCES # using only public headers, to cover only public API
${SyntaxHighlighting_HEADERS}
MD_MAINPAGE "${CMAKE_SOURCE_DIR}/README.md"
LINK_QCHS
Qt5Core_QCH
Qt5Gui_QCH
Qt6Core_QCH
Qt6Gui_QCH
INCLUDE_DIRS
${CMAKE_CURRENT_BINARY_DIR}
BLANK_MACROS
@@ -111,11 +113,3 @@ if(BUILD_QCH)
COMPONENT Devel
)
endif()
ecm_generate_pri_file(
BASE_NAME KSyntaxHighlighting LIB_NAME
KF5SyntaxHighlighting
DEPS "gui"
FILENAME_VAR PRI_FILENAME
INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR_KF}/KSyntaxHighlighting
)
install(FILES ${PRI_FILENAME} DESTINATION ${ECM_MKSPECS_INSTALL_DIR})

View File

@@ -12,6 +12,7 @@
#include "format.h"
#include "ksyntaxhighlighting_logging.h"
#include "repository.h"
#include "repository_p.h"
#include "rule_p.h"
#include "state.h"
#include "state_p.h"
@@ -97,13 +98,6 @@ static inline int firstNonSpaceChar(QStringView 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);
@@ -116,43 +110,47 @@ State AbstractHighlighter::highlightLine(QStringView text, const State &state)
return State();
}
// limit the cache for unification to some reasonable size
// we use here at the moment 64k elements to not hog too much memory
// and to make the clearing no big stall
if (defData->unify.size() > 64 * 1024)
defData->unify.clear();
// verify/initialize state
auto newState = state;
auto stateData = StateData::get(newState);
const auto definitionId = DefinitionData::get(d->m_definition)->id;
if (!stateData->isEmpty() && stateData->m_defId != definitionId) {
bool isSharedData = true;
if (Q_UNLIKELY(stateData && stateData->m_defId != defData->id)) {
qCDebug(Log) << "Got invalid state, resetting.";
stateData->clear();
stateData = nullptr;
}
if (stateData->isEmpty()) {
if (Q_UNLIKELY(!stateData)) {
stateData = StateData::reset(newState);
stateData->push(defData->initialContext(), QStringList());
stateData->m_defId = definitionId;
stateData->m_defId = defData->id;
isSharedData = false;
}
// process empty lines
if (text.isEmpty()) {
if (Q_UNLIKELY(text.isEmpty())) {
/**
* handle line empty context switches
* guard against endless loops
* see https://phabricator.kde.org/D18509
*/
int endlessLoopingCounter = 0;
while (!stateData->topContext()->lineEmptyContext().isStay() || !stateData->topContext()->lineEndContext().isStay()) {
while (!stateData->topContext()->lineEmptyContext().isStay()) {
/**
* line empty context switches
*/
if (!stateData->topContext()->lineEmptyContext().isStay()) {
if (!d->switchContext(stateData, stateData->topContext()->lineEmptyContext(), QStringList())) {
/**
* end when trying to #pop the main context
*/
break;
}
if (!d->switchContext(stateData, stateData->topContext()->lineEmptyContext(), QStringList(), newState, isSharedData)) {
/**
* line end context switches only when lineEmptyContext is #stay. This avoids
* skipping empty lines after a line continuation character (see bug 405903)
* end when trying to #pop the main context
*/
} else if (!d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList())) {
break;
}
if (stateData->topContext()->stopEmptyLineContextSwitchLoop()) {
break;
}
@@ -165,9 +163,11 @@ State AbstractHighlighter::highlightLine(QStringView text, const State &state)
}
auto context = stateData->topContext();
applyFormat(0, 0, context->attributeFormat());
return newState;
return *defData->unify.insert(newState);
}
auto &dynamicRegexpCache = RepositoryPrivate::get(defData->repo)->m_dynamicRegexpCache;
int offset = 0;
int beginOffset = 0;
bool lineContinuation = false;
@@ -178,10 +178,10 @@ State AbstractHighlighter::highlightLine(QStringView text, const State &state)
* - store the result of the first position that matches (or -1 for no match in the full line) in the skipOffsets hash for re-use
* - have capturesForLastDynamicSkipOffset as guard for dynamic regexes to invalidate the cache if they might have changed
*/
QVarLengthArray<QPair<Rule *, int>, 8> skipOffsets;
QVarLengthArray<QPair<const Rule *, int>, 8> skipOffsets;
QStringList capturesForLastDynamicSkipOffset;
auto getSkipOffsetValue = [&skipOffsets](Rule *r) -> int {
auto getSkipOffsetValue = [&skipOffsets](const Rule *r) -> int {
auto i = std::find_if(skipOffsets.begin(), skipOffsets.end(), [r](const auto &v) {
return v.first == r;
});
@@ -190,7 +190,7 @@ State AbstractHighlighter::highlightLine(QStringView text, const State &state)
return i->second;
};
auto insertSkipOffset = [&skipOffsets](Rule *r, int i) {
auto insertSkipOffset = [&skipOffsets](const Rule *r, int i) {
auto it = std::find_if(skipOffsets.begin(), skipOffsets.end(), [r](const auto &v) {
return v.first == r;
});
@@ -237,7 +237,8 @@ State AbstractHighlighter::highlightLine(QStringView text, const State &state)
bool isLookAhead = false;
int newOffset = 0;
const Format *newFormat = nullptr;
for (const auto &rule : stateData->topContext()->rules()) {
for (const auto &ruleShared : stateData->topContext()->rules()) {
auto rule = ruleShared.get();
/**
* filter out rules that require a specific column
*/
@@ -265,29 +266,33 @@ State AbstractHighlighter::highlightLine(QStringView text, const State &state)
}
}
/**
* shall we skip application of this rule? two cases:
* - rule can't match at all => currentSkipOffset < 0
* - rule will only match for some higher offset => currentSkipOffset > offset
*
* we need to invalidate this if we are dynamic and have different captures then last time
*/
if (rule->isDynamic() && (capturesForLastDynamicSkipOffset != stateData->topCaptures())) {
skipOffsets.clear();
}
const auto currentSkipOffset = getSkipOffsetValue(rule.get());
if (currentSkipOffset < 0 || currentSkipOffset > offset) {
continue;
int currentSkipOffset = 0;
if (Q_UNLIKELY(rule->hasSkipOffset())) {
/**
* shall we skip application of this rule? two cases:
* - rule can't match at all => currentSkipOffset < 0
* - rule will only match for some higher offset => currentSkipOffset > offset
*
* we need to invalidate this if we are dynamic and have different captures then last time
*/
if (rule->isDynamic() && (capturesForLastDynamicSkipOffset != stateData->topCaptures())) {
skipOffsets.clear();
} else {
currentSkipOffset = getSkipOffsetValue(rule);
if (currentSkipOffset < 0 || currentSkipOffset > offset) {
continue;
}
}
}
const auto newResult = rule->doMatch(text, offset, stateData->topCaptures());
auto newResult = rule->doMatch(text, offset, stateData->topCaptures(), dynamicRegexpCache);
newOffset = newResult.offset();
/**
* update skip offset if new one rules out any later match or is larger than current one
*/
if (newResult.skipOffset() < 0 || newResult.skipOffset() > currentSkipOffset) {
insertSkipOffset(rule.get(), newResult.skipOffset());
insertSkipOffset(rule, newResult.skipOffset());
// remember new captures, if dynamic to enforce proper reset above on change!
if (rule->isDynamic()) {
@@ -316,12 +321,12 @@ State AbstractHighlighter::highlightLine(QStringView text, const State &state)
if (rule->isLookAhead()) {
Q_ASSERT(!rule->context().isStay());
d->switchContext(stateData, rule->context(), newResult.captures());
d->switchContext(stateData, rule->context(), std::move(newResult.captures()), newState, isSharedData);
isLookAhead = true;
break;
}
d->switchContext(stateData, rule->context(), newResult.captures());
d->switchContext(stateData, rule->context(), std::move(newResult.captures()), newState, isSharedData);
newFormat = rule->attributeFormat().isValid() ? &rule->attributeFormat() : &stateData->topContext()->attributeFormat();
if (newOffset == text.size() && rule->isLineContinue()) {
lineContinuation = true;
@@ -334,7 +339,7 @@ State AbstractHighlighter::highlightLine(QStringView text, const State &state)
if (newOffset <= offset) { // no matching rule
if (stateData->topContext()->fallthrough()) {
d->switchContext(stateData, stateData->topContext()->fallthroughContext(), QStringList());
d->switchContext(stateData, stateData->topContext()->fallthroughContext(), QStringList(), newState, isSharedData);
continue;
}
@@ -381,7 +386,7 @@ State AbstractHighlighter::highlightLine(QStringView 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(), newState, isSharedData)) {
break;
}
@@ -394,18 +399,30 @@ State AbstractHighlighter::highlightLine(QStringView text, const State &state)
}
}
return newState;
return *defData->unify.insert(newState);
}
bool AbstractHighlighterPrivate::switchContext(StateData *data, const ContextSwitch &contextSwitch, const QStringList &captures)
bool AbstractHighlighterPrivate::switchContext(StateData *&data, const ContextSwitch &contextSwitch, QStringList &&captures, State &state, bool &isSharedData)
{
const auto popCount = contextSwitch.popCount();
const auto context = contextSwitch.context();
if (popCount <= 0 && !context) {
return true;
}
// a modified state must be detached before modification
if (isSharedData) {
data = StateData::detach(state);
isSharedData = false;
}
// kill as many items as requested from the stack, will always keep the initial context alive!
const bool initialContextSurvived = data->pop(contextSwitch.popCount());
const bool initialContextSurvived = data->pop(popCount);
// if we have a new context to add, push it
// then we always "succeed"
if (contextSwitch.context()) {
data->push(contextSwitch.context(), captures);
if (context) {
data->push(context, std::move(captures));
return true;
}

View File

@@ -7,20 +7,15 @@
#ifndef KSYNTAXHIGHLIGHTING_ABSTRACTHIGHLIGHTERM_H
#define KSYNTAXHIGHLIGHTING_ABSTRACTHIGHLIGHTERM_H
#include "definition.h"
#include "ksyntaxhighlighting_export.h"
#include <QObject>
#include <memory>
QT_BEGIN_NAMESPACE
class QString;
QT_END_NAMESPACE
#include <QStringView>
namespace KSyntaxHighlighting
{
class AbstractHighlighterPrivate;
class Definition;
class FoldingRegion;
class Format;
class State;
@@ -106,21 +101,8 @@ public:
protected:
AbstractHighlighter();
AbstractHighlighter(AbstractHighlighterPrivate *dd);
KSYNTAXHIGHLIGHTING_NO_EXPORT explicit 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
// this context available in their applyX methods
/**
* Highlight the given line. Call this from your derived class
* where appropriate. This will result in any number of applyFormat()

View File

@@ -14,6 +14,7 @@ namespace KSyntaxHighlighting
{
class ContextSwitch;
class StateData;
class State;
class AbstractHighlighterPrivate
{
@@ -22,7 +23,7 @@ public:
virtual ~AbstractHighlighterPrivate();
void ensureDefinitionLoaded();
bool switchContext(StateData *data, const ContextSwitch &contextSwitch, const QStringList &captures);
bool switchContext(StateData *&data, const ContextSwitch &contextSwitch, QStringList &&captures, State &state, bool &isSharedData);
Definition m_definition;
Theme m_theme;

View File

@@ -5,6 +5,7 @@
*/
#include "ansihighlighter.h"
#include "abstracthighlighter_p.h"
#include "context_p.h"
#include "definition.h"
#include "definition_p.h"
@@ -18,6 +19,7 @@
#include <QFile>
#include <QFileInfo>
#include <QHash>
#include <QIODevice>
#include <QTextStream>
#include <cmath>
@@ -783,7 +785,7 @@ GraphLine &lineAtOffset(std::vector<GraphLine> &graphLines, int offset)
}
// disable bold, italic and underline on |
const QLatin1String graphSymbol("\x1b[21;23;24m|");
const QLatin1String graphSymbol("\x1b[22;23;24m|");
// reverse video
const QLatin1String nameStyle("\x1b[7m");
@@ -793,8 +795,8 @@ const QLatin1String nameStyle("\x1b[7m");
class DebugSyntaxHighlighter : public KSyntaxHighlighting::AbstractHighlighter
{
public:
using TraceOption = KSyntaxHighlighting::AnsiHighlighter::TraceOption;
using TraceOptions = KSyntaxHighlighting::AnsiHighlighter::TraceOptions;
using Option = KSyntaxHighlighting::AnsiHighlighter::Option;
using Options = KSyntaxHighlighting::AnsiHighlighter::Options;
void setDefinition(const KSyntaxHighlighting::Definition &def) override
{
@@ -815,14 +817,14 @@ public:
QLatin1String infoStyle,
QLatin1String editorBackground,
const std::vector<QPair<QString, QString>> &ansiStyles,
TraceOptions traceOptions)
Options options)
{
initRegionStyles(ansiStyles);
m_hasFormatTrace = traceOptions.testFlag(TraceOption::Format);
m_hasRegionTrace = traceOptions.testFlag(TraceOption::Region);
m_hasStackSizeTrace = traceOptions.testFlag(TraceOption::StackSize);
m_hasContextTrace = traceOptions.testFlag(TraceOption::Context);
m_hasFormatTrace = options.testFlag(Option::TraceFormat);
m_hasRegionTrace = options.testFlag(Option::TraceRegion);
m_hasStackSizeTrace = options.testFlag(Option::TraceStackSize);
m_hasContextTrace = options.testFlag(Option::TraceContext);
const bool hasFormatOrContextTrace = m_hasFormatTrace || m_hasContextTrace || m_hasStackSizeTrace;
const bool hasSeparator = hasFormatOrContextTrace && m_hasRegionTrace;
@@ -831,6 +833,7 @@ public:
bool firstLine = true;
State state;
QString currentLine;
const bool isUnbuffered = options.testFlag(Option::Unbuffered);
while (in.readLineInto(&currentLine)) {
auto oldState = state;
state = highlightLine(currentLine, state);
@@ -864,6 +867,10 @@ public:
}
m_highlightedFragments.clear();
if (isUnbuffered) {
out.flush();
}
}
}
@@ -970,12 +977,14 @@ private:
QString label;
if (m_hasStackSizeTrace) {
label += QLatin1Char('(') % QString::number(stateData->size()) % QLatin1Char(')');
// first state is empty
int stateSize = stateData ? stateData->size() : 0;
label = QLatin1Char('(') % QString::number(stateSize) % QLatin1Char(')');
}
if (m_hasContextTrace) {
// first state is empty
if (stateData->isEmpty()) {
if (!stateData) {
return label + QStringLiteral("[???]");
}
@@ -1138,7 +1147,7 @@ private:
QString name;
int offset;
int length;
quint16 formatId;
int formatId;
};
struct ContextCaptureHighlighter : KSyntaxHighlighting::AbstractHighlighter {
@@ -1168,7 +1177,7 @@ private:
int depth;
int offset;
int bindIndex;
quint16 regionId;
int regionId;
State state;
};
@@ -1190,7 +1199,7 @@ private:
};
} // anonymous namespace
class KSyntaxHighlighting::AnsiHighlighterPrivate
class KSyntaxHighlighting::AnsiHighlighterPrivate : public AbstractHighlighterPrivate
{
public:
QTextStream out;
@@ -1201,7 +1210,7 @@ public:
};
AnsiHighlighter::AnsiHighlighter()
: d(new AnsiHighlighterPrivate())
: AbstractHighlighter(new AnsiHighlighterPrivate())
{
}
@@ -1209,6 +1218,7 @@ AnsiHighlighter::~AnsiHighlighter() = default;
void AnsiHighlighter::setOutputFile(const QString &fileName)
{
Q_D(AnsiHighlighter);
if (d->file.isOpen()) {
d->file.close();
}
@@ -1218,21 +1228,16 @@ void AnsiHighlighter::setOutputFile(const QString &fileName)
return;
}
d->out.setDevice(&d->file);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
d->out.setCodec("UTF-8");
#endif
}
void AnsiHighlighter::setOutputFile(FILE *fileHandle)
{
Q_D(AnsiHighlighter);
d->file.open(fileHandle, QIODevice::WriteOnly);
d->out.setDevice(&d->file);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
d->out.setCodec("UTF-8");
#endif
}
void AnsiHighlighter::highlightFile(const QString &fileName, AnsiFormat format, bool useEditorBackground, TraceOptions traceOptions)
void AnsiHighlighter::highlightFile(const QString &fileName, AnsiFormat format, Options options)
{
QFileInfo fi(fileName);
QFile f(fileName);
@@ -1241,19 +1246,21 @@ void AnsiHighlighter::highlightFile(const QString &fileName, AnsiFormat format,
return;
}
highlightData(&f, format, useEditorBackground, traceOptions);
highlightData(&f, format, options);
}
void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useEditorBackground, TraceOptions traceOptions)
void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, Options options)
{
Q_D(AnsiHighlighter);
if (!d->out.device()) {
qCWarning(Log) << "No output stream defined!";
return;
}
const auto is256Colors = (format == AnsiFormat::XTerm256Color);
const auto theme = this->theme();
const auto definition = this->definition();
const auto &theme = d->m_theme;
const auto &definition = d->m_definition;
auto definitions = definition.includedDefinitions();
definitions.append(definition);
@@ -1265,6 +1272,8 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
QLatin1String foregroundDefaultColor;
QLatin1String backgroundDefaultColor;
const bool useEditorBackground = options.testFlag(Option::UseEditorBackground);
// https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
if (useEditorBackground) {
@@ -1277,23 +1286,19 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
backgroundDefaultColor = backgroundColorBuffer.latin1().mid(2);
}
// ansiStyles must not be empty for applyFormat to work even with a definition without any context
if (d->ansiStyles.empty()) {
d->ansiStyles.resize(32);
} else {
d->ansiStyles[0].first.clear();
d->ansiStyles[0].second.clear();
int maxId = 0;
for (const auto &definition : std::as_const(definitions)) {
for (const auto &format : std::as_const(DefinitionData::get(definition)->formats)) {
maxId = qMax(maxId, format.id());
}
}
d->ansiStyles.clear();
// ansiStyles must not be empty for applyFormat to work even with a definition without any context
d->ansiStyles.resize(maxId + 1);
// initialize ansiStyles
for (auto &&definition : std::as_const(definitions)) {
for (auto &&format : std::as_const(DefinitionData::get(definition)->formats)) {
const auto id = format.id();
if (id >= d->ansiStyles.size()) {
// better than id + 1 to avoid successive allocations
d->ansiStyles.resize(id * 2);
}
for (const auto &definition : std::as_const(definitions)) {
for (const auto &format : std::as_const(DefinitionData::get(definition)->formats)) {
AnsiBuffer buffer;
buffer.append(QLatin1String("\x1b["));
@@ -1329,7 +1334,8 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
// if there is ANSI style
if (buffer.latin1().size() > 2) {
buffer.setFinalStyle();
d->ansiStyles[id].first = buffer.latin1();
auto &style = d->ansiStyles[format.id()];
style.first = buffer.latin1();
if (useEditorBackground) {
buffer.clear();
@@ -1338,11 +1344,11 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
buffer.append(hasEffect ? QLatin1String("\x1b[0;") : QLatin1String("\x1b["));
buffer.append(backgroundDefaultColor);
buffer.setFinalStyle();
d->ansiStyles[id].second = buffer.latin1();
style.second = buffer.latin1();
} else if (hasEffect) {
buffer.append(QLatin1String("\x1b["));
if (hasBold) {
buffer.append(QLatin1String("21;"));
buffer.append(QLatin1String("22;"));
}
if (hasItalic) {
buffer.append(QLatin1String("23;"));
@@ -1354,10 +1360,10 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
buffer.append(QLatin1String("29;"));
}
buffer.setFinalStyle();
d->ansiStyles[id].second = buffer.latin1();
style.second = buffer.latin1();
}
} else {
d->ansiStyles[id].second = QStringLiteral("\x1b[0m");
style.second = QStringLiteral("\x1b[0m");
}
}
}
@@ -1370,13 +1376,11 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
}
QTextStream in(dev);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
in.setCodec("UTF-8");
#endif
if (!traceOptions) {
if (!options.testAnyFlag(Option::TraceAll)) {
State state;
QString currentLine;
const bool isUnbuffered = options.testFlag(Option::Unbuffered);
while (in.readLineInto(&currentLine)) {
d->currentLine = currentLine;
state = highlightLine(d->currentLine, state);
@@ -1386,6 +1390,10 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
} else {
d->out << QLatin1Char('\n');
}
if (isUnbuffered) {
d->out.flush();
}
}
} else {
AnsiBuffer buffer;
@@ -1394,7 +1402,7 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
buffer.setFinalStyle();
DebugSyntaxHighlighter debugHighlighter;
debugHighlighter.setDefinition(definition);
debugHighlighter.highlightData(in, d->out, buffer.latin1(), backgroundDefaultColor, d->ansiStyles, traceOptions);
debugHighlighter.highlightData(in, d->out, buffer.latin1(), backgroundDefaultColor, d->ansiStyles, options);
}
if (useEditorBackground) {
@@ -1408,6 +1416,7 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
void AnsiHighlighter::applyFormat(int offset, int length, const Format &format)
{
Q_D(AnsiHighlighter);
auto const &ansiStyle = d->ansiStyles[format.id()];
d->out << ansiStyle.first << d->currentLine.mid(offset, length) << ansiStyle.second;
}

View File

@@ -11,10 +11,11 @@
#include "ksyntaxhighlighting_export.h"
#include <QFlags>
#include <QIODevice>
#include <QString>
#include <memory>
QT_BEGIN_NAMESPACE
class QIODevice;
QT_END_NAMESPACE
namespace KSyntaxHighlighting
{
@@ -29,24 +30,25 @@ public:
XTerm256Color,
};
enum class TraceOption {
enum class Option {
NoOptions,
Format = 1 << 0,
Region = 1 << 1,
Context = 1 << 2,
StackSize = 1 << 3,
UseEditorBackground = 1 << 0,
Unbuffered = 1 << 1,
// Options that displays a useful visual aid for syntax creation
TraceFormat = 1 << 2,
TraceRegion = 1 << 3,
TraceContext = 1 << 4,
TraceStackSize = 1 << 5,
TraceAll = TraceFormat | TraceRegion | TraceContext | TraceStackSize,
};
Q_DECLARE_FLAGS(TraceOptions, TraceOption)
Q_DECLARE_FLAGS(Options, Option)
AnsiHighlighter();
~AnsiHighlighter() override;
void highlightFile(const QString &fileName,
AnsiFormat format = AnsiFormat::TrueColor,
bool useEditorBackground = true,
TraceOptions traceOptions = TraceOptions());
void
highlightData(QIODevice *device, AnsiFormat format = AnsiFormat::TrueColor, bool useEditorBackground = true, TraceOptions traceOptions = TraceOptions());
void highlightFile(const QString &fileName, AnsiFormat format = AnsiFormat::TrueColor, Options options = Option::UseEditorBackground);
void highlightData(QIODevice *device, AnsiFormat format = AnsiFormat::TrueColor, Options options = Option::UseEditorBackground);
void setOutputFile(const QString &fileName);
void setOutputFile(FILE *fileHandle);
@@ -55,10 +57,10 @@ protected:
void applyFormat(int offset, int length, const Format &format) override;
private:
std::unique_ptr<AnsiHighlighterPrivate> d;
Q_DECLARE_PRIVATE(AnsiHighlighter)
};
}
Q_DECLARE_OPERATORS_FOR_FLAGS(KSyntaxHighlighting::AnsiHighlighter::TraceOptions)
Q_DECLARE_OPERATORS_FOR_FLAGS(KSyntaxHighlighting::AnsiHighlighter::Options)
#endif // KSYNTAXHIGHLIGHTING_ANSIHIGHLIGHTER_H

View File

@@ -38,7 +38,15 @@ void Context::resolveContexts(DefinitionData &def, const HighlightingContextData
m_lineEndContext.resolve(def, data.lineEndContext);
m_lineEmptyContext.resolve(def, data.lineEmptyContext);
m_fallthroughContext.resolve(def, data.fallthroughContext);
m_fallthrough = !m_fallthroughContext.isStay();
m_stopEmptyLineContextSwitchLoop = data.stopEmptyLineContextSwitchLoop;
/**
* line end context switches only when lineEmptyContext is #stay. This avoids
* skipping empty lines after a line continuation character (see bug 405903)
*/
if (m_lineEmptyContext.isStay()) {
m_lineEmptyContext = m_lineEndContext;
}
m_rules.reserve(data.rules.size());
for (const auto &ruleData : data.rules) {
@@ -65,6 +73,7 @@ void Context::resolveIncludes(DefinitionData &def)
for (auto it = m_rules.begin(); it != m_rules.end();) {
const IncludeRules *includeRules = it->get()->castToIncludeRules();
if (!includeRules) {
m_hasDynamicRule = m_hasDynamicRule || it->get()->isDynamic();
++it;
continue;
}
@@ -111,6 +120,8 @@ void Context::resolveIncludes(DefinitionData &def)
context->resolveIncludes(*defData);
}
m_hasDynamicRule = m_hasDynamicRule || context->m_hasDynamicRule;
/**
* handle included attribute
* transitive closure: we might include attributes included from somewhere else

View File

@@ -16,10 +16,6 @@
#include <vector>
QT_BEGIN_NAMESPACE
class QXmlStreamReader;
QT_END_NAMESPACE
namespace KSyntaxHighlighting
{
class DefinitionData;
@@ -52,7 +48,17 @@ public:
bool fallthrough() const
{
return m_fallthrough;
return !m_fallthroughContext.isStay();
}
bool hasDynamicRule() const
{
return m_hasDynamicRule;
}
bool stopEmptyLineContextSwitchLoop() const
{
return m_stopEmptyLineContextSwitchLoop;
}
const ContextSwitch &fallthroughContext() const
@@ -96,7 +102,8 @@ private:
Format m_attributeFormat;
ResolveState m_resolveState = Unresolved;
bool m_fallthrough = false;
bool m_hasDynamicRule = false;
bool m_stopEmptyLineContextSwitchLoop = true;
bool m_indentationBasedFolding;
};
}

View File

@@ -26,8 +26,6 @@
#include <QCborMap>
#include <QCoreApplication>
#include <QFile>
#include <QHash>
#include <QStringList>
#include <QXmlStreamReader>
#include <algorithm>
@@ -43,13 +41,8 @@ DefinitionData::DefinitionData()
DefinitionData::~DefinitionData() = default;
DefinitionData *DefinitionData::get(const Definition &def)
{
return def.d.get();
}
Definition::Definition()
: d(new DefinitionData)
: d(std::make_shared<DefinitionData>())
{
d->q = *this;
}
@@ -63,6 +56,9 @@ Definition &Definition::operator=(const Definition &) = default;
Definition::Definition(std::shared_ptr<DefinitionData> &&dd)
: d(std::move(dd))
{
if (!d) {
Definition().d.swap(d);
}
}
bool Definition::operator==(const Definition &other) const
@@ -92,7 +88,10 @@ QString Definition::name() const
QString Definition::translatedName() const
{
return QCoreApplication::instance()->translate("Language", d->name.toUtf8().constData());
if (d->translatedName.isEmpty()) {
d->translatedName = QCoreApplication::instance()->translate("Language", d->nameUtf8.isEmpty() ? d->name.toUtf8().constData() : d->nameUtf8.constData());
}
return d->translatedName;
}
QString Definition::section() const
@@ -102,15 +101,19 @@ QString Definition::section() const
QString Definition::translatedSection() const
{
return QCoreApplication::instance()->translate("Language Section", d->section.toUtf8().constData());
if (d->translatedSection.isEmpty()) {
d->translatedSection = QCoreApplication::instance()->translate("Language Section",
d->sectionUtf8.isEmpty() ? d->section.toUtf8().constData() : d->sectionUtf8.constData());
}
return d->translatedSection;
}
QVector<QString> Definition::mimeTypes() const
QList<QString> Definition::mimeTypes() const
{
return d->mimetypes;
}
QVector<QString> Definition::extensions() const
QList<QString> Definition::extensions() const
{
return d->extensions;
}
@@ -218,12 +221,12 @@ bool Definition::setKeywordList(const QString &name, const QStringList &content)
}
}
QVector<Format> Definition::formats() const
QList<Format> Definition::formats() const
{
d->load();
// sort formats so that the order matches the order of the itemDatas in the xml files.
auto formatList = QVector<Format>::fromList(d->formats.values());
auto formatList = d->formats.values();
std::sort(formatList.begin(), formatList.end(), [](const KSyntaxHighlighting::Format &lhs, const KSyntaxHighlighting::Format &rhs) {
return lhs.id() < rhs.id();
});
@@ -231,13 +234,13 @@ QVector<Format> Definition::formats() const
return formatList;
}
QVector<Definition> Definition::includedDefinitions() const
QList<Definition> Definition::includedDefinitions() const
{
d->load();
// init worklist and result used as guard with this definition
QVector<const DefinitionData *> queue{d.get()};
QVector<Definition> definitions{*this};
QList<const DefinitionData *> queue{d.get()};
QList<Definition> definitions{*this};
while (!queue.empty()) {
const auto *def = queue.back();
queue.pop_back();
@@ -275,7 +278,7 @@ QPair<QString, QString> Definition::multiLineCommentMarker() const
return {d->multiLineCommentStartMarker, d->multiLineCommentEndMarker};
}
QVector<QPair<QChar, QString>> Definition::characterEncodings() const
QList<QPair<QChar, QString>> Definition::characterEncodings() const
{
d->load();
return d->characterEncodings;
@@ -394,7 +397,11 @@ void DefinitionData::clear()
characterEncodings.clear();
fileName.clear();
nameUtf8.clear();
translatedName.clear();
section.clear();
sectionUtf8.clear();
translatedSection.clear();
style.clear();
indenter.clear();
author.clear();
@@ -405,6 +412,9 @@ void DefinitionData::clear()
version = 0.0f;
priority = 0;
hidden = false;
// purge our cache that is used to unify states
unify.clear();
}
bool DefinitionData::loadMetaData(const QString &definitionFileName)
@@ -433,7 +443,9 @@ bool DefinitionData::loadMetaData(const QString &definitionFileName)
bool DefinitionData::loadMetaData(const QString &file, const QCborMap &obj)
{
name = obj.value(QLatin1String("name")).toString();
nameUtf8 = obj.value(QLatin1String("name")).toByteArray();
section = obj.value(QLatin1String("section")).toString();
sectionUtf8 = obj.value(QLatin1String("section")).toByteArray();
version = obj.value(QLatin1String("version")).toInteger();
priority = obj.value(QLatin1String("priority")).toInteger();
style = obj.value(QLatin1String("style")).toString();
@@ -444,13 +456,10 @@ 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)) {
extensions.push_back(ext);
}
extensions = exts.split(QLatin1Char(';'), Qt::SkipEmptyParts);
const auto mts = obj.value(QLatin1String("mimetype")).toString();
for (const auto &mt : mts.split(QLatin1Char(';'), Qt::SkipEmptyParts)) {
mimetypes.push_back(mt);
}
mimetypes = mts.split(QLatin1Char(';'), Qt::SkipEmptyParts);
return true;
}
@@ -805,10 +814,10 @@ bool DefinitionData::checkKateVersion(QStringView verStr)
qCWarning(Log) << "Skipping" << fileName << "due to having no valid kateversion attribute:" << verStr;
return false;
}
const auto major = verStr.left(idx).toString().toInt();
const auto minor = verStr.mid(idx + 1).toString().toInt();
const auto major = verStr.left(idx).toInt();
const auto minor = verStr.mid(idx + 1).toInt();
if (major > SyntaxHighlighting_VERSION_MAJOR || (major == SyntaxHighlighting_VERSION_MAJOR && minor > SyntaxHighlighting_VERSION_MINOR)) {
if (major > KSYNTAXHIGHLIGHTING_VERSION_MAJOR || (major == KSYNTAXHIGHLIGHTING_VERSION_MAJOR && minor > KSYNTAXHIGHLIGHTING_VERSION_MINOR)) {
qCWarning(Log) << "Skipping" << fileName << "due to being too new, version:" << verStr;
return false;
}
@@ -834,34 +843,20 @@ void DefinitionData::addImmediateIncludedDefinition(const Definition &def)
DefinitionRef::DefinitionRef() = default;
DefinitionRef::DefinitionRef(const Definition &def)
DefinitionRef::DefinitionRef(const Definition &def) noexcept
: d(def.d)
{
}
DefinitionRef::DefinitionRef(Definition &&def)
: d(std::move(def.d))
{
}
DefinitionRef &DefinitionRef::operator=(const Definition &def)
DefinitionRef &DefinitionRef::operator=(const Definition &def) noexcept
{
d = def.d;
return *this;
}
DefinitionRef &DefinitionRef::operator=(Definition &&def)
{
d = std::move(def.d);
return *this;
}
Definition DefinitionRef::definition() const
{
if (!d.expired()) {
return Definition(d.lock());
}
return Definition();
return Definition(d.lock());
}
bool DefinitionRef::operator==(const DefinitionRef &other) const
@@ -873,3 +868,5 @@ bool DefinitionRef::operator==(const Definition &other) const
{
return !d.owner_before(other.d) && !other.d.owner_before(d);
}
#include "moc_definition.cpp"

View File

@@ -10,16 +10,12 @@
#include "ksyntaxhighlighting_export.h"
#include <QList>
#include <QPair>
#include <QVector>
#include <QString>
#include <memory>
#include <qobjectdefs.h>
QT_BEGIN_NAMESPACE
class QChar;
class QString;
QT_END_NAMESPACE
namespace KSyntaxHighlighting
{
class Context;
@@ -185,13 +181,13 @@ public:
/**
* Mime types associated with this syntax definition.
*/
QVector<QString> mimeTypes() const;
QList<QString> mimeTypes() const;
/**
* File extensions associated with this syntax definition.
* The returned list contains wildcards.
*/
QVector<QString> extensions() const;
QList<QString> extensions() const;
/**
* Returns the definition version.
@@ -360,7 +356,7 @@ public:
* The order of the Format items equals the order of the itemDatas in the xml file.
* @since 5.49
*/
QVector<Format> formats() const;
QList<Format> formats() const;
/**
* Returns a list of Definitions that are referenced with the IncludeRules rule.
@@ -369,7 +365,7 @@ public:
*
* @since 5.49
*/
QVector<Definition> includedDefinitions() const;
QList<Definition> includedDefinitions() const;
/**
* Returns the marker that starts a single line comment.
@@ -400,7 +396,7 @@ public:
* the string \"{A} represents the character Ä.
* @since 5.50
*/
QVector<QPair<QChar, QString>> characterEncodings() const;
QList<QPair<QChar, QString>> characterEncodings() const;
/**
* @}
@@ -409,14 +405,14 @@ public:
private:
friend class DefinitionData;
friend class DefinitionRef;
explicit Definition(std::shared_ptr<DefinitionData> &&dd);
KSYNTAXHIGHLIGHTING_NO_EXPORT explicit Definition(std::shared_ptr<DefinitionData> &&dd);
std::shared_ptr<DefinitionData> d;
};
}
QT_BEGIN_NAMESPACE
Q_DECLARE_TYPEINFO(KSyntaxHighlighting::Definition, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(KSyntaxHighlighting::Definition, Q_RELOCATABLE_TYPE);
QT_END_NAMESPACE
#endif

View File

@@ -10,11 +10,13 @@
#include "definitionref_p.h"
#include "highlightingdata_p.hpp"
#include "state.h"
#include "worddelimiters_p.h"
#include <QHash>
#include <QList>
#include <QSet>
#include <QString>
#include <QVector>
#include <vector>
@@ -36,7 +38,10 @@ public:
DefinitionData(const DefinitionData &) = delete;
DefinitionData &operator=(const DefinitionData &) = delete;
static DefinitionData *get(const Definition &def);
static DefinitionData *get(const Definition &def)
{
return def.d.get();
}
bool isLoaded() const;
bool loadMetaData(const QString &definitionFileName);
@@ -80,9 +85,9 @@ public:
std::vector<Context> contexts;
QHash<QString, Format> formats;
// data loaded from xml file and emptied after loading contexts
QVector<HighlightingContextData> contextDatas;
QList<HighlightingContextData> contextDatas;
// Definition referenced by IncludeRules and ContextSwitch
QVector<DefinitionRef> immediateIncludedDefinitions;
QList<DefinitionRef> immediateIncludedDefinitions;
WordDelimiters wordDelimiters;
WordDelimiters wordWrapDelimiters;
bool keywordIsLoaded = false;
@@ -93,21 +98,28 @@ public:
CommentPosition singleLineCommentPosition = CommentPosition::StartOfLine;
QString multiLineCommentStartMarker;
QString multiLineCommentEndMarker;
QVector<QPair<QChar, QString>> characterEncodings;
QList<QPair<QChar, QString>> characterEncodings;
QString fileName;
QString name = QStringLiteral(QT_TRANSLATE_NOOP("Language", "None"));
QByteArray nameUtf8;
mutable QString translatedName;
QString section;
QByteArray sectionUtf8;
mutable QString translatedSection;
QString style;
QString indenter;
QString author;
QString license;
QVector<QString> mimetypes;
QVector<QString> extensions;
QList<QString> mimetypes;
QList<QString> extensions;
Qt::CaseSensitivity caseSensitive = Qt::CaseSensitive;
int version = 0;
int priority = 0;
bool hidden = false;
// cache that is used to unify states in AbstractHighlighter::highlightLine
mutable QSet<State> unify;
};
}

View File

@@ -169,8 +169,8 @@ DefinitionDownloader::~DefinitionDownloader()
void DefinitionDownloader::start()
{
const QString url = QLatin1String("https://www.kate-editor.org/syntax/update-") + QString::number(SyntaxHighlighting_VERSION_MAJOR) + QLatin1Char('.')
+ QString::number(SyntaxHighlighting_VERSION_MINOR) + QLatin1String(".xml");
const QString url = QLatin1String("https://www.kate-editor.org/syntax/update-") + QString::number(KSYNTAXHIGHLIGHTING_VERSION_MAJOR) + QLatin1Char('.')
+ QString::number(KSYNTAXHIGHLIGHTING_VERSION_MINOR) + QLatin1String(".xml");
auto req = QNetworkRequest(QUrl(url));
req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
auto reply = d->nam->get(req);
@@ -178,3 +178,5 @@ void DefinitionDownloader::start()
d->definitionListDownloadFinished(reply);
});
}
#include "moc_definitiondownloader.cpp"

View File

@@ -30,10 +30,8 @@ class DefinitionRef
{
public:
DefinitionRef();
explicit DefinitionRef(const Definition &def);
explicit DefinitionRef(Definition &&def);
DefinitionRef &operator=(const Definition &def);
DefinitionRef &operator=(Definition &&def);
explicit DefinitionRef(const Definition &def) noexcept;
DefinitionRef &operator=(const Definition &def) noexcept;
Definition definition() const;

View File

@@ -0,0 +1,39 @@
/*
SPDX-FileCopyrightText: 2023 Jonathan Poelen <jonathan.poelen+kde@gmail.com>
SPDX-License-Identifier: MIT
*/
#ifndef KSYNTAXHIGHLIGHTING_DYNAMICREGEXPCACHE_P_H
#define KSYNTAXHIGHLIGHTING_DYNAMICREGEXPCACHE_P_H
#include <QCache>
#include <QRegularExpression>
#include <QString>
#include <utility>
namespace KSyntaxHighlighting
{
class DynamicRegexpCache
{
public:
const QRegularExpression &compileRegexp(QString &&pattern, QRegularExpression::PatternOptions patternOptions)
{
const auto key = std::pair{std::move(pattern), patternOptions};
if (const auto regexp = m_cache.object(key)) {
return *regexp;
}
auto regexp = new QRegularExpression(key.first, patternOptions);
m_cache.insert(key, regexp);
return *regexp;
}
private:
QCache<std::pair<QString, QRegularExpression::PatternOptions>, QRegularExpression> m_cache;
};
}
#endif

View File

@@ -8,36 +8,39 @@
using namespace KSyntaxHighlighting;
static_assert(sizeof(FoldingRegion) == 2, "FoldingRegion is size-sensitive to frequent use in KTextEditor!");
static_assert(sizeof(FoldingRegion) == sizeof(int), "FoldingRegion is size-sensitive to frequent use in KTextEditor!");
FoldingRegion::FoldingRegion()
: m_type(None)
, m_id(0)
{
}
FoldingRegion::FoldingRegion() = default;
FoldingRegion::FoldingRegion(Type type, quint16 id)
: m_type(type)
, m_id(id)
FoldingRegion::FoldingRegion(Type type, int id)
: m_idWithType((type == End) ? -id : id)
{
}
bool FoldingRegion::operator==(const FoldingRegion &other) const
{
return m_id == other.m_id && m_type == other.m_type;
return m_idWithType == other.m_idWithType;
}
bool FoldingRegion::isValid() const
{
return type() != None;
return m_idWithType != 0;
}
quint16 FoldingRegion::id() const
int FoldingRegion::id() const
{
return m_id;
return (m_idWithType < 0) ? -m_idWithType : m_idWithType;
}
FoldingRegion::Type FoldingRegion::type() const
{
return static_cast<FoldingRegion::Type>(m_type);
if (isValid()) {
return (m_idWithType < 0) ? End : Begin;
}
return None;
}
FoldingRegion FoldingRegion::sibling() const
{
return isValid() ? FoldingRegion(type() ? End : Begin, id()) : FoldingRegion();
}

View File

@@ -22,7 +22,7 @@ public:
* Defines whether a FoldingRegion starts or ends a folding region.
*/
enum Type {
//! Used internally as indicator for invalid FoldingRegion%s.
//! Used internally as indicator for an invalid FoldingRegion.
None,
//! Indicates the start of a FoldingRegion.
Begin,
@@ -64,7 +64,7 @@ public:
* brace, you need to do kind of a reference counting to find the correct
* closing brace.
*/
quint16 id() const;
int id() const;
/**
* Returns whether this is the begin or end of a region.
@@ -74,12 +74,21 @@ public:
*/
Type type() const;
/**
* Returns the matching start or end region.
*
* @note Will return invalid region for an invalid region.
*
* @since 6.0
*/
FoldingRegion sibling() const;
private:
friend class Rule;
FoldingRegion(Type type, quint16 id);
KSYNTAXHIGHLIGHTING_NO_EXPORT FoldingRegion(Type type, int id);
quint16 m_type : 2;
quint16 m_id : 14;
// 0 is invalid, positive begin, negative end
int m_idWithType = 0;
};
}

View File

@@ -98,7 +98,7 @@ QString Format::name() const
return d->name;
}
quint16 Format::id() const
int Format::id() const
{
return d->id;
}

View File

@@ -13,12 +13,6 @@
#include <QExplicitlySharedDataPointer>
QT_BEGIN_NAMESPACE
class QColor;
class QString;
class QXmlStreamReader;
QT_END_NAMESPACE
namespace KSyntaxHighlighting
{
class FormatPrivate;
@@ -54,7 +48,7 @@ public:
* the repository is reloaded (which also invalidatess the corresponding
* Definition anyway).
*/
quint16 id() const;
int id() const;
/** Returns the underlying TextStyle of this Format.
* Every Theme::TextStyle is visually defined by a Theme. A Format uses one
@@ -192,7 +186,7 @@ private:
}
QT_BEGIN_NAMESPACE
Q_DECLARE_TYPEINFO(KSyntaxHighlighting::Format, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(KSyntaxHighlighting::Format, Q_RELOCATABLE_TYPE);
QT_END_NAMESPACE
#endif // KSYNTAXHIGHLIGHTING_FORMAT_H

View File

@@ -13,6 +13,10 @@
#include <QSharedData>
#include <QString>
QT_BEGIN_NAMESPACE
class QXmlStreamReader;
QT_END_NAMESPACE
namespace KSyntaxHighlighting
{
class FormatPrivate : public QSharedData
@@ -21,6 +25,11 @@ public:
FormatPrivate() = default;
static FormatPrivate *detachAndGet(Format &format);
static std::intptr_t ptrId(const Format &format)
{
return std::intptr_t(format.d.data());
}
TextStyleData styleOverride(const Theme &theme) const;
void load(QXmlStreamReader &reader);
@@ -33,7 +42,7 @@ public:
QString name;
TextStyleData style;
Theme::TextStyle defaultStyle = Theme::Normal;
quint16 id = 0;
int id = 0;
bool spellCheck = true;
};

View File

@@ -379,6 +379,7 @@ void HighlightingContextData::load(const QString &defName, QXmlStreamReader &rea
lineEmptyContext = reader.attributes().value(QLatin1String("lineEmptyContext")).toString();
fallthroughContext = reader.attributes().value(QLatin1String("fallthroughContext")).toString();
noIndentationBasedFolding = Xml::attrToBool(reader.attributes().value(QLatin1String("noIndentationBasedFolding")));
stopEmptyLineContextSwitchLoop = Xml::attrToBool(reader.attributes().value(QLatin1String("stopEmptyLineContextSwitchLoop")));
rules.reserve(8);

View File

@@ -208,6 +208,7 @@ public:
std::vector<Rule> rules;
bool stopEmptyLineContextSwitchLoop = false;
bool noIndentationBasedFolding = false;
};
}

View File

@@ -6,7 +6,9 @@
*/
#include "htmlhighlighter.h"
#include "abstracthighlighter_p.h"
#include "definition.h"
#include "definition_p.h"
#include "format.h"
#include "ksyntaxhighlighting_logging.h"
#include "state.h"
@@ -14,21 +16,22 @@
#include <QFile>
#include <QFileInfo>
#include <QIODevice>
#include <QTextStream>
#include <QVarLengthArray>
using namespace KSyntaxHighlighting;
class KSyntaxHighlighting::HtmlHighlighterPrivate
class KSyntaxHighlighting::HtmlHighlighterPrivate : public AbstractHighlighterPrivate
{
public:
std::unique_ptr<QTextStream> out;
std::unique_ptr<QFile> file;
QString currentLine;
std::vector<QString> htmlStyles;
};
HtmlHighlighter::HtmlHighlighter()
: d(new HtmlHighlighterPrivate())
: AbstractHighlighter(new HtmlHighlighterPrivate())
{
}
@@ -38,27 +41,21 @@ HtmlHighlighter::~HtmlHighlighter()
void HtmlHighlighter::setOutputFile(const QString &fileName)
{
Q_D(HtmlHighlighter);
d->file.reset(new QFile(fileName));
if (!d->file->open(QFile::WriteOnly | QFile::Truncate)) {
qCWarning(Log) << "Failed to open output file" << fileName << ":" << d->file->errorString();
return;
}
d->out.reset(new QTextStream(d->file.get()));
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
d->out->setEncoding(QStringConverter::Utf8);
#else
d->out->setCodec("UTF-8");
#endif
}
void HtmlHighlighter::setOutputFile(FILE *fileHandle)
{
Q_D(HtmlHighlighter);
d->out.reset(new QTextStream(fileHandle, QIODevice::WriteOnly));
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
d->out->setEncoding(QStringConverter::Utf8);
#else
d->out->setCodec("UTF-8");
#endif
}
void HtmlHighlighter::highlightFile(const QString &fileName, const QString &title)
@@ -79,7 +76,7 @@ void HtmlHighlighter::highlightFile(const QString &fileName, const QString &titl
/**
* @brief toHtmlRgba
* Converts QColor -> rgba(r, g, b, a) if there is an alpha channel
* Converts QColor -> #RRGGBBAA if there is an alpha channel
* otherwise it will just return the hexcode. This is because QColor
* outputs #AARRGGBB, whereas browser support #RRGGBBAA.
*
@@ -91,22 +88,24 @@ static QString toHtmlRgbaString(const QColor &color)
if (color.alpha() == 0xFF) {
return color.name();
}
QString rgba = QStringLiteral("rgba(");
rgba.append(QString::number(color.red()));
rgba.append(QLatin1Char(','));
rgba.append(QString::number(color.green()));
rgba.append(QLatin1Char(','));
rgba.append(QString::number(color.blue()));
rgba.append(QLatin1Char(','));
// this must be alphaF
rgba.append(QString::number(color.alphaF()));
rgba.append(QLatin1Char(')'));
return rgba;
static const char16_t digits[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
QChar hexcode[9];
hexcode[0] = QLatin1Char('#');
hexcode[1] = digits[color.red() >> 4];
hexcode[2] = digits[color.red() & 0xf];
hexcode[3] = digits[color.green() >> 4];
hexcode[4] = digits[color.green() & 0xf];
hexcode[5] = digits[color.blue() >> 4];
hexcode[6] = digits[color.blue() & 0xf];
hexcode[7] = digits[color.alpha() >> 4];
hexcode[8] = digits[color.alpha() & 0xf];
return QString(hexcode, 9);
}
void HtmlHighlighter::highlightData(QIODevice *dev, const QString &title)
{
Q_D(HtmlHighlighter);
if (!d->out) {
qCWarning(Log) << "No output stream defined!";
return;
@@ -114,29 +113,73 @@ void HtmlHighlighter::highlightData(QIODevice *dev, const QString &title)
QString htmlTitle;
if (title.isEmpty()) {
htmlTitle = QStringLiteral("Kate Syntax Highlighter");
htmlTitle = QStringLiteral("KSyntaxHighlighter");
} else {
htmlTitle = title.toHtmlEscaped();
}
const auto &theme = d->m_theme;
const auto &definition = d->m_definition;
auto definitions = definition.includedDefinitions();
definitions.append(definition);
int maxId = 0;
for (const auto &definition : std::as_const(definitions)) {
for (const auto &format : std::as_const(DefinitionData::get(definition)->formats)) {
maxId = qMax(maxId, format.id());
}
}
d->htmlStyles.clear();
// htmlStyles must not be empty for applyFormat to work even with a definition without any context
d->htmlStyles.resize(maxId + 1);
// initialize htmlStyles
for (const auto &definition : std::as_const(definitions)) {
for (const auto &format : std::as_const(DefinitionData::get(definition)->formats)) {
auto &buffer = d->htmlStyles[format.id()];
if (format.hasTextColor(theme)) {
buffer += QStringLiteral("color:") + toHtmlRgbaString(format.textColor(theme)) + QStringLiteral(";");
}
if (format.hasBackgroundColor(theme)) {
buffer += QStringLiteral("background-color:") + toHtmlRgbaString(format.backgroundColor(theme)) + QStringLiteral(";");
}
if (format.isBold(theme)) {
buffer += QStringLiteral("font-weight:bold;");
}
if (format.isItalic(theme)) {
buffer += QStringLiteral("font-style:italic;");
}
if (format.isUnderline(theme)) {
buffer += QStringLiteral("text-decoration:underline;");
}
if (format.isStrikeThrough(theme)) {
buffer += QStringLiteral("text-decoration:line-through;");
}
if (!buffer.isEmpty()) {
buffer.insert(0, QStringLiteral("<span style=\""));
// replace last ';'
buffer.back() = u'"';
buffer += u'>';
}
}
}
State state;
*d->out << "<!DOCTYPE html>\n";
*d->out << "<html><head>\n";
*d->out << "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>\n";
*d->out << "<title>" << htmlTitle << "</title>\n";
*d->out << "<meta name=\"generator\" content=\"KF5::SyntaxHighlighting - Definition (" << definition().name() << ") - Theme (" << theme().name()
<< ")\"/>\n";
*d->out << "<meta name=\"generator\" content=\"KF5::SyntaxHighlighting - Definition (" << definition.name() << ") - Theme (" << theme.name() << ")\"/>\n";
*d->out << "</head><body";
*d->out << " style=\"background-color:" << toHtmlRgbaString(QColor::fromRgba(theme().editorColor(Theme::BackgroundColor)));
if (theme().textColor(Theme::Normal)) {
*d->out << ";color:" << toHtmlRgbaString(QColor::fromRgba(theme().textColor(Theme::Normal)));
*d->out << " style=\"background-color:" << toHtmlRgbaString(QColor::fromRgba(theme.editorColor(Theme::BackgroundColor)));
if (theme.textColor(Theme::Normal)) {
*d->out << ";color:" << toHtmlRgbaString(QColor::fromRgba(theme.textColor(Theme::Normal)));
}
*d->out << "\"><pre>\n";
QTextStream in(dev);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
in.setCodec("UTF-8");
#endif
while (in.readLineInto(&d->currentLine)) {
state = highlightLine(d->currentLine, state);
*d->out << "\n";
@@ -155,38 +198,24 @@ void HtmlHighlighter::applyFormat(int offset, int length, const Format &format)
return;
}
// collect potential output, cheaper than thinking about "is there any?"
QVarLengthArray<QString, 16> formatOutput;
if (format.hasTextColor(theme())) {
formatOutput << QStringLiteral("color:") << toHtmlRgbaString(format.textColor(theme())) << QStringLiteral(";");
}
if (format.hasBackgroundColor(theme())) {
formatOutput << QStringLiteral("background-color:") << toHtmlRgbaString(format.backgroundColor(theme())) << QStringLiteral(";");
}
if (format.isBold(theme())) {
formatOutput << QStringLiteral("font-weight:bold;");
}
if (format.isItalic(theme())) {
formatOutput << QStringLiteral("font-style:italic;");
}
if (format.isUnderline(theme())) {
formatOutput << QStringLiteral("text-decoration:underline;");
}
if (format.isStrikeThrough(theme())) {
formatOutput << QStringLiteral("text-decoration:line-through;");
Q_D(HtmlHighlighter);
auto const &htmlStyle = d->htmlStyles[format.id()];
if (!htmlStyle.isEmpty()) {
*d->out << htmlStyle;
}
if (!formatOutput.isEmpty()) {
*d->out << "<span style=\"";
for (const auto &out : std::as_const(formatOutput)) {
*d->out << out;
}
*d->out << "\">";
for (QChar ch : QStringView(d->currentLine).mid(offset, length)) {
if (ch == u'<')
*d->out << QStringLiteral("&lt;");
else if (ch == u'&')
*d->out << QStringLiteral("&amp;");
else
*d->out << ch;
}
*d->out << d->currentLine.mid(offset, length).toHtmlEscaped();
if (!formatOutput.isEmpty()) {
*d->out << "</span>";
if (!htmlStyle.isEmpty()) {
*d->out << QStringLiteral("</span>");
}
}

View File

@@ -10,10 +10,11 @@
#include "abstracthighlighter.h"
#include "ksyntaxhighlighting_export.h"
#include <QIODevice>
#include <QString>
#include <memory>
QT_BEGIN_NAMESPACE
class QIODevice;
QT_END_NAMESPACE
namespace KSyntaxHighlighting
{
@@ -35,7 +36,7 @@ protected:
void applyFormat(int offset, int length, const Format &format) override;
private:
std::unique_ptr<HtmlHighlighterPrivate> d;
Q_DECLARE_PRIVATE(HtmlHighlighter)
};
}

View File

@@ -47,7 +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), KeywordComparator{caseSensitive});
return std::binary_search(vectorToSearch.begin(), vectorToSearch.end(), str, KeywordComparator{caseSensitive});
}
void KeywordList::load(QXmlStreamReader &reader)
@@ -103,10 +103,7 @@ void KeywordList::initLookupForCaseSensitivity(Qt::CaseSensitivity caseSensitive
/**
* fill vector with refs to keywords
*/
vectorToSort.reserve(m_keywords.size());
for (const auto &keyword : std::as_const(m_keywords)) {
vectorToSort.push_back(keyword);
}
vectorToSort.assign(m_keywords.constBegin(), m_keywords.constEnd());
/**
* sort with right predicate

View File

@@ -41,9 +41,9 @@ public:
* @param offset offset of match
* @param captures captures of the match
*/
explicit MatchResult(const int offset, const QStringList &captures)
explicit MatchResult(const int offset, QStringList &&captures)
: m_offset(offset)
, m_captures(captures)
, m_captures(std::move(captures))
{
}
@@ -69,7 +69,7 @@ public:
* Captures of the match.
* @return captured text of this match
*/
const QStringList &captures() const
QStringList &captures()
{
return m_captures;
}

View File

@@ -77,9 +77,9 @@ Definition findHighestPriorityDefinitionIf(const QMap<QString, Definition> &defs
}
template<typename UnaryPredicate>
QVector<Definition> findDefinitionsIf(const QMap<QString, Definition> &defs, UnaryPredicate predicate)
QList<Definition> findDefinitionsIf(const QMap<QString, Definition> &defs, UnaryPredicate predicate)
{
QVector<Definition> matches;
QList<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();
@@ -127,7 +127,7 @@ Definition Repository::definitionForFileName(const QString &fileName) const
return findHighestPriorityDefinitionIf(d->m_defs, anyWildcardMatches(fileNameFromFilePath(fileName)));
}
QVector<Definition> Repository::definitionsForFileName(const QString &fileName) const
QList<Definition> Repository::definitionsForFileName(const QString &fileName) const
{
return findDefinitionsIf(d->m_defs, anyWildcardMatches(fileNameFromFilePath(fileName)));
}
@@ -137,22 +137,22 @@ Definition Repository::definitionForMimeType(const QString &mimeType) const
return findHighestPriorityDefinitionIf(d->m_defs, anyMimeTypeEquals(mimeType));
}
QVector<Definition> Repository::definitionsForMimeType(const QString &mimeType) const
QList<Definition> Repository::definitionsForMimeType(const QString &mimeType) const
{
return findDefinitionsIf(d->m_defs, anyMimeTypeEquals(mimeType));
}
QVector<Definition> Repository::definitions() const
QList<Definition> Repository::definitions() const
{
return d->m_sortedDefs;
}
QVector<Theme> Repository::themes() const
QList<Theme> Repository::themes() const
{
return d->m_themes;
}
static auto lowerBoundTheme(const QVector<KSyntaxHighlighting::Theme> &themes, QStringView themeName)
static auto lowerBoundTheme(const QList<KSyntaxHighlighting::Theme> &themes, QStringView themeName)
{
return std::lower_bound(themes.begin(), themes.end(), themeName, [](const Theme &lhs, QStringView rhs) {
return lhs.name() < rhs;
@@ -177,42 +177,32 @@ Theme Repository::defaultTheme(Repository::DefaultTheme t) const
return theme(QStringLiteral("Breeze Light"));
}
Theme Repository::defaultTheme(Repository::DefaultTheme t)
{
return std::as_const(*this).defaultTheme(t);
}
Theme Repository::themeForPalette(const QPalette &palette) const
{
const auto base = palette.color(QPalette::Base);
const auto highlight = palette.color(QPalette::Highlight).rgb();
// find themes with matching background colors
QVector<const KSyntaxHighlighting::Theme *> matchingThemes;
// find themes with matching background and highlight colors
const Theme *firstMatchingTheme = nullptr;
for (const auto &theme : std::as_const(d->m_themes)) {
const auto background = theme.editorColor(KSyntaxHighlighting::Theme::EditorColorRole::BackgroundColor);
const auto background = theme.editorColor(Theme::EditorColorRole::BackgroundColor);
if (background == base.rgb()) {
matchingThemes.append(&theme);
}
}
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 : std::as_const(matchingThemes)) {
auto selection = theme->editorColor(KSyntaxHighlighting::Theme::EditorColorRole::TextSelection);
if (selection == highlight.rgb()) {
return *theme;
// find theme with a matching highlight color
auto selection = theme.editorColor(Theme::EditorColorRole::TextSelection);
if (selection == highlight) {
return theme;
}
if (!firstMatchingTheme) {
firstMatchingTheme = &theme;
}
}
return *matchingThemes.first();
}
if (firstMatchingTheme) {
return *firstMatchingTheme;
}
// fallback to just use the default light or dark theme
return defaultTheme((base.lightness() < 128) ? KSyntaxHighlighting::Repository::DarkTheme : KSyntaxHighlighting::Repository::LightTheme);
}
Theme Repository::themeForPalette(const QPalette &palette)
{
return std::as_const(*this).themeForPalette(palette);
return defaultTheme((base.lightness() < 128) ? Repository::DarkTheme : Repository::LightTheme);
}
void RepositoryPrivate::load(Repository *repo)
@@ -238,12 +228,6 @@ void RepositoryPrivate::load(Repository *repo)
QStandardPaths::LocateDirectory)) {
loadSyntaxFolder(repo, dir);
}
// backward compatibility with Kate
for (const auto &dir :
QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("katepart5/syntax"), QStandardPaths::LocateDirectory)) {
loadSyntaxFolder(repo, dir);
}
#endif
// default resources are always used, this is the one location that has a index cbor file
@@ -377,25 +361,27 @@ void RepositoryPrivate::addTheme(const Theme &theme)
}
}
quint16 RepositoryPrivate::foldingRegionId(const QString &defName, const QString &foldName)
int RepositoryPrivate::foldingRegionId(const QString &defName, const QString &foldName)
{
const auto it = m_foldingRegionIds.constFind(qMakePair(defName, foldName));
if (it != m_foldingRegionIds.constEnd()) {
return it.value();
}
Q_ASSERT(m_foldingRegionId < std::numeric_limits<int>::max());
m_foldingRegionIds.insert(qMakePair(defName, foldName), ++m_foldingRegionId);
return m_foldingRegionId;
}
quint16 RepositoryPrivate::nextFormatId()
int RepositoryPrivate::nextFormatId()
{
Q_ASSERT(m_formatId < std::numeric_limits<quint16>::max());
Q_ASSERT(m_formatId < std::numeric_limits<int>::max());
return ++m_formatId;
}
void Repository::reload()
{
qCDebug(Log) << "Reloading syntax definitions!";
Q_EMIT aboutToReload();
for (const auto &def : std::as_const(d->m_sortedDefs)) {
DefinitionData::get(def)->clear();
}
@@ -410,6 +396,8 @@ void Repository::reload()
d->m_formatId = 0;
d->load(this);
Q_EMIT reloaded();
}
void Repository::addCustomSearchPath(const QString &path)
@@ -418,7 +406,9 @@ void Repository::addCustomSearchPath(const QString &path)
reload();
}
QVector<QString> Repository::customSearchPaths() const
QList<QString> Repository::customSearchPaths() const
{
return d->m_customSearchPaths;
}
#include "moc_repository.cpp"

View File

@@ -9,7 +9,8 @@
#include "ksyntaxhighlighting_export.h"
#include <QVector>
#include <QList>
#include <QObject>
#include <QtGlobal>
#include <memory>
@@ -76,13 +77,6 @@ class Theme;
* map to $HOME/.local5/share/org.kde.syntax-highlighting/syntax and
* /usr/share/org.kde.syntax-highlighting/syntax.
*
* -# Next, for backwards compatibility with Kate, all syntax highlighting
* files are loaded that are located in
* QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("katepart5/syntax"), QStandardPaths::LocateDirectory);
* Again, under Unix, this uses $XDG_DATA_HOME and $XDG_DATA_DIRS, which
* could map to $HOME/.local5/share/katepart5/syntax and
* /usr/share/katepart5/syntax.
*
* -# Then, all files compiled into the library through resources are loaded.
* The internal resource path is ":/org.kde.syntax-highlighting/syntax".
* This path should never be touched by other applications.
@@ -124,8 +118,12 @@ class Theme;
* @see Definition, Theme, AbstractHighlighter
* @since 5.28
*/
class KSYNTAXHIGHLIGHTING_EXPORT Repository
class KSYNTAXHIGHLIGHTING_EXPORT Repository : public QObject
{
Q_OBJECT
Q_PROPERTY(QList<KSyntaxHighlighting::Definition> definitions READ definitions NOTIFY reloaded)
Q_PROPERTY(QList<KSyntaxHighlighting::Theme> themes READ themes NOTIFY reloaded)
public:
/**
* Create a new syntax definition repository.
@@ -148,7 +146,7 @@ public:
* Therefore, only the string "JavaScript" will return a valid
* Definition file.
*/
Definition definitionForName(const QString &defName) const;
Q_INVOKABLE KSyntaxHighlighting::Definition definitionForName(const QString &defName) const;
/**
* Returns the best matching Definition for the file named @p fileName.
@@ -159,7 +157,7 @@ public:
* If no match is found, Definition::isValid() of the returned instance
* returns false.
*/
Definition definitionForFileName(const QString &fileName) const;
Q_INVOKABLE KSyntaxHighlighting::Definition definitionForFileName(const QString &fileName) const;
/**
* Returns all Definition%s for the file named @p fileName sorted by priority.
@@ -168,7 +166,7 @@ public:
*
* @since 5.56
*/
QVector<Definition> definitionsForFileName(const QString &fileName) const;
Q_INVOKABLE QList<KSyntaxHighlighting::Definition> definitionsForFileName(const QString &fileName) const;
/**
* Returns the best matching Definition to the type named @p mimeType
@@ -178,34 +176,34 @@ public:
*
* @since 5.50
*/
Definition definitionForMimeType(const QString &mimeType) const;
Q_INVOKABLE KSyntaxHighlighting::Definition definitionForMimeType(const QString &mimeType) const;
/**
* Returns all Definition%s to the type named @p mimeType sorted by priority
*
* @since 5.56
*/
QVector<Definition> definitionsForMimeType(const QString &mimeType) const;
Q_INVOKABLE QList<KSyntaxHighlighting::Definition> definitionsForMimeType(const QString &mimeType) const;
/**
* Returns all available Definition%s.
* Definition%ss are ordered by translated section and translated names,
* for consistent displaying.
*/
QVector<Definition> definitions() const;
Q_INVOKABLE QList<KSyntaxHighlighting::Definition> definitions() const;
/**
* Returns all available color themes.
* The returned list should never be empty.
*/
QVector<Theme> themes() const;
Q_INVOKABLE QList<KSyntaxHighlighting::Theme> themes() const;
/**
* Returns the theme called @p themeName.
* If the requested theme cannot be found, the retunred Theme is invalid,
* see Theme::isValid().
*/
Theme theme(const QString &themeName) const;
Q_INVOKABLE KSyntaxHighlighting::Theme theme(const QString &themeName) const;
/**
* Built-in default theme types.
@@ -217,21 +215,14 @@ public:
//! Theme with a dark background color.
DarkTheme
};
Q_ENUM(DefaultTheme)
/**
* Returns a default theme instance of the given type.
* The returned Theme is guaranteed to be a valid theme.
* @since 5.79
*/
Theme defaultTheme(DefaultTheme t = LightTheme) const;
/**
* Returns a default theme instance of the given type.
* The returned Theme is guaranteed to be a valid theme.
*
* KF6: remove in favor of const variant
*/
Theme defaultTheme(DefaultTheme t = LightTheme);
Q_INVOKABLE KSyntaxHighlighting::Theme defaultTheme(DefaultTheme t = LightTheme) const;
/**
* Returns the best matching theme for the given palette
@@ -239,14 +230,6 @@ public:
**/
Theme themeForPalette(const QPalette &palette) const;
/**
* Returns the best matching theme for the given palette
* @since 5.77
*
* KF6: remove in favor of const variant
**/
Theme themeForPalette(const QPalette &palette);
/**
* Reloads the repository.
* This is a moderately expensive operations and should thus only be
@@ -278,7 +261,20 @@ public:
* @see addCustomSearchPath()
* @since 5.39
*/
QVector<QString> customSearchPaths() const;
QList<QString> customSearchPaths() const;
Q_SIGNALS:
/**
* This signal is emitted before the reload is started.
* @since 6.0
*/
void aboutToReload();
/**
* This signal is emitted when the reload is finished.
* @since 6.0
*/
void reloaded();
private:
Q_DISABLE_COPY(Repository)

View File

@@ -8,11 +8,11 @@
#define KSYNTAXHIGHLIGHTING_REPOSITORY_P_H
#include <QHash>
#include <QVector>
#include <QList>
#include <QMap>
#include <QString>
QT_BEGIN_NAMESPACE
class QString;
QT_END_NAMESPACE
#include "dynamicregexpcache_p.h"
namespace KSyntaxHighlighting
{
@@ -36,22 +36,24 @@ public:
void loadThemeFolder(const QString &path);
void addTheme(const Theme &theme);
quint16 foldingRegionId(const QString &defName, const QString &foldName);
quint16 nextFormatId();
int foldingRegionId(const QString &defName, const QString &foldName);
int nextFormatId();
QVector<QString> m_customSearchPaths;
QList<QString> m_customSearchPaths;
// sorted map to have deterministic iteration order for e.g. definitionsForFileName
QMap<QString, Definition> m_defs;
// this vector is sorted by translated sections/names
QVector<Definition> m_sortedDefs;
QList<Definition> m_sortedDefs;
QVector<Theme> m_themes;
QList<Theme> m_themes;
QHash<QPair<QString, QString>, quint16> m_foldingRegionIds;
quint16 m_foldingRegionId = 0;
quint16 m_formatId = 0;
QHash<QPair<QString, QString>, int> m_foldingRegionIds;
int m_foldingRegionId = 0;
int m_formatId = 0;
DynamicRegexpCache m_dynamicRegexpCache;
};
}

View File

@@ -1,20 +1,19 @@
/*
SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org>
SPDX-FileCopyrightText: 2018 Christoph Cullmann <cullmann@kde.org>
SPDX-FileCopyrightText: 2020 Jonathan Poelen <jonathan.poelen@gmail.com>
SPDX-FileCopyrightText: 2020 Jonathan Poelen <jonathan.poelen+kde@gmail.com>
SPDX-License-Identifier: MIT
*/
#include "context_p.h"
#include "definition_p.h"
#include "dynamicregexpcache_p.h"
#include "ksyntaxhighlighting_logging.h"
#include "rule_p.h"
#include "worddelimiters_p.h"
#include "xml_p.h"
#include <QString>
using namespace KSyntaxHighlighting;
// QChar::isDigit() match any digit in unicode (romain numeral, etc)
@@ -90,8 +89,8 @@ static int matchEscapedChar(QStringView text, int offset)
static QString replaceCaptures(const QString &pattern, const QStringList &captures, bool quote)
{
auto result = pattern;
for (int i = captures.size() - 1; i >= 1; --i) {
result.replace(QLatin1Char('%') + QString::number(i), quote ? QRegularExpression::escape(captures.at(i)) : captures.at(i));
for (int i = captures.size(); i >= 1; --i) {
result.replace(QLatin1Char('%') + QString::number(i), quote ? QRegularExpression::escape(captures.at(i - 1)) : captures.at(i - 1));
}
return result;
}
@@ -233,7 +232,7 @@ AnyChar::AnyChar(const HighlightingContextData::Rule::AnyChar &data)
{
}
MatchResult AnyChar::doMatch(QStringView text, int offset, const QStringList &) const
MatchResult AnyChar::doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const
{
if (m_chars.contains(text.at(offset))) {
return offset + 1;
@@ -243,15 +242,15 @@ MatchResult AnyChar::doMatch(QStringView text, int offset, const QStringList &)
DetectChar::DetectChar(const HighlightingContextData::Rule::DetectChar &data)
: m_char(data.char1)
, m_captureIndex(data.dynamic ? data.char1.digitValue() : 0)
, m_captureIndex((data.dynamic ? data.char1.digitValue() : 0) - 1)
{
m_dynamic = data.dynamic;
}
MatchResult DetectChar::doMatch(QStringView text, int offset, const QStringList &captures) const
MatchResult DetectChar::doMatch(QStringView text, int offset, const QStringList &captures, DynamicRegexpCache &) const
{
if (m_dynamic) {
if (m_captureIndex == 0 || captures.size() <= m_captureIndex || captures.at(m_captureIndex).isEmpty()) {
if (m_captureIndex == -1 || captures.size() <= m_captureIndex || captures.at(m_captureIndex).isEmpty()) {
return offset;
}
if (text.at(offset) == captures.at(m_captureIndex).at(0)) {
@@ -272,7 +271,7 @@ Detect2Chars::Detect2Chars(const HighlightingContextData::Rule::Detect2Chars &da
{
}
MatchResult Detect2Chars::doMatch(QStringView text, int offset, const QStringList &) const
MatchResult Detect2Chars::doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const
{
if (text.size() - offset < 2) {
return offset;
@@ -283,7 +282,7 @@ MatchResult Detect2Chars::doMatch(QStringView text, int offset, const QStringLis
return offset;
}
MatchResult DetectIdentifier::doMatch(QStringView text, int offset, const QStringList &) const
MatchResult DetectIdentifier::doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const
{
if (!text.at(offset).isLetter() && text.at(offset) != QLatin1Char('_')) {
return offset;
@@ -299,7 +298,7 @@ MatchResult DetectIdentifier::doMatch(QStringView text, int offset, const QStrin
return text.size();
}
MatchResult DetectSpaces::doMatch(QStringView text, int offset, const QStringList &) const
MatchResult DetectSpaces::doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const
{
while (offset < text.size() && text.at(offset).isSpace()) {
++offset;
@@ -313,7 +312,7 @@ Float::Float(DefinitionData &def, const HighlightingContextData::Rule::Float &da
resolveAdditionalWordDelimiters(m_wordDelimiters, data.wordDelimiters);
}
MatchResult Float::doMatch(QStringView text, int offset, const QStringList &) const
MatchResult Float::doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const
{
if (offset > 0 && !m_wordDelimiters.contains(text.at(offset - 1))) {
return offset;
@@ -358,7 +357,7 @@ MatchResult Float::doMatch(QStringView text, int offset, const QStringList &) co
return expOffset;
}
MatchResult HlCChar::doMatch(QStringView text, int offset, const QStringList &) const
MatchResult HlCChar::doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const
{
if (text.size() < offset + 3) {
return offset;
@@ -393,7 +392,7 @@ HlCHex::HlCHex(DefinitionData &def, const HighlightingContextData::Rule::HlCHex
resolveAdditionalWordDelimiters(m_wordDelimiters, data.wordDelimiters);
}
MatchResult HlCHex::doMatch(QStringView text, int offset, const QStringList &) const
MatchResult HlCHex::doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const
{
if (offset > 0 && !m_wordDelimiters.contains(text.at(offset - 1))) {
return offset;
@@ -427,7 +426,7 @@ HlCOct::HlCOct(DefinitionData &def, const HighlightingContextData::Rule::HlCOct
resolveAdditionalWordDelimiters(m_wordDelimiters, data.wordDelimiters);
}
MatchResult HlCOct::doMatch(QStringView text, int offset, const QStringList &) const
MatchResult HlCOct::doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const
{
if (offset > 0 && !m_wordDelimiters.contains(text.at(offset - 1))) {
return offset;
@@ -453,7 +452,7 @@ MatchResult HlCOct::doMatch(QStringView text, int offset, const QStringList &) c
return offset;
}
MatchResult HlCStringChar::doMatch(QStringView text, int offset, const QStringList &) const
MatchResult HlCStringChar::doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const
{
return matchEscapedChar(text, offset);
}
@@ -464,7 +463,7 @@ IncludeRules::IncludeRules(const HighlightingContextData::Rule::IncludeRules &da
{
}
MatchResult IncludeRules::doMatch(QStringView text, int offset, const QStringList &) const
MatchResult IncludeRules::doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const
{
Q_UNUSED(text);
qCWarning(Log) << "Unresolved include rule";
@@ -477,7 +476,7 @@ Int::Int(DefinitionData &def, const HighlightingContextData::Rule::Int &data)
resolveAdditionalWordDelimiters(m_wordDelimiters, data.wordDelimiters);
}
MatchResult Int::doMatch(QStringView text, int offset, const QStringList &) const
MatchResult Int::doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const
{
if (offset > 0 && !m_wordDelimiters.contains(text.at(offset - 1))) {
return offset;
@@ -521,9 +520,10 @@ KeywordListRule::KeywordListRule(const KeywordList &keywordList, DefinitionData
, m_caseSensitivity(data.hasCaseSensitivityOverride ? data.caseSensitivityOverride : keywordList.caseSensitivity())
{
resolveAdditionalWordDelimiters(m_wordDelimiters, data.wordDelimiters);
m_hasSkipOffset = true;
}
MatchResult KeywordListRule::doMatch(QStringView text, int offset, const QStringList &) const
MatchResult KeywordListRule::doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const
{
auto newOffset = offset;
while (text.size() > newOffset && !m_wordDelimiters.contains(text.at(newOffset))) {
@@ -546,7 +546,7 @@ LineContinue::LineContinue(const HighlightingContextData::Rule::LineContinue &da
{
}
MatchResult LineContinue::doMatch(QStringView text, int offset, const QStringList &) const
MatchResult LineContinue::doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const
{
if (offset == text.size() - 1 && text.at(offset) == m_char) {
return offset + 1;
@@ -560,7 +560,7 @@ RangeDetect::RangeDetect(const HighlightingContextData::Rule::RangeDetect &data)
{
}
MatchResult RangeDetect::doMatch(QStringView text, int offset, const QStringList &) const
MatchResult RangeDetect::doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const
{
if (text.size() - offset < 2) {
return offset;
@@ -591,25 +591,16 @@ static QRegularExpression::PatternOptions makePattenOptions(const HighlightingCo
static void resolveRegex(QRegularExpression &regexp, Context *context)
{
if (!regexp.isValid()) {
// DontCaptureOption with back reference capture is an error, remove this option then try again
bool enableCapture = context && context->hasDynamicRule();
// disable DontCaptureOption when reference a context with dynamic rule or
// with invalid regex because DontCaptureOption with back reference capture is an error
if (enableCapture || !regexp.isValid()) {
regexp.setPatternOptions(regexp.patternOptions() & ~QRegularExpression::DontCaptureOption);
if (!regexp.isValid()) {
qCDebug(Log) << "Invalid regexp:" << regexp.pattern();
}
return;
}
// disable DontCaptureOption when reference a context with dynamic rule
if (context) {
for (const Rule::Ptr &rule : context->rules()) {
if (rule->isDynamic()) {
regexp.setPatternOptions(regexp.patternOptions() & ~QRegularExpression::DontCaptureOption);
break;
}
}
if (!regexp.isValid()) {
qCDebug(Log) << "Invalid regexp:" << regexp.pattern();
}
}
@@ -618,15 +609,25 @@ static MatchResult regexMatch(const QRegularExpression &regexp, QStringView text
/**
* match the pattern
*/
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
const auto result = regexp.matchView(text, offset, QRegularExpression::NormalMatch, QRegularExpression::DontCheckSubjectStringMatchOption);
#else
const auto result = regexp.match(text, offset, QRegularExpression::NormalMatch, QRegularExpression::DontCheckSubjectStringMatchOption);
#endif
if (result.capturedStart() == offset) {
/**
* we only need to compute the captured texts if we have real capture groups
* highlightings should only address %1..%.., see e.g. replaceCaptures
* DetectChar ignores %0, too
*/
if (result.lastCapturedIndex() > 0) {
return MatchResult(offset + result.capturedLength(), result.capturedTexts());
int lastCapturedIndex = result.lastCapturedIndex();
if (lastCapturedIndex > 0) {
QStringList captures;
captures.reserve(lastCapturedIndex);
// ignore the capturing group number 0
for (int i = 1; i <= lastCapturedIndex; ++i)
captures.push_back(result.captured(i));
return MatchResult(offset + result.capturedLength(), std::move(captures));
}
/**
@@ -645,20 +646,17 @@ static MatchResult regexMatch(const QRegularExpression &regexp, QStringView text
RegExpr::RegExpr(const HighlightingContextData::Rule::RegExpr &data)
: m_regexp(data.pattern, makePattenOptions(data))
{
m_hasSkipOffset = true;
}
void RegExpr::resolve()
{
if (m_isResolved) {
return;
}
m_isResolved = true;
resolveRegex(m_regexp, context().context());
}
MatchResult RegExpr::doMatch(QStringView text, int offset, const QStringList &) const
MatchResult RegExpr::doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const
{
if (Q_UNLIKELY(!m_isResolved)) {
const_cast<RegExpr *>(this)->resolve();
@@ -672,14 +670,11 @@ DynamicRegExpr::DynamicRegExpr(const HighlightingContextData::Rule::RegExpr &dat
, m_patternOptions(makePattenOptions(data))
{
m_dynamic = true;
m_hasSkipOffset = true;
}
void DynamicRegExpr::resolve()
{
if (m_isResolved) {
return;
}
m_isResolved = true;
QRegularExpression regexp(m_pattern, m_patternOptions);
@@ -687,7 +682,7 @@ void DynamicRegExpr::resolve()
m_patternOptions = regexp.patternOptions();
}
MatchResult DynamicRegExpr::doMatch(QStringView text, int offset, const QStringList &captures) const
MatchResult DynamicRegExpr::doMatch(QStringView text, int offset, const QStringList &captures, DynamicRegexpCache &dynamicRegexpCache) const
{
if (Q_UNLIKELY(!m_isResolved)) {
const_cast<DynamicRegExpr *>(this)->resolve();
@@ -696,8 +691,8 @@ MatchResult DynamicRegExpr::doMatch(QStringView text, int offset, const QStringL
/**
* create new pattern with right instantiation
*/
const QRegularExpression regexp(replaceCaptures(m_pattern, captures, true), m_patternOptions);
auto pattern = replaceCaptures(m_pattern, captures, true);
auto &regexp = dynamicRegexpCache.compileRegexp(std::move(pattern), m_patternOptions);
return regexMatch(regexp, text, offset);
}
@@ -707,7 +702,7 @@ StringDetect::StringDetect(const HighlightingContextData::Rule::StringDetect &da
{
}
MatchResult StringDetect::doMatch(QStringView text, int offset, const QStringList &) const
MatchResult StringDetect::doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const
{
return matchString(m_string, text, offset, m_caseSensitivity);
}
@@ -719,7 +714,7 @@ DynamicStringDetect::DynamicStringDetect(const HighlightingContextData::Rule::St
m_dynamic = true;
}
MatchResult DynamicStringDetect::doMatch(QStringView text, int offset, const QStringList &captures) const
MatchResult DynamicStringDetect::doMatch(QStringView text, int offset, const QStringList &captures, DynamicRegexpCache &) const
{
/**
* for dynamic case: create new pattern with right instantiation
@@ -736,7 +731,7 @@ WordDetect::WordDetect(DefinitionData &def, const HighlightingContextData::Rule:
resolveAdditionalWordDelimiters(m_wordDelimiters, data.wordDelimiters);
}
MatchResult WordDetect::doMatch(QStringView text, int offset, const QStringList &) const
MatchResult WordDetect::doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const
{
if (text.size() - offset < m_word.size()) {
return offset;

View File

@@ -27,6 +27,7 @@ namespace KSyntaxHighlighting
class WordDelimiters;
class DefinitionData;
class IncludeRules;
class DynamicRegexpCache;
class Rule
{
@@ -83,7 +84,15 @@ public:
return m_type == Type::LineContinue;
}
virtual MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const = 0;
// If true, then the rule uses the skipOffset parameter of MatchResult.
// This is used by AbstractHighlighter::highlightLine() to look for a rule
// in the skipOffsets cache only if it can be found there.
bool hasSkipOffset() const
{
return m_hasSkipOffset;
}
virtual MatchResult doMatch(QStringView text, int offset, const QStringList &captures, DynamicRegexpCache &dynamicRegexpCache) const = 0;
static Rule::Ptr create(DefinitionData &def, const HighlightingContextData::Rule &ruleData, QStringView lookupContextName);
@@ -98,6 +107,7 @@ private:
IncludeRules,
};
private:
Format m_attributeFormat;
ContextSwitch m_context;
int m_column = -1;
@@ -108,6 +118,7 @@ private:
bool m_lookAhead = false;
protected:
bool m_hasSkipOffset = false;
bool m_dynamic = false;
};
@@ -117,10 +128,10 @@ public:
AnyChar(const HighlightingContextData::Rule::AnyChar &data);
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
private:
QString m_chars;
WordDelimiters m_chars;
};
class DetectChar final : public Rule
@@ -129,7 +140,7 @@ public:
DetectChar(const HighlightingContextData::Rule::DetectChar &data);
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
private:
QChar m_char;
@@ -142,7 +153,7 @@ public:
Detect2Chars(const HighlightingContextData::Rule::Detect2Chars &data);
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
private:
QChar m_char1;
@@ -152,13 +163,13 @@ private:
class DetectIdentifier final : public Rule
{
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
};
class DetectSpaces final : public Rule
{
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
};
class Float final : public Rule
@@ -167,7 +178,7 @@ public:
Float(DefinitionData &def, const HighlightingContextData::Rule::Float &data);
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
private:
WordDelimiters m_wordDelimiters;
@@ -189,7 +200,7 @@ public:
}
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
private:
QString m_contextName;
@@ -202,7 +213,7 @@ public:
Int(DefinitionData &def, const HighlightingContextData::Rule::Int &data);
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
private:
WordDelimiters m_wordDelimiters;
@@ -211,7 +222,7 @@ private:
class HlCChar final : public Rule
{
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
};
class HlCHex final : public Rule
@@ -220,7 +231,7 @@ public:
HlCHex(DefinitionData &def, const HighlightingContextData::Rule::HlCHex &data);
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
private:
WordDelimiters m_wordDelimiters;
@@ -232,7 +243,7 @@ public:
HlCOct(DefinitionData &def, const HighlightingContextData::Rule::HlCOct &data);
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
private:
WordDelimiters m_wordDelimiters;
@@ -241,7 +252,7 @@ private:
class HlCStringChar final : public Rule
{
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
};
class KeywordListRule final : public Rule
@@ -252,7 +263,7 @@ public:
static Rule::Ptr create(DefinitionData &def, const HighlightingContextData::Rule::Keyword &data, QStringView lookupContextName);
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
private:
WordDelimiters m_wordDelimiters;
@@ -266,7 +277,7 @@ public:
LineContinue(const HighlightingContextData::Rule::LineContinue &data);
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
private:
QChar m_char;
@@ -278,7 +289,7 @@ public:
RangeDetect(const HighlightingContextData::Rule::RangeDetect &data);
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
private:
QChar m_begin;
@@ -291,7 +302,7 @@ public:
RegExpr(const HighlightingContextData::Rule::RegExpr &data);
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
private:
void resolve();
@@ -305,7 +316,7 @@ public:
DynamicRegExpr(const HighlightingContextData::Rule::RegExpr &data);
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
private:
void resolve();
@@ -320,7 +331,7 @@ public:
StringDetect(const HighlightingContextData::Rule::StringDetect &data);
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
private:
QString m_string;
@@ -333,7 +344,7 @@ public:
DynamicStringDetect(const HighlightingContextData::Rule::StringDetect &data);
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
private:
QString m_string;
@@ -346,7 +357,7 @@ public:
WordDetect(DefinitionData &def, const HighlightingContextData::Rule::WordDetect &data);
protected:
MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override;
private:
WordDelimiters m_wordDelimiters;

View File

@@ -1,4 +1,4 @@
/*
/*
SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org>
SPDX-FileCopyrightText: 2018 Christoph Cullmann <cullmann@kde.org>
@@ -14,36 +14,23 @@
using namespace KSyntaxHighlighting;
StateData *StateData::get(State &state)
StateData *StateData::reset(State &state)
{
// create state data on demand, to make default state construction cheap
if (!state.d) {
state.d = new StateData();
} else {
state.d.detach();
}
auto *p = new StateData();
state.d.reset(p);
return p;
}
StateData *StateData::detach(State &state)
{
state.d.detach();
return state.d.data();
}
bool StateData::isEmpty() const
{
return m_contextStack.isEmpty();
}
void StateData::clear()
{
m_contextStack.clear();
}
int StateData::size() const
{
return m_contextStack.size();
}
void StateData::push(Context *context, const QStringList &captures)
void StateData::push(Context *context, QStringList &&captures)
{
Q_ASSERT(context);
m_contextStack.push_back(qMakePair(context, captures));
m_contextStack.push_back(StackValue{context, std::move(captures)});
}
bool StateData::pop(int popCount)
@@ -54,42 +41,23 @@ bool StateData::pop(int popCount)
}
// keep the initial context alive in any case
Q_ASSERT(!isEmpty());
const bool initialContextSurvived = m_contextStack.size() > popCount;
Q_ASSERT(!m_contextStack.empty());
const bool initialContextSurvived = int(m_contextStack.size()) > popCount;
m_contextStack.resize(std::max(1, int(m_contextStack.size()) - popCount));
return initialContextSurvived;
}
Context *StateData::topContext() const
{
Q_ASSERT(!isEmpty());
return m_contextStack.last().first;
}
State::State() = default;
const QStringList &StateData::topCaptures() const
{
Q_ASSERT(!isEmpty());
return m_contextStack.last().second;
}
State::State(State &&other) noexcept = default;
State::State()
{
}
State::State(const State &other) noexcept = default;
State::State(const State &other)
: d(other.d)
{
}
State::~State() = default;
State::~State()
{
}
State &State::operator=(State &&other) noexcept = default;
State &State::operator=(const State &other)
{
d = other.d;
return *this;
}
State &State::operator=(const State &other) noexcept = default;
bool State::operator==(const State &other) const
{
@@ -104,8 +72,13 @@ bool State::operator!=(const State &other) const
bool State::indentationBasedFoldingEnabled() const
{
if (!d || d->m_contextStack.isEmpty()) {
if (!d || d->m_contextStack.empty()) {
return false;
}
return d->m_contextStack.last().first->indentationBasedFoldingEnabled();
return d->m_contextStack.back().context->indentationBasedFoldingEnabled();
}
std::size_t KSyntaxHighlighting::qHash(const State &state, std::size_t seed)
{
return state.d ? qHashMulti(seed, *state.d) : 0;
}

View File

@@ -10,11 +10,15 @@
#include "ksyntaxhighlighting_export.h"
#include <QExplicitlySharedDataPointer>
#include <QHash>
namespace KSyntaxHighlighting
{
class State;
class StateData;
KSYNTAXHIGHLIGHTING_EXPORT std::size_t qHash(const State &state, std::size_t seed = 0);
/** Opaque handle to the state of the highlighting engine.
* This needs to be fed into AbstractHighlighter for every line of text
* and allows concrete highlighter implementations to store state per
@@ -29,9 +33,11 @@ public:
* in a document.
*/
State();
State(const State &other);
State(State &&other) noexcept;
State(const State &other) noexcept;
~State();
State &operator=(const State &rhs);
State &operator=(State &&rhs) noexcept;
State &operator=(const State &rhs) noexcept;
/** Compares two states for equality.
* For two equal states and identical text input, AbstractHighlighter
@@ -56,13 +62,13 @@ public:
private:
friend class StateData;
KSYNTAXHIGHLIGHTING_EXPORT friend std::size_t qHash(const State &, std::size_t);
QExplicitlySharedDataPointer<StateData> d;
};
}
QT_BEGIN_NAMESPACE
Q_DECLARE_TYPEINFO(KSyntaxHighlighting::State, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(KSyntaxHighlighting::State, Q_RELOCATABLE_TYPE);
QT_END_NAMESPACE
#endif // KSYNTAXHIGHLIGHTING_STATE_H

View File

@@ -8,8 +8,10 @@
#ifndef KSYNTAXHIGHLIGHTING_STATE_P_H
#define KSYNTAXHIGHLIGHTING_STATE_P_H
#include <vector>
#include <QSharedData>
#include <QVector>
#include <QStringList>
#include "definitionref_p.h"
@@ -21,15 +23,25 @@ class StateData : public QSharedData
{
friend class State;
friend class AbstractHighlighter;
friend std::size_t qHash(const StateData &, std::size_t);
public:
StateData() = default;
static StateData *get(State &state);
bool isEmpty() const;
void clear();
int size() const;
void push(Context *context, const QStringList &captures);
static StateData *reset(State &state);
static StateData *detach(State &state);
static StateData *get(const State &state)
{
return state.d.data();
}
int size() const
{
return m_contextStack.size();
}
void push(Context *context, QStringList &&captures);
/**
* Pop the number of elements given from the top of the current stack.
@@ -39,8 +51,25 @@ public:
*/
bool pop(int popCount);
Context *topContext() const;
const QStringList &topCaptures() const;
Context *topContext() const
{
return m_contextStack.back().context;
}
const QStringList &topCaptures() const
{
return m_contextStack.back().captures;
}
struct StackValue {
Context *context;
QStringList captures;
bool operator==(const StackValue &other) const
{
return context == other.context && captures == other.captures;
}
};
private:
/**
@@ -51,9 +80,18 @@ private:
/**
* the context stack combines the active context + valid captures
*/
QVector<QPair<Context *, QStringList>> m_contextStack;
std::vector<StackValue> m_contextStack;
};
inline std::size_t qHash(const StateData::StackValue &stackValue, std::size_t seed = 0)
{
return qHashMulti(seed, stackValue.context, stackValue.captures);
}
inline std::size_t qHash(const StateData &k, std::size_t seed = 0)
{
return qHashMulti(seed, k.m_defId, qHashRange(k.m_contextStack.begin(), k.m_contextStack.end(), seed));
}
}
#endif

View File

@@ -7,10 +7,13 @@
#include "syntaxhighlighter.h"
#include "abstracthighlighter_p.h"
#include "definition.h"
#include "definition_p.h"
#include "foldingregion.h"
#include "format.h"
#include "format_p.h"
#include "state.h"
#include "theme.h"
#include "themedata_p.h"
Q_DECLARE_METATYPE(QTextBlock)
@@ -22,14 +25,26 @@ class TextBlockUserData : public QTextBlockUserData
{
public:
State state;
QVector<FoldingRegion> foldingRegions;
QList<FoldingRegion> foldingRegions;
};
class SyntaxHighlighterPrivate : public AbstractHighlighterPrivate
{
public:
static FoldingRegion foldingRegion(const QTextBlock &startBlock);
QVector<FoldingRegion> foldingRegions;
void initTextFormat(QTextCharFormat &tf, const Format &format);
void computeTextFormats();
struct TextFormat {
QTextCharFormat tf;
/**
* id to check that the format belongs to the definition
*/
std::intptr_t ptrId;
};
QList<FoldingRegion> foldingRegions;
std::vector<TextFormat> tfs;
};
}
@@ -48,6 +63,52 @@ FoldingRegion SyntaxHighlighterPrivate::foldingRegion(const QTextBlock &startBlo
return FoldingRegion();
}
void SyntaxHighlighterPrivate::initTextFormat(QTextCharFormat &tf, const Format &format)
{
// always set the foreground color to avoid palette issues
tf.setForeground(format.textColor(m_theme));
if (format.hasBackgroundColor(m_theme)) {
tf.setBackground(format.backgroundColor(m_theme));
}
if (format.isBold(m_theme)) {
tf.setFontWeight(QFont::Bold);
}
if (format.isItalic(m_theme)) {
tf.setFontItalic(true);
}
if (format.isUnderline(m_theme)) {
tf.setFontUnderline(true);
}
if (format.isStrikeThrough(m_theme)) {
tf.setFontStrikeOut(true);
}
}
void SyntaxHighlighterPrivate::computeTextFormats()
{
auto definitions = m_definition.includedDefinitions();
definitions.append(m_definition);
int maxId = 0;
for (const auto &definition : std::as_const(definitions)) {
for (const auto &format : std::as_const(DefinitionData::get(definition)->formats)) {
maxId = qMax(maxId, format.id());
}
}
tfs.clear();
tfs.resize(maxId + 1);
// initialize tfs
for (const auto &definition : std::as_const(definitions)) {
for (const auto &format : std::as_const(DefinitionData::get(definition)->formats)) {
auto &tf = tfs[format.id()];
tf.ptrId = FormatPrivate::ptrId(format);
initTextFormat(tf.tf, format);
}
}
}
SyntaxHighlighter::SyntaxHighlighter(QObject *parent)
: QSyntaxHighlighter(parent)
, AbstractHighlighter(new SyntaxHighlighterPrivate)
@@ -68,13 +129,27 @@ SyntaxHighlighter::~SyntaxHighlighter()
void SyntaxHighlighter::setDefinition(const Definition &def)
{
const auto needsRehighlight = definition() != def;
AbstractHighlighter::setDefinition(def);
Q_D(SyntaxHighlighter);
const auto needsRehighlight = d->m_definition != def;
if (DefinitionData::get(d->m_definition) != DefinitionData::get(def)) {
d->m_definition = def;
d->tfs.clear();
}
if (needsRehighlight) {
rehighlight();
}
}
void SyntaxHighlighter::setTheme(const Theme &theme)
{
Q_D(SyntaxHighlighter);
if (ThemeData::get(d->m_theme) != ThemeData::get(theme)) {
d->m_theme = theme;
d->tfs.clear();
}
}
bool SyntaxHighlighter::startsFoldingRegion(const QTextBlock &startBlock) const
{
return SyntaxHighlighterPrivate::foldingRegion(startBlock).type() == FoldingRegion::Begin;
@@ -92,13 +167,13 @@ QTextBlock SyntaxHighlighter::findFoldingRegionEnd(const QTextBlock &startBlock)
if (!data) {
continue;
}
for (auto it = data->foldingRegions.constBegin(); it != data->foldingRegions.constEnd(); ++it) {
if ((*it).id() != region.id()) {
for (const auto &foldingRegion : std::as_const(data->foldingRegions)) {
if (foldingRegion.id() != region.id()) {
continue;
}
if ((*it).type() == FoldingRegion::End) {
if (foldingRegion.type() == FoldingRegion::End) {
--depth;
} else if ((*it).type() == FoldingRegion::Begin) {
} else if (foldingRegion.type() == FoldingRegion::Begin) {
++depth;
}
if (depth == 0) {
@@ -114,30 +189,31 @@ void SyntaxHighlighter::highlightBlock(const QString &text)
{
Q_D(SyntaxHighlighter);
State state;
static const State emptyState;
const State *previousState = &emptyState;
if (currentBlock().position() > 0) {
const auto prevBlock = currentBlock().previous();
const auto prevData = dynamic_cast<TextBlockUserData *>(prevBlock.userData());
if (prevData) {
state = prevData->state;
previousState = &prevData->state;
}
}
d->foldingRegions.clear();
state = highlightLine(text, state);
auto newState = highlightLine(text, *previousState);
auto data = dynamic_cast<TextBlockUserData *>(currentBlockUserData());
if (!data) { // first time we highlight this
data = new TextBlockUserData;
data->state = state;
data->state = std::move(newState);
data->foldingRegions = d->foldingRegions;
setCurrentBlockUserData(data);
return;
}
if (data->state == state && data->foldingRegions == d->foldingRegions) { // we ended up in the same state, so we are done here
if (data->state == newState && data->foldingRegions == d->foldingRegions) { // we ended up in the same state, so we are done here
return;
}
data->state = state;
data->state = std::move(newState);
data->foldingRegions = d->foldingRegions;
const auto nextBlock = currentBlock().next();
@@ -146,40 +222,35 @@ void SyntaxHighlighter::highlightBlock(const QString &text)
}
}
void SyntaxHighlighter::applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format)
void SyntaxHighlighter::applyFormat(int offset, int length, const Format &format)
{
if (length == 0) {
return;
}
QTextCharFormat tf;
// always set the foreground color to avoid palette issues
tf.setForeground(format.textColor(theme()));
Q_D(SyntaxHighlighter);
if (format.hasBackgroundColor(theme())) {
tf.setBackground(format.backgroundColor(theme()));
}
if (format.isBold(theme())) {
tf.setFontWeight(QFont::Bold);
}
if (format.isItalic(theme())) {
tf.setFontItalic(true);
}
if (format.isUnderline(theme())) {
tf.setFontUnderline(true);
}
if (format.isStrikeThrough(theme())) {
tf.setFontStrikeOut(true);
if (Q_UNLIKELY(d->tfs.empty())) {
d->computeTextFormats();
}
QSyntaxHighlighter::setFormat(offset, length, tf);
const auto id = static_cast<std::size_t>(format.id());
// This doesn't happen when format comes from the definition.
// But as the user can override the function to pass any format, this is a possible scenario.
if (id < d->tfs.size() && d->tfs[id].ptrId == FormatPrivate::ptrId(format)) {
QSyntaxHighlighter::setFormat(offset, length, d->tfs[id].tf);
} else {
QTextCharFormat tf;
d->initTextFormat(tf, format);
QSyntaxHighlighter::setFormat(offset, length, tf);
}
}
void SyntaxHighlighter::applyFolding(int offset, int length, FoldingRegion region)
{
Q_UNUSED(offset);
Q_UNUSED(length);
[[maybe_unused]] Q_D(SyntaxHighlighter);
Q_D(SyntaxHighlighter);
if (region.type() == FoldingRegion::Begin) {
d->foldingRegions.push_back(region);
@@ -196,3 +267,5 @@ void SyntaxHighlighter::applyFolding(int offset, int length, FoldingRegion regio
d->foldingRegions.push_back(region);
}
}
#include "moc_syntaxhighlighter.cpp"

View File

@@ -32,6 +32,7 @@ public:
~SyntaxHighlighter() override;
void setDefinition(const Definition &def) override;
void setTheme(const Theme &theme) override;
/** Returns whether there is a folding region beginning at @p startBlock.
* This only considers syntax-based folding regions,

View File

@@ -103,3 +103,5 @@ QRgb Theme::editorColor(EditorColorRole role) const
{
return m_data->editorColor(role);
}
#include "moc_theme.cpp"

View File

@@ -67,11 +67,6 @@ class KSYNTAXHIGHLIGHTING_EXPORT Theme
Q_PROPERTY(QString name READ name)
Q_PROPERTY(QString translatedName READ translatedName)
public:
// TODO KF6:
// - make TextStyle an enum class
// - move out of Theme into KSyntaxHighlighting
// - do the same for EditorColorRole
/**
* Default styles that can be referenced from syntax definition XML files.
* Make sure to choose readable colors with good contrast especially in
@@ -342,7 +337,7 @@ private:
/**
* Constructor taking a shared ThemeData instance.
*/
explicit Theme(ThemeData *data);
KSYNTAXHIGHLIGHTING_NO_EXPORT explicit Theme(ThemeData *data);
friend class RepositoryPrivate;
friend class ThemeData;
@@ -356,7 +351,7 @@ private:
}
QT_BEGIN_NAMESPACE
Q_DECLARE_TYPEINFO(KSyntaxHighlighting::Theme, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(KSyntaxHighlighting::Theme, Q_RELOCATABLE_TYPE);
QT_END_NAMESPACE
#endif // KSYNTAXHIGHLIGHTING_THEME_H

View File

@@ -18,11 +18,6 @@
using namespace KSyntaxHighlighting;
ThemeData *ThemeData::get(const Theme &theme)
{
return theme.m_data.data();
}
ThemeData::ThemeData()
{
memset(m_editorColors, 0, sizeof(m_editorColors));
@@ -87,9 +82,18 @@ bool ThemeData::load(const QString &filePath)
return false;
}
const QByteArray jsonData = loadFile.readAll();
// look for metadata object
int metaDataStart = jsonData.indexOf("\"metadata\"");
int start = jsonData.indexOf('{', metaDataStart);
int end = jsonData.indexOf("}", metaDataStart);
if (start < 0 || end < 0) {
qCWarning(Log) << "Failed to parse theme file" << filePath << ":"
<< "no metadata object found";
return false;
}
QJsonParseError parseError;
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError);
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData.mid(start, (end + 1) - start), &parseError);
if (parseError.error != QJsonParseError::NoError) {
qCWarning(Log) << "Failed to parse theme file" << filePath << ":" << parseError.errorString();
return false;
@@ -97,13 +101,34 @@ bool ThemeData::load(const QString &filePath)
m_filePath = filePath;
QJsonObject obj = jsonDoc.object();
// read metadata
const QJsonObject metadata = obj.value(QLatin1String("metadata")).toObject();
QJsonObject metadata = jsonDoc.object();
m_name = metadata.value(QLatin1String("name")).toString();
m_revision = metadata.value(QLatin1String("revision")).toInt();
return true;
}
void ThemeData::loadComplete()
{
if (m_completelyLoaded) {
return;
}
m_completelyLoaded = true;
QFile loadFile(m_filePath);
if (!loadFile.open(QIODevice::ReadOnly)) {
return;
}
const QByteArray jsonData = loadFile.readAll();
QJsonParseError parseError;
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError);
if (parseError.error != QJsonParseError::NoError) {
qCWarning(Log) << "Failed to parse theme file" << m_filePath << ":" << parseError.errorString();
return;
}
QJsonObject obj = jsonDoc.object();
// read text styles
const auto metaEnumStyle = QMetaEnum::fromType<Theme::TextStyle>();
const QJsonObject textStyles = obj.value(QLatin1String("text-styles")).toObject();
@@ -162,7 +187,7 @@ bool ThemeData::load(const QString &filePath)
}
}
return true;
return;
}
QString ThemeData::name() const
@@ -187,6 +212,9 @@ QString ThemeData::filePath() const
TextStyleData ThemeData::textStyle(Theme::TextStyle style) const
{
if (!m_completelyLoaded) {
const_cast<ThemeData *>(this)->loadComplete();
}
return m_textStyles[style];
}
@@ -232,12 +260,18 @@ bool ThemeData::isStrikeThrough(Theme::TextStyle style) const
QRgb ThemeData::editorColor(Theme::EditorColorRole role) const
{
if (!m_completelyLoaded) {
const_cast<ThemeData *>(this)->loadComplete();
}
Q_ASSERT(static_cast<int>(role) >= 0 && static_cast<int>(role) <= static_cast<int>(Theme::TemplateReadOnlyPlaceholder));
return m_editorColors[role];
}
TextStyleData ThemeData::textStyleOverride(const QString &definitionName, const QString &attributeName) const
{
if (!m_completelyLoaded) {
const_cast<ThemeData *>(this)->loadComplete();
}
auto it = m_textStyleOverrides.find(definitionName);
if (it != m_textStyleOverrides.end()) {
return it->value(attributeName);

View File

@@ -24,7 +24,10 @@ namespace KSyntaxHighlighting
class ThemeData : public QSharedData
{
public:
static ThemeData *get(const Theme &theme);
static ThemeData *get(const Theme &theme)
{
return theme.m_data.data();
}
/**
* Default constructor, creating an uninitialized ThemeData instance.
@@ -37,6 +40,8 @@ public:
*/
bool load(const QString &filePath);
void loadComplete();
/**
* Returns the unique name of this Theme.
*/
@@ -140,6 +145,8 @@ private:
//! on disk (in a read-only or a writeable location).
QString m_filePath;
bool m_completelyLoaded = false;
//! TextStyles
std::vector<TextStyleData> m_textStyles;
@@ -154,7 +161,7 @@ private:
}
QT_BEGIN_NAMESPACE
Q_DECLARE_TYPEINFO(KSyntaxHighlighting::TextStyleData, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(KSyntaxHighlighting::TextStyleData, Q_RELOCATABLE_TYPE);
QT_END_NAMESPACE
#endif // KSYNTAXHIGHLIGHTING_THEMEDATA_P_H

View File

@@ -16,6 +16,12 @@ WordDelimiters::WordDelimiters()
}
}
WordDelimiters::WordDelimiters(QStringView str)
: asciiDelimiters{}
{
append(str);
}
bool WordDelimiters::contains(QChar c) const
{
if (c.unicode() < 128) {

View File

@@ -26,6 +26,11 @@ class WordDelimiters
public:
WordDelimiters();
/**
* Initialize with a default delimiters.
*/
explicit WordDelimiters(QStringView str);
/**
* Returns @c true if @p c is a word delimiter; otherwise returns @c false.
*/

View File

@@ -7,11 +7,10 @@ ecm_add_qml_module(kquicksyntaxhighlightingplugin URI "org.kde.syntaxhighlightin
target_sources(kquicksyntaxhighlightingplugin PRIVATE
kquicksyntaxhighlightingplugin.cpp
kquicksyntaxhighlighter.cpp
repositorywrapper.cpp
)
target_link_libraries(kquicksyntaxhighlightingplugin PRIVATE
KF5SyntaxHighlighting
Qt${QT_MAJOR_VERSION}::Quick
KF6SyntaxHighlighting
Qt6::Quick
)
ecm_finalize_qml_module(kquicksyntaxhighlightingplugin DESTINATION ${KDE_INSTALL_QMLDIR})

View File

@@ -49,7 +49,7 @@ QVariant KQuickSyntaxHighlighter::definition() const
void KQuickSyntaxHighlighter::setDefinition(const QVariant &definition)
{
Definition def;
if (definition.type() == QVariant::String) {
if (definition.userType() == QMetaType::QString) {
def = unwrappedRepository()->definitionForName(definition.toString());
} else {
def = definition.value<Definition>();
@@ -73,9 +73,9 @@ QVariant KQuickSyntaxHighlighter::theme() const
void KQuickSyntaxHighlighter::setTheme(const QVariant &theme)
{
Theme t;
if (theme.type() == QVariant::String) {
if (theme.userType() == QMetaType::QString) {
t = unwrappedRepository()->theme(theme.toString());
} else if (theme.type() == QVariant::Int) {
} else if (theme.userType() == QMetaType::Int) {
t = unwrappedRepository()->defaultTheme(static_cast<Repository::DefaultTheme>(theme.toInt()));
} else {
t = theme.value<Theme>();
@@ -89,12 +89,12 @@ void KQuickSyntaxHighlighter::setTheme(const QVariant &theme)
}
}
RepositoryWrapper *KQuickSyntaxHighlighter::repository() const
Repository *KQuickSyntaxHighlighter::repository() const
{
return m_repository;
}
void KQuickSyntaxHighlighter::setRepository(RepositoryWrapper *repository)
void KQuickSyntaxHighlighter::setRepository(Repository *repository)
{
if (m_repository == repository) {
return;
@@ -106,7 +106,9 @@ void KQuickSyntaxHighlighter::setRepository(RepositoryWrapper *repository)
Repository *KQuickSyntaxHighlighter::unwrappedRepository() const
{
if (m_repository) {
return m_repository->m_repository;
return m_repository;
}
return defaultRepository();
}
#include "moc_kquicksyntaxhighlighter.cpp"

View File

@@ -8,8 +8,6 @@
#ifndef KQUICKSYNTAXHIGHLIGHTER_H
#define KQUICKSYNTAXHIGHLIGHTER_H
#include "repositorywrapper.h"
#include <KSyntaxHighlighting/Definition>
#include <KSyntaxHighlighting/Theme>
@@ -29,7 +27,7 @@ class KQuickSyntaxHighlighter : public QObject
Q_PROPERTY(QObject *textEdit READ textEdit WRITE setTextEdit NOTIFY textEditChanged)
Q_PROPERTY(QVariant definition READ definition WRITE setDefinition NOTIFY definitionChanged)
Q_PROPERTY(QVariant theme READ theme WRITE setTheme NOTIFY themeChanged)
Q_PROPERTY(RepositoryWrapper *repository READ repository WRITE setRepository NOTIFY repositoryChanged)
Q_PROPERTY(KSyntaxHighlighting::Repository *repository READ repository WRITE setRepository NOTIFY repositoryChanged)
public:
explicit KQuickSyntaxHighlighter(QObject *parent = nullptr);
@@ -44,8 +42,8 @@ public:
QVariant theme() const;
void setTheme(const QVariant &theme);
RepositoryWrapper *repository() const;
void setRepository(RepositoryWrapper *repository);
KSyntaxHighlighting::Repository *repository() const;
void setRepository(KSyntaxHighlighting::Repository *repository);
Q_SIGNALS:
void textEditChanged() const;
@@ -59,7 +57,7 @@ private:
QObject *m_textEdit;
KSyntaxHighlighting::Definition m_definition;
KSyntaxHighlighting::Theme m_theme;
RepositoryWrapper *m_repository = nullptr;
KSyntaxHighlighting::Repository *m_repository = nullptr;
KSyntaxHighlighting::SyntaxHighlighter *m_highlighter = nullptr;
};

View File

@@ -7,7 +7,6 @@
#include "kquicksyntaxhighlightingplugin.h"
#include "kquicksyntaxhighlighter.h"
#include "repositorywrapper.h"
#include <KSyntaxHighlighting/Definition>
#include <KSyntaxHighlighting/Repository>
@@ -30,17 +29,18 @@ void KQuickSyntaxHighlightingPlugin::registerTypes(const char *uri)
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("org.kde.syntaxhighlighting"));
qRegisterMetaType<Definition>();
qRegisterMetaType<QVector<Definition>>();
qRegisterMetaType<QList<Definition>>();
qRegisterMetaType<Theme>();
qRegisterMetaType<QVector<Theme>>();
qRegisterMetaType<QList<Theme>>();
qmlRegisterType<KQuickSyntaxHighlighter>(uri, 1, 0, "SyntaxHighlighter");
qmlRegisterUncreatableType<Definition>(uri, 1, 0, "Definition", {});
qmlRegisterUncreatableType<Theme>(uri, 1, 0, "Theme", {});
qmlRegisterSingletonType<RepositoryWrapper>(uri, 1, 0, "Repository", [](auto engine, auto scriptEngine) {
qmlRegisterUncreatableMetaObject(Definition::staticMetaObject, uri, 1, 0, "Definition", {});
qmlRegisterUncreatableMetaObject(Theme::staticMetaObject, uri, 1, 0, "Theme", {});
qmlRegisterSingletonType<Repository>(uri, 1, 0, "Repository", [](auto engine, auto scriptEngine) {
(void)engine;
(void)scriptEngine;
auto repo = new RepositoryWrapper;
repo->m_repository = defaultRepository();
return repo;
auto repo = defaultRepository();
scriptEngine->setObjectOwnership(repo, QJSEngine::CppOwnership);
return defaultRepository();
});
}
#include "moc_kquicksyntaxhighlightingplugin.cpp"

View File

@@ -1,65 +0,0 @@
/*
SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: MIT
*/
#include "repositorywrapper.h"
#include <KSyntaxHighlighting/Definition>
#include <KSyntaxHighlighting/Repository>
#include <KSyntaxHighlighting/Theme>
using namespace KSyntaxHighlighting;
RepositoryWrapper::RepositoryWrapper(QObject *parent)
: QObject(parent)
{
}
Definition RepositoryWrapper::definitionForName(const QString &defName) const
{
return m_repository->definitionForName(defName);
}
Definition RepositoryWrapper::definitionForFileName(const QString &fileName) const
{
return m_repository->definitionForFileName(fileName);
}
QVector<Definition> RepositoryWrapper::definitionsForFileName(const QString &fileName) const
{
return m_repository->definitionsForFileName(fileName);
}
Definition RepositoryWrapper::definitionForMimeType(const QString &mimeType) const
{
return m_repository->definitionForMimeType(mimeType);
}
QVector<Definition> RepositoryWrapper::definitionsForMimeType(const QString &mimeType) const
{
return m_repository->definitionsForMimeType(mimeType);
}
QVector<Definition> RepositoryWrapper::definitions() const
{
return m_repository->definitions();
}
QVector<Theme> RepositoryWrapper::themes() const
{
return m_repository->themes();
}
Theme RepositoryWrapper::theme(const QString &themeName) const
{
return m_repository->theme(themeName);
}
Theme RepositoryWrapper::defaultTheme(DefaultTheme t) const
{
return m_repository->defaultTheme(static_cast<Repository::DefaultTheme>(t));
}
#include "moc_repositorywrapper.cpp"

View File

@@ -1,45 +0,0 @@
/*
SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: MIT
*/
#ifndef REPOSITORYWRAPPER_H
#define REPOSITORYWRAPPER_H
#include <QObject>
namespace KSyntaxHighlighting
{
class Definition;
class Repository;
class Theme;
}
// TODO KF6: merge this into KSyntaxHighlighting::Repository
class RepositoryWrapper : public QObject
{
Q_OBJECT
// TODO KF6: NOTIFY on reload
Q_PROPERTY(QVector<KSyntaxHighlighting::Definition> definitions READ definitions CONSTANT)
Q_PROPERTY(QVector<KSyntaxHighlighting::Theme> themes READ themes CONSTANT)
public:
explicit RepositoryWrapper(QObject *parent = nullptr);
Q_INVOKABLE KSyntaxHighlighting::Definition definitionForName(const QString &defName) const;
Q_INVOKABLE KSyntaxHighlighting::Definition definitionForFileName(const QString &fileName) const;
Q_INVOKABLE QVector<KSyntaxHighlighting::Definition> definitionsForFileName(const QString &fileName) const;
Q_INVOKABLE KSyntaxHighlighting::Definition definitionForMimeType(const QString &mimeType) const;
Q_INVOKABLE QVector<KSyntaxHighlighting::Definition> definitionsForMimeType(const QString &mimeType) const;
QVector<KSyntaxHighlighting::Definition> definitions() const;
QVector<KSyntaxHighlighting::Theme> themes() const;
Q_INVOKABLE KSyntaxHighlighting::Theme theme(const QString &themeName) const;
enum DefaultTheme { LightTheme, DarkTheme };
Q_ENUM(DefaultTheme)
Q_INVOKABLE KSyntaxHighlighting::Theme defaultTheme(DefaultTheme t = LightTheme) const;
KSyntaxHighlighting::Repository *m_repository = nullptr;
};
#endif // REPOSITORYWRAPPER_H

View File

@@ -25,7 +25,7 @@ Project {
name: "KSyntaxHighlighting_bundled"
condition: !qtc.preferSystemSyntaxHighlighting || !Qt.KSyntaxHighlighting.present
cpp.defines: base.concat("KF5SyntaxHighlighting_EXPORTS")
cpp.defines: base.concat("KF6SyntaxHighlighting_EXPORTS")
cpp.includePaths: [
product.sourceDirectory + "/src/lib/",
product.sourceDirectory + "/autogenerated/include/",
@@ -58,6 +58,7 @@ Project {
"definitiondownloader.cpp",
"definitiondownloader.h",
"definitionref_p.h",
"dynamicregexpcache_p.h",
"foldingregion.cpp",
"foldingregion.h",
"format.cpp",

View File

@@ -427,6 +427,10 @@ QFuture<PluginDumper::DependencyInfo> PluginDumper::loadDependencies(const FileP
Utils::onFinished(loadQmlTypeDescription(dependenciesPaths), const_cast<PluginDumper*>(this),
[this, iface, visited](const QFuture<PluginDumper::QmlTypeDescription> &typesFuture) {
if (typesFuture.resultCount() == 0 || typesFuture.isCanceled()) {
iface->reportCanceled();
return;
}
PluginDumper::QmlTypeDescription typesResult = typesFuture.result();
FilePaths newDependencies = FileUtils::toFilePathList(typesResult.dependencies);

View File

@@ -101,6 +101,9 @@ static PyObject *cdbext_resolveSymbol(PyObject *, PyObject *args) // -> Value
if (!PyArg_ParseTuple(args, "s", &pattern))
Py_RETURN_NONE;
if (debugPyCdbextModule)
DebugPrint() << "resolve symbol: " << pattern;
CIDebugSymbols *symbols = ExtensionCommandContext::instance()->symbols();
auto rc = PyList_New(0);
@@ -132,6 +135,9 @@ static PyObject *cdbext_getNameByAddress(PyObject *, PyObject *args)
if (!PyArg_ParseTuple(args, "K", &address))
Py_RETURN_NONE;
if (debugPyCdbextModule)
DebugPrint() << "name by address: " << address;
CIDebugSymbols *symbols = ExtensionCommandContext::instance()->symbols();
PyObject* ret = NULL;
@@ -153,6 +159,9 @@ static PyObject *cdbext_getAddressByName(PyObject *, PyObject *args)
if (!PyArg_ParseTuple(args, "s", &name))
Py_RETURN_NONE;
if (debugPyCdbextModule)
DebugPrint() << "address by name: " << name;
CIDebugSymbols *symbols = ExtensionCommandContext::instance()->symbols();
ULONG64 address = 0;
@@ -177,6 +186,14 @@ static PyObject *cdbext_listOfLocals(PyObject *, PyObject *args) // -> [ Value ]
Py_RETURN_NONE;
const std::string partialVariable(partialVariablesC);
if (debugPyCdbextModule) {
if (partialVariable.empty())
DebugPrint() << "list of locals";
else
DebugPrint() << "list of locals with partial variable: " << partialVariable;
}
IDebugSymbolGroup2 *symbolGroup = nullptr;
auto locals = PyList_New(0);
if (partialVariable.empty()) {

View File

@@ -1178,6 +1178,8 @@ GroupItem workflowPolicy(WorkflowPolicy policy)
return Group::workflowPolicy(policy);
}
const GroupItem nullItem = GroupItem({});
const GroupItem sequential = parallelLimit(1);
const GroupItem parallel = parallelLimit(0);

Some files were not shown because too many files have changed in this diff Show More