Skip to content

Commit 39fba17

Browse files
committed
enhance: text editor (#365)
* support extra grammars. * avoid crashing on text editor detached from visual tree
1 parent a3496a9 commit 39fba17

File tree

6 files changed

+453
-33
lines changed

6 files changed

+453
-33
lines changed

src/Models/TextMateHelper.cs

Lines changed: 85 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,112 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.IO;
34

45
using Avalonia;
6+
using Avalonia.Platform;
57
using Avalonia.Styling;
68

79
using AvaloniaEdit;
810
using AvaloniaEdit.TextMate;
911

1012
using TextMateSharp.Grammars;
13+
using TextMateSharp.Internal.Grammars.Reader;
14+
using TextMateSharp.Internal.Types;
15+
using TextMateSharp.Registry;
16+
using TextMateSharp.Themes;
1117

1218
namespace SourceGit.Models
1319
{
20+
public class RegistryOptionsWrapper : IRegistryOptions
21+
{
22+
public RegistryOptionsWrapper(ThemeName defaultTheme)
23+
{
24+
_backend = new RegistryOptions(defaultTheme);
25+
_extraGrammars = new Dictionary<string, IRawGrammar>();
26+
27+
string[] extraGrammarFiles = ["toml.json"];
28+
foreach (var file in extraGrammarFiles)
29+
{
30+
var asset = AssetLoader.Open(new Uri($"avares://SourceGit/Resources/Grammars/{file}",
31+
UriKind.RelativeOrAbsolute));
32+
33+
try
34+
{
35+
var grammar = GrammarReader.ReadGrammarSync(new StreamReader(asset));
36+
_extraGrammars.Add(grammar.GetScopeName(), grammar);
37+
}
38+
catch
39+
{
40+
// ignore
41+
}
42+
}
43+
}
44+
45+
public IRawTheme GetTheme(string scopeName)
46+
{
47+
return _backend.GetTheme(scopeName);
48+
}
49+
50+
public IRawGrammar GetGrammar(string scopeName)
51+
{
52+
if (_extraGrammars.TryGetValue(scopeName, out var grammar))
53+
return grammar;
54+
55+
return _backend.GetGrammar(scopeName);
56+
}
57+
58+
public ICollection<string> GetInjections(string scopeName)
59+
{
60+
return _backend.GetInjections(scopeName);
61+
}
62+
63+
public IRawTheme GetDefaultTheme()
64+
{
65+
return _backend.GetDefaultTheme();
66+
}
67+
68+
public IRawTheme LoadTheme(ThemeName name)
69+
{
70+
return _backend.LoadTheme(name);
71+
}
72+
73+
public string GetScopeByFileName(string filename)
74+
{
75+
var extension = Path.GetExtension(filename);
76+
var scope = $"source{extension}";
77+
if (_extraGrammars.ContainsKey(scope))
78+
return scope;
79+
80+
if (extension == ".h")
81+
extension = ".cpp";
82+
else if (extension == ".resx" || extension == ".plist")
83+
extension = ".xml";
84+
else if (extension == ".command")
85+
extension = ".sh";
86+
87+
return _backend.GetScopeByExtension(extension);
88+
}
89+
90+
private RegistryOptions _backend = null;
91+
private Dictionary<string, IRawGrammar> _extraGrammars = null;
92+
}
93+
1494
public static class TextMateHelper
1595
{
1696
public static TextMate.Installation CreateForEditor(TextEditor editor)
1797
{
1898
if (Application.Current?.ActualThemeVariant == ThemeVariant.Dark)
19-
return editor.InstallTextMate(new RegistryOptions(ThemeName.DarkPlus));
99+
return editor.InstallTextMate(new RegistryOptionsWrapper(ThemeName.DarkPlus));
20100

21-
return editor.InstallTextMate(new RegistryOptions(ThemeName.LightPlus));
101+
return editor.InstallTextMate(new RegistryOptionsWrapper(ThemeName.LightPlus));
22102
}
23103

24104
public static void SetThemeByApp(TextMate.Installation installation)
25105
{
26106
if (installation == null)
27107
return;
28108

29-
if (installation.RegistryOptions is RegistryOptions reg)
109+
if (installation.RegistryOptions is RegistryOptionsWrapper reg)
30110
{
31111
if (Application.Current?.ActualThemeVariant == ThemeVariant.Dark)
32112
installation.SetTheme(reg.LoadTheme(ThemeName.DarkPlus));
@@ -37,15 +117,9 @@ public static void SetThemeByApp(TextMate.Installation installation)
37117

38118
public static void SetGrammarByFileName(TextMate.Installation installation, string filePath)
39119
{
40-
if (installation is { RegistryOptions: RegistryOptions reg })
120+
if (installation is { RegistryOptions: RegistryOptionsWrapper reg })
41121
{
42-
var ext = Path.GetExtension(filePath);
43-
if (ext == ".h")
44-
ext = ".cpp";
45-
else if (ext == ".resx" || ext == ".plist")
46-
ext = ".xml";
47-
48-
installation.SetGrammar(reg.GetScopeByExtension(ext));
122+
installation.SetGrammar(reg.GetScopeByFileName(filePath));
49123
GC.Collect();
50124
}
51125
}

src/Native/Linux.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Runtime.Versioning;
66

77
using Avalonia;
8-
using Avalonia.Dialogs;
98
using Avalonia.Media;
109

1110
namespace SourceGit.Native

0 commit comments

Comments
 (0)