From e86716fc54c79cdb0994c6b8879801de14e46c54 Mon Sep 17 00:00:00 2001 From: ema Date: Sun, 22 Jun 2025 23:31:59 +0800 Subject: [PATCH] Support .properties --- .../TextViewerPanel.cs | 9 +++ .../ColorExtensions.cs | 39 +++++++++++ .../CustomHighlightingDefinition.cs | 62 ++++++++++++++++++ .../Dark/PropertiesHighlightingDefinition.cs | 63 ++++++++++++++++++ .../Light/PropertiesHighlightingDefinition.cs | 65 +++++++++++++++++++ .../Themes/HighlightingThemeManager.cs | 28 +++++++- 6 files changed, 264 insertions(+), 2 deletions(-) create mode 100644 QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/ColorExtensions.cs create mode 100644 QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/CustomHighlightingDefinition.cs create mode 100644 QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/PropertiesHighlightingDefinition.cs create mode 100644 QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/PropertiesHighlightingDefinition.cs diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/TextViewerPanel.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/TextViewerPanel.cs index cbf0c74..869ecdd 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/TextViewerPanel.cs +++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/TextViewerPanel.cs @@ -23,6 +23,7 @@ using QuickLook.Common.Helpers; using QuickLook.Common.Plugin; using QuickLook.Plugin.TextViewer.Detectors; using QuickLook.Plugin.TextViewer.Themes; +using QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions; using System; using System.IO; using System.Reflection; @@ -183,6 +184,14 @@ public partial class TextViewerPanel : TextEditor, IDisposable : highlighting.SyntaxHighlighting; Document = doc; + if (SyntaxHighlighting is ICustomHighlightingDefinition custom) + { + foreach (var lineTransformer in custom.LineTransformers) + { + TextArea.TextView.LineTransformers.Add(lineTransformer); + } + } + if (highlighting.IsDark) { Background = Brushes.Transparent; diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/ColorExtensions.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/ColorExtensions.cs new file mode 100644 index 0000000..042e868 --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/ColorExtensions.cs @@ -0,0 +1,39 @@ +using System; +using System.Globalization; +using System.Windows.Media; + +namespace QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions; + +internal static class ColorExtensions +{ + public static Color ToColor(this string hex) + { + if (string.IsNullOrWhiteSpace(hex)) + throw new ArgumentNullException(nameof(hex)); + + hex = hex.TrimStart('#'); + + if (hex.Length == 6) + hex = "FF" + hex; + + if (hex.Length != 8) + throw new FormatException("Hex color must be 6 (RGB) or 8 (ARGB) characters long."); + + byte a = byte.Parse(hex.Substring(0, 2), NumberStyles.HexNumber); + byte r = byte.Parse(hex.Substring(2, 2), NumberStyles.HexNumber); + byte g = byte.Parse(hex.Substring(4, 2), NumberStyles.HexNumber); + byte b = byte.Parse(hex.Substring(6, 2), NumberStyles.HexNumber); + + return Color.FromArgb(a, r, g, b); + } + + public static Brush ToBrush(this Color color) + { + return new SolidColorBrush(color); + } + + public static Brush ToBrush(this string hex) + { + return new SolidColorBrush(hex.ToColor()); + } +} diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/CustomHighlightingDefinition.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/CustomHighlightingDefinition.cs new file mode 100644 index 0000000..162a2a7 --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/CustomHighlightingDefinition.cs @@ -0,0 +1,62 @@ +using ICSharpCode.AvalonEdit.Highlighting; +using ICSharpCode.AvalonEdit.Rendering; +using System.Collections.Generic; +using System.ComponentModel; +using System.Windows.Media; + +namespace QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions; + +[TypeConverter(typeof(HighlightingDefinitionTypeConverter))] +public class CustomHighlightingDefinition : ICustomHighlightingDefinition +{ + public virtual string Theme => "Light"; + + public virtual string Name => null; + + public virtual string Extension => Name != null ? $".{Name}" : null; + + public virtual HighlightingRuleSet MainRuleSet => new(); + + public virtual HighlightingRuleSet GetNamedRuleSet(string name) => null; + + public virtual HighlightingColor GetNamedColor(string name) => null; + + public virtual IEnumerable NamedHighlightingColors => []; + + public virtual IDictionary Properties => new Dictionary(); + + public virtual HighlightingColor DefaultTextColor => new(); + + public virtual HighlightingRuleSet GetRuleSet(string name) => MainRuleSet; + + public virtual DocumentColorizingTransformer[] LineTransformers { get; } +} + +public class LightHighlightingDefinition : CustomHighlightingDefinition +{ + public override string Theme => "Light"; + + public override HighlightingColor DefaultTextColor => new() + { + Foreground = new SimpleHighlightingBrush(Colors.Black) + }; +} + +public class DarkHighlightingDefinition : CustomHighlightingDefinition +{ + public override string Theme => "Dark"; + + public override HighlightingColor DefaultTextColor => new() + { + Foreground = new SimpleHighlightingBrush("#D4D4C9".ToColor()) + }; +} + +public interface ICustomHighlightingDefinition : IHighlightingDefinition +{ + public string Theme { get; } + + public string Extension { get; } + + public DocumentColorizingTransformer[] LineTransformers { get; } +} diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/PropertiesHighlightingDefinition.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/PropertiesHighlightingDefinition.cs new file mode 100644 index 0000000..7ecb4e6 --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Dark/PropertiesHighlightingDefinition.cs @@ -0,0 +1,63 @@ +using ICSharpCode.AvalonEdit.Document; +using ICSharpCode.AvalonEdit.Highlighting; +using ICSharpCode.AvalonEdit.Rendering; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions.Dark; + +public class PropertiesHighlightingDefinition : DarkHighlightingDefinition +{ + public override string Name => "Properties"; + + public override string Extension => ".properties"; + + public override HighlightingRuleSet MainRuleSet => new() + { + Rules = + { + new HighlightingRule + { + Regex = new Regex(@"#.*", RegexOptions.Compiled), + Color = GetNamedColor("Comment") + } + } + }; + + public override HighlightingColor GetNamedColor(string name) + { + return name switch + { + "Comment" => new HighlightingColor + { + Name = "Comment", + Foreground = new SimpleHighlightingBrush("#6A9949".ToColor()), + }, + _ => null + }; + } + + public override IEnumerable NamedHighlightingColors => + [ + GetNamedColor("Comment") + ]; + + public override DocumentColorizingTransformer[] LineTransformers { get; } = [new KeyHighlighter()]; + + public class KeyHighlighter : DocumentColorizingTransformer + { + protected override void ColorizeLine(DocumentLine line) + { + var text = CurrentContext.Document.GetText(line); + int idx = text.IndexOf('='); + if (idx > 0) + { + ChangeLinePart( + line.Offset, + line.Offset + idx, + el => el.TextRunProperties.SetForegroundBrush("#3F9CD6".ToBrush()) + ); + } + } + } +} diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/PropertiesHighlightingDefinition.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/PropertiesHighlightingDefinition.cs new file mode 100644 index 0000000..094dd75 --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingDefinitions/Light/PropertiesHighlightingDefinition.cs @@ -0,0 +1,65 @@ +using ICSharpCode.AvalonEdit.Document; +using ICSharpCode.AvalonEdit.Highlighting; +using ICSharpCode.AvalonEdit.Rendering; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using System.Windows; +using System.Windows.Media; + +namespace QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions.Light; + +public class PropertiesHighlightingDefinition : LightHighlightingDefinition +{ + public override string Name => "Properties"; + + public override string Extension => ".properties"; + + public override HighlightingRuleSet MainRuleSet => new() + { + Rules = + { + new HighlightingRule + { + Regex = new Regex(@"#.*", RegexOptions.Compiled), + Color = GetNamedColor("Comment") + } + } + }; + + public override HighlightingColor GetNamedColor(string name) + { + return name switch + { + "Comment" => new HighlightingColor + { + Name = "Comment", + Foreground = new SimpleHighlightingBrush(Colors.Green), + }, + _ => null + }; + } + + public override IEnumerable NamedHighlightingColors => + [ + GetNamedColor("Comment") + ]; + + public override DocumentColorizingTransformer[] LineTransformers { get; } = [new KeyHighlighter()]; + + public class KeyHighlighter : DocumentColorizingTransformer + { + protected override void ColorizeLine(DocumentLine line) + { + var text = CurrentContext.Document.GetText(line); + int idx = text.IndexOf('='); + if (idx > 0) + { + ChangeLinePart( + line.Offset, + line.Offset + idx, + el => el.TextRunProperties.SetForegroundBrush(Colors.Blue.ToBrush()) + ); + } + } + } +} diff --git a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingThemeManager.cs b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingThemeManager.cs index a956b7b..02f9a56 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingThemeManager.cs +++ b/QuickLook.Plugin/QuickLook.Plugin.TextViewer/Themes/HighlightingThemeManager.cs @@ -19,12 +19,15 @@ using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.AvalonEdit.Highlighting.Xshd; using QuickLook.Common.Helpers; using QuickLook.Plugin.TextViewer.Detectors; +using QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions; using System; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Xml; +using DarkHighlightingDefinition = QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions.Dark; +using LightHighlightingDefinition = QuickLook.Plugin.TextViewer.Themes.HighlightingDefinitions.Light; namespace QuickLook.Plugin.TextViewer.Themes; @@ -37,8 +40,7 @@ public class HighlightingThemeManager public static void Initialize() { InitHighlightingManager(); - AddHighlightingManager(Light, nameof(Light)); - AddHighlightingManager(Dark, nameof(Dark)); + InitCustomHighlighting(); } public static HighlightingTheme GetHighlightingByExtensionOrDetector(string extension, string text = null) @@ -132,6 +134,9 @@ public class HighlightingThemeManager ProcessHelper.WriteLog(e.ToString()); } } + + AddHighlightingManager(Light, nameof(Light)); + AddHighlightingManager(Dark, nameof(Dark)); } private static void AddHighlightingManager(HighlightingManager hlm, string dirName) @@ -163,6 +168,25 @@ public class HighlightingThemeManager } } } + + private static void InitCustomHighlighting() + { + AddCustomHighlighting(Light, new LightHighlightingDefinition.PropertiesHighlightingDefinition()); + + AddCustomHighlighting(Dark, new DarkHighlightingDefinition.PropertiesHighlightingDefinition()); + } + + private static void AddCustomHighlighting(HighlightingManager hlm, CustomHighlightingDefinition definition) + { + try + { + hlm.RegisterHighlighting(definition.Name, definition.Extension.Split(';'), definition); + } + catch (Exception e) + { + ProcessHelper.WriteLog(e.ToString()); + } + } } file static class EmbeddedResource