151 lines
4.8 KiB
C#
151 lines
4.8 KiB
C#
|
|
using System;
|
||
|
|
using System.Linq;
|
||
|
|
|
||
|
|
using TextMateSharp.Grammars;
|
||
|
|
using TextMateSharp.Model;
|
||
|
|
using TextMateSharp.Registry;
|
||
|
|
using TextMateSharp.Themes;
|
||
|
|
|
||
|
|
namespace Unity.CodeEditor.TextMate
|
||
|
|
{
|
||
|
|
internal static class TextMate
|
||
|
|
{
|
||
|
|
internal static void RegisterExceptionHandler(Action<Exception> handler)
|
||
|
|
{
|
||
|
|
_exceptionHandler = handler;
|
||
|
|
}
|
||
|
|
|
||
|
|
internal static Installation InstallTextMate(
|
||
|
|
this TextEditor editor,
|
||
|
|
IRegistryOptions registryOptions,
|
||
|
|
bool initCurrentDocument = true)
|
||
|
|
{
|
||
|
|
return new Installation(editor, registryOptions, initCurrentDocument);
|
||
|
|
}
|
||
|
|
|
||
|
|
internal class Installation
|
||
|
|
{
|
||
|
|
private IRegistryOptions _textMateRegistryOptions;
|
||
|
|
private Registry _textMateRegistry;
|
||
|
|
private TextEditor _editor;
|
||
|
|
private TextEditorModel _editorModel;
|
||
|
|
private IGrammar _grammar;
|
||
|
|
private TMModel _tmModel;
|
||
|
|
private TextMateColoringTransformer _transformer;
|
||
|
|
|
||
|
|
internal IRegistryOptions RegistryOptions { get { return _textMateRegistryOptions; } }
|
||
|
|
internal TextEditorModel EditorModel { get { return _editorModel; } }
|
||
|
|
|
||
|
|
internal Installation(TextEditor editor, IRegistryOptions registryOptions, bool initCurrentDocument = true)
|
||
|
|
{
|
||
|
|
_textMateRegistryOptions = registryOptions;
|
||
|
|
_textMateRegistry = new Registry(registryOptions);
|
||
|
|
|
||
|
|
_editor = editor;
|
||
|
|
|
||
|
|
SetTheme(registryOptions.GetDefaultTheme());
|
||
|
|
|
||
|
|
editor.DocumentChanged += OnEditorOnDocumentChanged;
|
||
|
|
|
||
|
|
if (initCurrentDocument)
|
||
|
|
{
|
||
|
|
OnEditorOnDocumentChanged(editor, EventArgs.Empty);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
internal void SetGrammar(string scopeName)
|
||
|
|
{
|
||
|
|
_grammar = _textMateRegistry.LoadGrammar(scopeName);
|
||
|
|
|
||
|
|
GetOrCreateTransformer().SetGrammar(_grammar);
|
||
|
|
|
||
|
|
_editor.TextArea.TextView.Redraw();
|
||
|
|
}
|
||
|
|
|
||
|
|
internal void SetTheme(IRawTheme theme)
|
||
|
|
{
|
||
|
|
_textMateRegistry.SetTheme(theme);
|
||
|
|
|
||
|
|
GetOrCreateTransformer().SetTheme(_textMateRegistry.GetTheme());
|
||
|
|
|
||
|
|
_tmModel?.InvalidateLine(0);
|
||
|
|
|
||
|
|
_editorModel?.InvalidateViewPortLines();
|
||
|
|
}
|
||
|
|
|
||
|
|
internal void Dispose()
|
||
|
|
{
|
||
|
|
_editor.DocumentChanged -= OnEditorOnDocumentChanged;
|
||
|
|
|
||
|
|
DisposeEditorModel(_editorModel);
|
||
|
|
DisposeTMModel(_tmModel, _transformer);
|
||
|
|
DisposeTransformer(_transformer);
|
||
|
|
}
|
||
|
|
|
||
|
|
void OnEditorOnDocumentChanged(object sender, EventArgs args)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
DisposeEditorModel(_editorModel);
|
||
|
|
DisposeTMModel(_tmModel, _transformer);
|
||
|
|
|
||
|
|
_editorModel = new TextEditorModel(_editor.TextArea.TextView, _editor.Document, _exceptionHandler);
|
||
|
|
_tmModel = new TMModel(_editorModel);
|
||
|
|
_tmModel.SetGrammar(_grammar);
|
||
|
|
_transformer = GetOrCreateTransformer();
|
||
|
|
_transformer.SetModel(_editor.Document, _tmModel);
|
||
|
|
_tmModel.AddModelTokensChangedListener(_transformer);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
_exceptionHandler?.Invoke(ex);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
TextMateColoringTransformer GetOrCreateTransformer()
|
||
|
|
{
|
||
|
|
var transformer = _editor.TextArea.TextView.LineTransformers.OfType<TextMateColoringTransformer>().FirstOrDefault();
|
||
|
|
|
||
|
|
if (transformer is null)
|
||
|
|
{
|
||
|
|
transformer = new TextMateColoringTransformer(
|
||
|
|
_editor.TextArea.TextView, _exceptionHandler);
|
||
|
|
|
||
|
|
_editor.TextArea.TextView.LineTransformers.Add(transformer);
|
||
|
|
}
|
||
|
|
|
||
|
|
return transformer;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void DisposeTransformer(TextMateColoringTransformer transformer)
|
||
|
|
{
|
||
|
|
if (transformer == null)
|
||
|
|
return;
|
||
|
|
|
||
|
|
transformer.Dispose();
|
||
|
|
}
|
||
|
|
|
||
|
|
static void DisposeTMModel(TMModel tmModel, TextMateColoringTransformer transformer)
|
||
|
|
{
|
||
|
|
if (tmModel == null)
|
||
|
|
return;
|
||
|
|
|
||
|
|
if (transformer != null)
|
||
|
|
tmModel.RemoveModelTokensChangedListener(transformer);
|
||
|
|
|
||
|
|
tmModel.Dispose();
|
||
|
|
}
|
||
|
|
|
||
|
|
static void DisposeEditorModel(TextEditorModel editorModel)
|
||
|
|
{
|
||
|
|
if (editorModel == null)
|
||
|
|
return;
|
||
|
|
|
||
|
|
editorModel.Dispose();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static Action<Exception> _exceptionHandler;
|
||
|
|
}
|
||
|
|
}
|