mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-10-31 13:03:20 -07:00
enhance: text editor (#365)
* support extra grammars. * avoid crashing on text editor detached from visual tree
This commit is contained in:
parent
a3496a9d2f
commit
39fba17648
6 changed files with 453 additions and 33 deletions
|
@ -1,24 +1,104 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
|
using Avalonia.Platform;
|
||||||
using Avalonia.Styling;
|
using Avalonia.Styling;
|
||||||
|
|
||||||
using AvaloniaEdit;
|
using AvaloniaEdit;
|
||||||
using AvaloniaEdit.TextMate;
|
using AvaloniaEdit.TextMate;
|
||||||
|
|
||||||
using TextMateSharp.Grammars;
|
using TextMateSharp.Grammars;
|
||||||
|
using TextMateSharp.Internal.Grammars.Reader;
|
||||||
|
using TextMateSharp.Internal.Types;
|
||||||
|
using TextMateSharp.Registry;
|
||||||
|
using TextMateSharp.Themes;
|
||||||
|
|
||||||
namespace SourceGit.Models
|
namespace SourceGit.Models
|
||||||
{
|
{
|
||||||
|
public class RegistryOptionsWrapper : IRegistryOptions
|
||||||
|
{
|
||||||
|
public RegistryOptionsWrapper(ThemeName defaultTheme)
|
||||||
|
{
|
||||||
|
_backend = new RegistryOptions(defaultTheme);
|
||||||
|
_extraGrammars = new Dictionary<string, IRawGrammar>();
|
||||||
|
|
||||||
|
string[] extraGrammarFiles = ["toml.json"];
|
||||||
|
foreach (var file in extraGrammarFiles)
|
||||||
|
{
|
||||||
|
var asset = AssetLoader.Open(new Uri($"avares://SourceGit/Resources/Grammars/{file}",
|
||||||
|
UriKind.RelativeOrAbsolute));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var grammar = GrammarReader.ReadGrammarSync(new StreamReader(asset));
|
||||||
|
_extraGrammars.Add(grammar.GetScopeName(), grammar);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IRawTheme GetTheme(string scopeName)
|
||||||
|
{
|
||||||
|
return _backend.GetTheme(scopeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IRawGrammar GetGrammar(string scopeName)
|
||||||
|
{
|
||||||
|
if (_extraGrammars.TryGetValue(scopeName, out var grammar))
|
||||||
|
return grammar;
|
||||||
|
|
||||||
|
return _backend.GetGrammar(scopeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICollection<string> GetInjections(string scopeName)
|
||||||
|
{
|
||||||
|
return _backend.GetInjections(scopeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IRawTheme GetDefaultTheme()
|
||||||
|
{
|
||||||
|
return _backend.GetDefaultTheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IRawTheme LoadTheme(ThemeName name)
|
||||||
|
{
|
||||||
|
return _backend.LoadTheme(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetScopeByFileName(string filename)
|
||||||
|
{
|
||||||
|
var extension = Path.GetExtension(filename);
|
||||||
|
var scope = $"source{extension}";
|
||||||
|
if (_extraGrammars.ContainsKey(scope))
|
||||||
|
return scope;
|
||||||
|
|
||||||
|
if (extension == ".h")
|
||||||
|
extension = ".cpp";
|
||||||
|
else if (extension == ".resx" || extension == ".plist")
|
||||||
|
extension = ".xml";
|
||||||
|
else if (extension == ".command")
|
||||||
|
extension = ".sh";
|
||||||
|
|
||||||
|
return _backend.GetScopeByExtension(extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RegistryOptions _backend = null;
|
||||||
|
private Dictionary<string, IRawGrammar> _extraGrammars = null;
|
||||||
|
}
|
||||||
|
|
||||||
public static class TextMateHelper
|
public static class TextMateHelper
|
||||||
{
|
{
|
||||||
public static TextMate.Installation CreateForEditor(TextEditor editor)
|
public static TextMate.Installation CreateForEditor(TextEditor editor)
|
||||||
{
|
{
|
||||||
if (Application.Current?.ActualThemeVariant == ThemeVariant.Dark)
|
if (Application.Current?.ActualThemeVariant == ThemeVariant.Dark)
|
||||||
return editor.InstallTextMate(new RegistryOptions(ThemeName.DarkPlus));
|
return editor.InstallTextMate(new RegistryOptionsWrapper(ThemeName.DarkPlus));
|
||||||
|
|
||||||
return editor.InstallTextMate(new RegistryOptions(ThemeName.LightPlus));
|
return editor.InstallTextMate(new RegistryOptionsWrapper(ThemeName.LightPlus));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetThemeByApp(TextMate.Installation installation)
|
public static void SetThemeByApp(TextMate.Installation installation)
|
||||||
|
@ -26,7 +106,7 @@ namespace SourceGit.Models
|
||||||
if (installation == null)
|
if (installation == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (installation.RegistryOptions is RegistryOptions reg)
|
if (installation.RegistryOptions is RegistryOptionsWrapper reg)
|
||||||
{
|
{
|
||||||
if (Application.Current?.ActualThemeVariant == ThemeVariant.Dark)
|
if (Application.Current?.ActualThemeVariant == ThemeVariant.Dark)
|
||||||
installation.SetTheme(reg.LoadTheme(ThemeName.DarkPlus));
|
installation.SetTheme(reg.LoadTheme(ThemeName.DarkPlus));
|
||||||
|
@ -37,15 +117,9 @@ namespace SourceGit.Models
|
||||||
|
|
||||||
public static void SetGrammarByFileName(TextMate.Installation installation, string filePath)
|
public static void SetGrammarByFileName(TextMate.Installation installation, string filePath)
|
||||||
{
|
{
|
||||||
if (installation is { RegistryOptions: RegistryOptions reg })
|
if (installation is { RegistryOptions: RegistryOptionsWrapper reg })
|
||||||
{
|
{
|
||||||
var ext = Path.GetExtension(filePath);
|
installation.SetGrammar(reg.GetScopeByFileName(filePath));
|
||||||
if (ext == ".h")
|
|
||||||
ext = ".cpp";
|
|
||||||
else if (ext == ".resx" || ext == ".plist")
|
|
||||||
ext = ".xml";
|
|
||||||
|
|
||||||
installation.SetGrammar(reg.GetScopeByExtension(ext));
|
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ using System.IO;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Dialogs;
|
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
|
|
||||||
namespace SourceGit.Native
|
namespace SourceGit.Native
|
||||||
|
|
343
src/Resources/Grammars/toml.json
Normal file
343
src/Resources/Grammars/toml.json
Normal file
|
@ -0,0 +1,343 @@
|
||||||
|
{
|
||||||
|
"version": "1.0.0",
|
||||||
|
"scopeName": "source.toml",
|
||||||
|
"uuid": "8b4e5008-c50d-11ea-a91b-54ee75aeeb97",
|
||||||
|
"information_for_contributors": [
|
||||||
|
"Originally was maintained by aster (galaster@foxmail.com). This notice is only kept here for the record, please don't send e-mails about bugs and other issues."
|
||||||
|
],
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"include": "#commentDirective"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#comment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#table"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#entryBegin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#value"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"comment": {
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "comment.line.number-sign.toml"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"name": "punctuation.definition.comment.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"comment": "Comments",
|
||||||
|
"match": "\\s*((#).*)$"
|
||||||
|
},
|
||||||
|
"commentDirective": {
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "meta.preprocessor.toml"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"name": "punctuation.definition.meta.preprocessor.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"comment": "Comments",
|
||||||
|
"match": "\\s*((#):.*)$"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"name": "meta.table.toml",
|
||||||
|
"match": "^\\s*(\\[)\\s*((?:(?:(?:[A-Za-z0-9_+-]+)|(?:\"[^\"]+\")|(?:'[^']+'))\\s*\\.?\\s*)+)\\s*(\\])",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "punctuation.definition.table.toml"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"match": "(?:[A-Za-z0-9_+-]+)|(?:\"[^\"]+\")|(?:'[^']+')",
|
||||||
|
"name": "support.type.property-name.table.toml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "\\.",
|
||||||
|
"name": "punctuation.separator.dot.toml"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"name": "punctuation.definition.table.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "meta.array.table.toml",
|
||||||
|
"match": "^\\s*(\\[\\[)\\s*((?:(?:(?:[A-Za-z0-9_+-]+)|(?:\"[^\"]+\")|(?:'[^']+'))\\s*\\.?\\s*)+)\\s*(\\]\\])",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "punctuation.definition.array.table.toml"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"match": "(?:[A-Za-z0-9_+-]+)|(?:\"[^\"]+\")|(?:'[^']+')",
|
||||||
|
"name": "support.type.property-name.array.toml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "\\.",
|
||||||
|
"name": "punctuation.separator.dot.toml"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"name": "punctuation.definition.array.table.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "(\\{)",
|
||||||
|
"end": "(\\})",
|
||||||
|
"name": "meta.table.inline.toml",
|
||||||
|
"beginCaptures": {
|
||||||
|
"1": {
|
||||||
|
"name": "punctuation.definition.table.inline.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"endCaptures": {
|
||||||
|
"1": {
|
||||||
|
"name": "punctuation.definition.table.inline.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"include": "#comment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": ",",
|
||||||
|
"name": "punctuation.separator.table.inline.toml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#entryBegin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#value"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"entryBegin": {
|
||||||
|
"name": "meta.entry.toml",
|
||||||
|
"match": "\\s*((?:(?:(?:[A-Za-z0-9_+-]+)|(?:\"[^\"]+\")|(?:'[^']+'))\\s*\\.?\\s*)+)\\s*(=)",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"match": "(?:[A-Za-z0-9_+-]+)|(?:\"[^\"]+\")|(?:'[^']+')",
|
||||||
|
"name": "support.type.property-name.toml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "\\.",
|
||||||
|
"name": "punctuation.separator.dot.toml"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"name": "punctuation.eq.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"name": "string.quoted.triple.basic.block.toml",
|
||||||
|
"begin": "\"\"\"",
|
||||||
|
"end": "\"\"\"",
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"match": "\\\\([btnfr\"\\\\\\n/ ]|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})",
|
||||||
|
"name": "constant.character.escape.toml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "\\\\[^btnfr/\"\\\\\\n]",
|
||||||
|
"name": "invalid.illegal.escape.toml"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "string.quoted.single.basic.line.toml",
|
||||||
|
"begin": "\"",
|
||||||
|
"end": "\"",
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"match": "\\\\([btnfr\"\\\\\\n/ ]|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})",
|
||||||
|
"name": "constant.character.escape.toml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "\\\\[^btnfr/\"\\\\\\n]",
|
||||||
|
"name": "invalid.illegal.escape.toml"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "string.quoted.triple.literal.block.toml",
|
||||||
|
"begin": "'''",
|
||||||
|
"end": "'''"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "string.quoted.single.literal.line.toml",
|
||||||
|
"begin": "'",
|
||||||
|
"end": "'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.other.time.datetime.offset.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"match": "(?<!\\w)(\\d{4}\\-\\d{2}\\-\\d{2}[T| ]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[\\+\\-]\\d{2}:\\d{2}))(?!\\w)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.other.time.datetime.local.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"match": "(\\d{4}\\-\\d{2}\\-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "constant.other.time.date.toml",
|
||||||
|
"match": "\\d{4}\\-\\d{2}\\-\\d{2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "constant.other.time.time.toml",
|
||||||
|
"match": "\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "(?<!\\w)(true|false)(?!\\w)",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.language.boolean.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "(?<!\\w)([\\+\\-]?(0|([1-9](([0-9]|_[0-9])+)?))(?:(?:\\.([0-9]+))?[eE][\\+\\-]?[1-9]_?[0-9]*|(?:\\.[0-9_]*)))(?!\\w)",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.numeric.float.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "(?<!\\w)((?:[\\+\\-]?(0|([1-9](([0-9]|_[0-9])+)?))))(?!\\w)",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.numeric.integer.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "(?<!\\w)([\\+\\-]?inf)(?!\\w)",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.numeric.inf.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "(?<!\\w)([\\+\\-]?nan)(?!\\w)",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.numeric.nan.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "(?<!\\w)((?:0x(([0-9a-fA-F](([0-9a-fA-F]|_[0-9a-fA-F])+)?))))(?!\\w)",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.numeric.hex.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "(?<!\\w)(0o[0-7](_?[0-7])*)(?!\\w)",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.numeric.oct.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "(?<!\\w)(0b[01](_?[01])*)(?!\\w)",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.numeric.bin.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "meta.array.toml",
|
||||||
|
"begin": "(?<!\\w)(\\[)\\s*",
|
||||||
|
"end": "\\s*(\\])(?!\\w)",
|
||||||
|
"beginCaptures": {
|
||||||
|
"1": {
|
||||||
|
"name": "punctuation.definition.array.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"endCaptures": {
|
||||||
|
"1": {
|
||||||
|
"name": "punctuation.definition.array.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"match": ",",
|
||||||
|
"name": "punctuation.separator.array.toml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#comment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#value"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "(\\{)",
|
||||||
|
"end": "(\\})",
|
||||||
|
"name": "meta.table.inline.toml",
|
||||||
|
"beginCaptures": {
|
||||||
|
"1": {
|
||||||
|
"name": "punctuation.definition.table.inline.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"endCaptures": {
|
||||||
|
"1": {
|
||||||
|
"name": "punctuation.definition.table.inline.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"include": "#comment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": ",",
|
||||||
|
"name": "punctuation.separator.table.inline.toml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#entryBegin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#value"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,6 +30,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AvaloniaResource Include="App.ico" />
|
<AvaloniaResource Include="App.ico" />
|
||||||
<AvaloniaResource Include="Resources/Fonts/*" />
|
<AvaloniaResource Include="Resources/Fonts/*" />
|
||||||
|
<AvaloniaResource Include="Resources/Grammars/*" />
|
||||||
<AvaloniaResource Include="Resources/Images/*" />
|
<AvaloniaResource Include="Resources/Images/*" />
|
||||||
<AvaloniaResource Include="Resources/Images/ExternalToolIcons/*" />
|
<AvaloniaResource Include="Resources/Images/ExternalToolIcons/*" />
|
||||||
<AvaloniaResource Include="Resources/Images/ExternalToolIcons/JetBrains/*" />
|
<AvaloniaResource Include="Resources/Images/ExternalToolIcons/JetBrains/*" />
|
||||||
|
|
|
@ -40,6 +40,9 @@ namespace SourceGit.Views
|
||||||
|
|
||||||
foreach (var line in view.VisualLines)
|
foreach (var line in view.VisualLines)
|
||||||
{
|
{
|
||||||
|
if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted)
|
||||||
|
continue;
|
||||||
|
|
||||||
var lineNumber = line.FirstDocumentLine.LineNumber;
|
var lineNumber = line.FirstDocumentLine.LineNumber;
|
||||||
if (lineNumber > _editor.BlameData.LineInfos.Count)
|
if (lineNumber > _editor.BlameData.LineInfos.Count)
|
||||||
break;
|
break;
|
||||||
|
@ -151,6 +154,9 @@ namespace SourceGit.Views
|
||||||
|
|
||||||
foreach (var line in view.VisualLines)
|
foreach (var line in view.VisualLines)
|
||||||
{
|
{
|
||||||
|
if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted)
|
||||||
|
continue;
|
||||||
|
|
||||||
var lineNumber = line.FirstDocumentLine.LineNumber;
|
var lineNumber = line.FirstDocumentLine.LineNumber;
|
||||||
if (lineNumber >= _editor.BlameData.LineInfos.Count)
|
if (lineNumber >= _editor.BlameData.LineInfos.Count)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -41,8 +41,8 @@ namespace SourceGit.Views
|
||||||
Math.Abs(Height - old.Height) > 0.001 ||
|
Math.Abs(Height - old.Height) > 0.001 ||
|
||||||
StartIdx != old.StartIdx ||
|
StartIdx != old.StartIdx ||
|
||||||
EndIdx != old.EndIdx ||
|
EndIdx != old.EndIdx ||
|
||||||
Combined != Combined ||
|
Combined != old.Combined ||
|
||||||
IsOldSide != IsOldSide;
|
IsOldSide != old.IsOldSide;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +92,9 @@ namespace SourceGit.Views
|
||||||
var typeface = view.CreateTypeface();
|
var typeface = view.CreateTypeface();
|
||||||
foreach (var line in view.VisualLines)
|
foreach (var line in view.VisualLines)
|
||||||
{
|
{
|
||||||
|
if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted)
|
||||||
|
continue;
|
||||||
|
|
||||||
var index = line.FirstDocumentLine.LineNumber;
|
var index = line.FirstDocumentLine.LineNumber;
|
||||||
if (index > lines.Count)
|
if (index > lines.Count)
|
||||||
break;
|
break;
|
||||||
|
@ -160,7 +163,7 @@ namespace SourceGit.Views
|
||||||
var width = textView.Bounds.Width;
|
var width = textView.Bounds.Width;
|
||||||
foreach (var line in textView.VisualLines)
|
foreach (var line in textView.VisualLines)
|
||||||
{
|
{
|
||||||
if (line.FirstDocumentLine == null)
|
if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var index = line.FirstDocumentLine.LineNumber;
|
var index = line.FirstDocumentLine.LineNumber;
|
||||||
|
@ -256,8 +259,6 @@ namespace SourceGit.Views
|
||||||
v.TextRunProperties.SetForegroundBrush(_presenter.IndicatorForeground);
|
v.TextRunProperties.SetForegroundBrush(_presenter.IndicatorForeground);
|
||||||
v.TextRunProperties.SetTypeface(new Typeface(_presenter.FontFamily, FontStyle.Italic));
|
v.TextRunProperties.SetTypeface(new Typeface(_presenter.FontFamily, FontStyle.Italic));
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,7 +422,7 @@ namespace SourceGit.Views
|
||||||
if (chunk == null || (!chunk.Combined && chunk.IsOldSide != IsOld))
|
if (chunk == null || (!chunk.Combined && chunk.IsOldSide != IsOld))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var color = (Color)this.FindResource("SystemAccentColor");
|
var color = (Color)this.FindResource("SystemAccentColor")!;
|
||||||
var brush = new SolidColorBrush(color, 0.1);
|
var brush = new SolidColorBrush(color, 0.1);
|
||||||
var pen = new Pen(color.ToUInt32());
|
var pen = new Pen(color.ToUInt32());
|
||||||
var rect = new Rect(0, chunk.Y, Bounds.Width, chunk.Height);
|
var rect = new Rect(0, chunk.Y, Bounds.Width, chunk.Height);
|
||||||
|
@ -710,12 +711,7 @@ namespace SourceGit.Views
|
||||||
|
|
||||||
var firstLineIdx = view.VisualLines[0].FirstDocumentLine.LineNumber - 1;
|
var firstLineIdx = view.VisualLines[0].FirstDocumentLine.LineNumber - 1;
|
||||||
var lastLineIdx = view.VisualLines[^1].FirstDocumentLine.LineNumber - 1;
|
var lastLineIdx = view.VisualLines[^1].FirstDocumentLine.LineNumber - 1;
|
||||||
if (endIdx < firstLineIdx)
|
if (endIdx < firstLineIdx || startIdx > lastLineIdx)
|
||||||
{
|
|
||||||
TrySetChunk(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (startIdx > lastLineIdx)
|
|
||||||
{
|
{
|
||||||
TrySetChunk(null);
|
TrySetChunk(null);
|
||||||
return;
|
return;
|
||||||
|
@ -746,6 +742,9 @@ namespace SourceGit.Views
|
||||||
var lineIdx = -1;
|
var lineIdx = -1;
|
||||||
foreach (var line in view.VisualLines)
|
foreach (var line in view.VisualLines)
|
||||||
{
|
{
|
||||||
|
if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted)
|
||||||
|
continue;
|
||||||
|
|
||||||
var index = line.FirstDocumentLine.LineNumber;
|
var index = line.FirstDocumentLine.LineNumber;
|
||||||
if (index > diff.Lines.Count)
|
if (index > diff.Lines.Count)
|
||||||
break;
|
break;
|
||||||
|
@ -888,12 +887,7 @@ namespace SourceGit.Views
|
||||||
|
|
||||||
var firstLineIdx = view.VisualLines[0].FirstDocumentLine.LineNumber - 1;
|
var firstLineIdx = view.VisualLines[0].FirstDocumentLine.LineNumber - 1;
|
||||||
var lastLineIdx = view.VisualLines[^1].FirstDocumentLine.LineNumber - 1;
|
var lastLineIdx = view.VisualLines[^1].FirstDocumentLine.LineNumber - 1;
|
||||||
if (endIdx < firstLineIdx)
|
if (endIdx < firstLineIdx || startIdx > lastLineIdx)
|
||||||
{
|
|
||||||
TrySetChunk(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (startIdx > lastLineIdx)
|
|
||||||
{
|
{
|
||||||
TrySetChunk(null);
|
TrySetChunk(null);
|
||||||
return;
|
return;
|
||||||
|
@ -930,6 +924,9 @@ namespace SourceGit.Views
|
||||||
var lineIdx = -1;
|
var lineIdx = -1;
|
||||||
foreach (var line in view.VisualLines)
|
foreach (var line in view.VisualLines)
|
||||||
{
|
{
|
||||||
|
if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted)
|
||||||
|
continue;
|
||||||
|
|
||||||
var index = line.FirstDocumentLine.LineNumber;
|
var index = line.FirstDocumentLine.LineNumber;
|
||||||
if (index > lines.Count)
|
if (index > lines.Count)
|
||||||
break;
|
break;
|
||||||
|
@ -1164,7 +1161,7 @@ namespace SourceGit.Views
|
||||||
SetCurrentValue(SelectedChunkProperty, null);
|
SetCurrentValue(SelectedChunkProperty, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnStageChunk(object sender, RoutedEventArgs e)
|
private void OnStageChunk(object _1, RoutedEventArgs _2)
|
||||||
{
|
{
|
||||||
var chunk = SelectedChunk;
|
var chunk = SelectedChunk;
|
||||||
if (chunk == null)
|
if (chunk == null)
|
||||||
|
@ -1222,7 +1219,7 @@ namespace SourceGit.Views
|
||||||
repo.SetWatcherEnabled(true);
|
repo.SetWatcherEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnUnstageChunk(object sender, RoutedEventArgs e)
|
private void OnUnstageChunk(object _1, RoutedEventArgs _2)
|
||||||
{
|
{
|
||||||
var chunk = SelectedChunk;
|
var chunk = SelectedChunk;
|
||||||
if (chunk == null)
|
if (chunk == null)
|
||||||
|
@ -1276,7 +1273,7 @@ namespace SourceGit.Views
|
||||||
repo.SetWatcherEnabled(true);
|
repo.SetWatcherEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDiscardChunk(object sender, RoutedEventArgs e)
|
private void OnDiscardChunk(object _1, RoutedEventArgs _2)
|
||||||
{
|
{
|
||||||
var chunk = SelectedChunk;
|
var chunk = SelectedChunk;
|
||||||
if (chunk == null)
|
if (chunk == null)
|
||||||
|
|
Loading…
Reference in a new issue