Add CMake syntax highlighting and format detection

This commit is contained in:
ema
2025-07-09 04:16:19 +08:00
parent 631fd91219
commit 67dc0ce10d
6 changed files with 243 additions and 12 deletions

View File

@@ -20,11 +20,11 @@ using System.IO;
namespace QuickLook.Plugin.TextViewer.Detectors; namespace QuickLook.Plugin.TextViewer.Detectors;
public sealed class CMakeListsDetector : IFormatDetector public sealed class CMakeListsDetector : IConfusedFormatDetector
{ {
public string Name => "CMakeLists"; public string Name => "CMake";
public string Extension => ".txt"; public string Extension => ".cmake";
public bool Detect(string path, string text) public bool Detect(string path, string text)
{ {

View File

@@ -24,7 +24,7 @@ public sealed class DockerfileDetector : IFormatDetector
{ {
public string Name => "Dockerfile"; public string Name => "Dockerfile";
public string Extension => ".df"; public string Extension => null;
public bool Detect(string path, string text) public bool Detect(string path, string text)
{ {

View File

@@ -28,18 +28,26 @@ public class FormatDetector
new XMLDetector(), new XMLDetector(),
new JSONDetector(), new JSONDetector(),
new MakefileDetector(), new MakefileDetector(),
new CMakeListsDetector(),
//new HostsDetector(), //new HostsDetector(),
//new CMakeListsDetector(),
//new DockerfileDetector(), //new DockerfileDetector(),
]; ];
public static IFormatDetector Detect(string path, string text) public static IConfusedFormatDetector ResolveConfusedFormat(string path, string text)
{ {
_ = path;
if (string.IsNullOrWhiteSpace(text)) return null; if (string.IsNullOrWhiteSpace(text)) return null;
return Instance.TextDetectors.Where(detector => detector.Detect(path, text)) return Instance.TextDetectors
.Where(detector => detector is IConfusedFormatDetector && detector.Detect(path, text))
.FirstOrDefault() as IConfusedFormatDetector;
}
public static IFormatDetector Detect(string path, string text)
{
if (string.IsNullOrWhiteSpace(text)) return null;
return Instance.TextDetectors
.Where(detector => detector is not IConfusedFormatDetector && detector.Detect(path, text))
.FirstOrDefault(); .FirstOrDefault();
} }
} }
@@ -52,3 +60,5 @@ public interface IFormatDetector
public bool Detect(string path, string text); public bool Detect(string path, string text);
} }
public interface IConfusedFormatDetector : IFormatDetector;

View File

@@ -24,7 +24,7 @@ public sealed class HostsDetector : IFormatDetector
{ {
public string Name => "Hosts"; public string Name => "Hosts";
public string Extension => ".hosts"; public string Extension => null;
public bool Detect(string path, string text) public bool Detect(string path, string text)
{ {

View File

@@ -0,0 +1,190 @@
<?xml version="1.0" encoding="utf-8"?>
<SyntaxDefinition name="CMake" extensions=".cmake">
<Environment>
<Default color="Black" bgcolor="#FFFFFF"/>
<Selection color="Black" bgcolor="#C3C3FF"/>
<LineNumbers color="Gray" bgcolor="#FFFFFF"/>
<CaretMarker color="#F0F0F1"/>
<VRuler color="#E0E0E5"/>
<FoldLine color="#A0A0A0" bgcolor="#FFFFFF"/>
<FoldMarker color="Black" bgcolor="#FFFFFF"/>
<SelectedFoldLine color="Black" bgcolor="#FFFFFF"/>
</Environment>
<Properties>
<Property name="LineComment" value="#"/>
</Properties>
<Digits name="Digits" color="#BF382A"/>
<RuleSets>
<RuleSet ignorecase="false">
<Delimiters>()[]{},:.`=;+-*/%~ &amp;|^&gt;&lt;</Delimiters>
<Span name="LineComment" stopateol="true" color="Green" bold="false" italic="false">
<Begin>#</Begin>
</Span>
<Span name="BracketComment" stopateol="false" color="Green" bold="false" italic="false">
<Begin>#[[</Begin>
<End>]]</End>
</Span>
<Span name="String" stopateol="true" color="#808080" bold="false" italic="false" escapecharacter="\">
<Begin>"</Begin>
<End>"</End>
</Span>
<Span name="Char" stopateol="true" color="#808080" bold="false" italic="false" escapecharacter="\">
<Begin>'</Begin>
<End>'</End>
</Span>
<Span name="Preprocessor" stopateol="true" color="Sienna" bold="false" italic="false">
<Begin>$</Begin>
</Span>
<Span name="Variable" stopateol="false" color="Purple" bold="false" italic="false">
<Begin>${</Begin>
<End>}</End>
</Span>
<Span name="GeneratorExpression" stopateol="false" color="DarkBlue" bold="true" italic="false">
<Begin>$&lt;</Begin>
<End>&gt;</End>
</Span>
<KeyWords name="Keywords1" color="Blue" bold="false" italic="false">
<Key word="add_custom_command"/>
<Key word="add_custom_target"/>
<Key word="add_definitions"/>
<Key word="add_dependencies"/>
<Key word="add_executable"/>
<Key word="add_library"/>
<Key word="add_subdirectory"/>
<Key word="add_test"/>
<Key word="cmake_minimum_required"/>
<Key word="configure_file"/>
<Key word="enable_testing"/>
<Key word="find_library"/>
<Key word="find_package"/>
<Key word="find_path"/>
<Key word="find_program"/>
<Key word="include"/>
<Key word="include_directories"/>
<Key word="install"/>
<Key word="link_directories"/>
<Key word="link_libraries"/>
<Key word="list"/>
<Key word="message"/>
<Key word="project"/>
<Key word="set"/>
<Key word="set_property"/>
<Key word="set_target_properties"/>
<Key word="target_compile_definitions"/>
<Key word="target_compile_options"/>
<Key word="target_include_directories"/>
<Key word="target_link_libraries"/>
<Key word="unset"/>
</KeyWords>
<KeyWords name="Keywords2" color="DarkViolet" bold="false" italic="false">
<Key word="if"/>
<Key word="else"/>
<Key word="elseif"/>
<Key word="endif"/>
<Key word="while"/>
<Key word="endwhile"/>
<Key word="foreach"/>
<Key word="endforeach"/>
<Key word="function"/>
<Key word="endfunction"/>
<Key word="macro"/>
<Key word="endmacro"/>
</KeyWords>
<KeyWords name="Keywords3" color="Red" bold="false" italic="false">
<Key word="ON"/>
<Key word="OFF"/>
<Key word="TRUE"/>
<Key word="FALSE"/>
<Key word="CACHE"/>
<Key word="INTERNAL"/>
<Key word="FORCE"/>
<Key word="STATIC"/>
<Key word="SHARED"/>
<Key word="MODULE"/>
<Key word="INTERFACE"/>
<Key word="PUBLIC"/>
<Key word="PRIVATE"/>
</KeyWords>
<KeyWords name="Keywords4" color="Sienna" bold="false" italic="false">
<Key word="EQUAL"/>
<Key word="LESS"/>
<Key word="GREATER"/>
<Key word="STREQUAL"/>
<Key word="STRLESS"/>
<Key word="STRGREATER"/>
<Key word="MATCHES"/>
<Key word="VERSION_EQUAL"/>
<Key word="VERSION_LESS"/>
<Key word="VERSION_GREATER"/>
<Key word="EXISTS"/>
<Key word="IS_DIRECTORY"/>
<Key word="IS_NEWER_THAN"/>
<Key word="AND"/>
<Key word="OR"/>
<Key word="NOT"/>
<Key word="DEFINED"/>
<Key word="COMMAND"/>
<Key word="POLICY"/>
<Key word="TARGET"/>
</KeyWords>
<KeyWords name="Keywords5" color="DarkMagenta" bold="false" italic="false">
<Key word="CMAKE_SOURCE_DIR"/>
<Key word="CMAKE_BINARY_DIR"/>
<Key word="CMAKE_CURRENT_SOURCE_DIR"/>
<Key word="CMAKE_CURRENT_BINARY_DIR"/>
<Key word="CMAKE_CURRENT_LIST_DIR"/>
<Key word="CMAKE_CURRENT_LIST_FILE"/>
<Key word="CMAKE_MODULE_PATH"/>
<Key word="CMAKE_PREFIX_PATH"/>
<Key word="CMAKE_INSTALL_PREFIX"/>
<Key word="CMAKE_BUILD_TYPE"/>
<Key word="CMAKE_CXX_STANDARD"/>
<Key word="CMAKE_C_STANDARD"/>
<Key word="CMAKE_CXX_COMPILER"/>
<Key word="CMAKE_C_COMPILER"/>
<Key word="CMAKE_SYSTEM_NAME"/>
<Key word="CMAKE_SYSTEM_VERSION"/>
<Key word="CMAKE_SYSTEM_PROCESSOR"/>
<Key word="PROJECT_NAME"/>
<Key word="PROJECT_VERSION"/>
<Key word="PROJECT_SOURCE_DIR"/>
<Key word="PROJECT_BINARY_DIR"/>
</KeyWords>
</RuleSet>
<RuleSet name="Doxygen" ignorecase="false">
<Delimiters>~!%^*()+=|\#/{}[];"'&lt;&gt; , .?</Delimiters>
<KeyWords name="Keywords1" color="DimGray" bold="false" italic="false">
<Key word="@author"/>
<Key word="@brief"/>
<Key word="@param"/>
<Key word="@return"/>
<Key word="@note"/>
<Key word="@warning"/>
<Key word="@deprecated"/>
<Key word="@since"/>
<Key word="@see"/>
</KeyWords>
</RuleSet>
</RuleSets>
</SyntaxDefinition>

View File

@@ -46,16 +46,29 @@ public class HighlightingThemeManager
{ {
if (Light is null || Dark is null) return HighlightingTheme.Default; if (Light is null || Dark is null) return HighlightingTheme.Default;
var useFormatDetector = SettingHelper.Get("UseFormatDetector", true, "QuickLook.Plugin.TextViewer");
var highlightingTheme = GetDefinitionByExtension(nameof(Dark), extension); var highlightingTheme = GetDefinitionByExtension(nameof(Dark), extension);
if (useFormatDetector && FormatDetector.ResolveConfusedFormat(path, text) is IConfusedFormatDetector confusedFormatDetector)
{
if (!string.IsNullOrEmpty(confusedFormatDetector.Extension))
{
highlightingTheme = GetDefinitionByExtension(nameof(Dark), confusedFormatDetector.Extension)
?? GetDefinitionByExtension(nameof(Light), confusedFormatDetector.Extension);
}
else
{
highlightingTheme = GetDefinition(nameof(Dark), confusedFormatDetector.Name)
?? GetDefinition(nameof(Light), confusedFormatDetector.Name);
}
}
if (highlightingTheme == null) if (highlightingTheme == null)
{ {
highlightingTheme = GetDefinitionByExtension(nameof(Light), extension); highlightingTheme = GetDefinitionByExtension(nameof(Light), extension);
if (highlightingTheme == null) if (highlightingTheme == null)
{ {
var useFormatDetector = SettingHelper.Get("UseFormatDetector", true, "QuickLook.Plugin.TextViewer");
if (useFormatDetector && FormatDetector.Detect(path, text)?.Extension is string detectExtension) if (useFormatDetector && FormatDetector.Detect(path, text)?.Extension is string detectExtension)
{ {
highlightingTheme = GetDefinitionByExtension(nameof(Dark), detectExtension) highlightingTheme = GetDefinitionByExtension(nameof(Dark), detectExtension)
@@ -85,6 +98,24 @@ public class HighlightingThemeManager
return highlightingTheme; return highlightingTheme;
} }
private static HighlightingTheme GetDefinition(string theme, string extension)
{
var highlightingManager = theme == nameof(Dark) ? Dark : Light;
var def = highlightingManager.GetDefinition(extension);
if (def != null)
{
return new HighlightingTheme()
{
Theme = theme,
HighlightingManager = highlightingManager,
SyntaxHighlighting = def,
Extension = extension,
};
}
return null;
}
private static HighlightingTheme GetDefinitionByExtension(string theme, string extension) private static HighlightingTheme GetDefinitionByExtension(string theme, string extension)
{ {
var highlightingManager = theme == nameof(Dark) ? Dark : Light; var highlightingManager = theme == nameof(Dark) ? Dark : Light;