syntact highlighting

main
Paul Schneider 10 months ago
parent 3ced6adbd4
commit e253fc562d
9 changed files with 157 additions and 16 deletions

@ -5,7 +5,7 @@
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (console)",
"name": ".NET Core Launch red sample",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",

@ -4,6 +4,7 @@ using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using Irony.Ast;
using Irony.Interpreter.Ast;
using Irony.Parsing;
@ -12,6 +13,8 @@ namespace irules.core
[Language("IRule", "0.1", "Clauses grammar.")]
public class ClauseGrammar : Grammar
{
private readonly IdOptions idoptions;
public ClauseGrammar()
{
var comment = new CommentTerminal("comment", "#", "\n");
@ -23,11 +26,12 @@ namespace irules.core
NonTerminal idOrRelation = new NonTerminal("idOrRelation");
NonTerminal SOrOr = new NonTerminal("SOrOr");
IdentifierTerminal id = new IdentifierTerminal("Id");
var orExpr = new NonTerminal("OrExpr", typeof(BinaryOperationNode));
var andExpr = new NonTerminal("AndExpr", typeof(BinaryOperationNode));
var neg = new NonTerminal("Negation", typeof(UnaryOperationNode))
{
Rule = "^" + andExpr + ReduceHere()
Rule = "^" + singleByOr + ReduceHere()
};
expr.Rule = "(" + expr + ")" | SOrOr ;
SOrOr.Rule = orExpr | singleByOr;
@ -40,6 +44,7 @@ namespace irules.core
RegisterBracePair("(", ")");
RegisterOperators(30, "&|^");
Root = expr;
}
}
}

@ -1,3 +1,4 @@
using System.Runtime.InteropServices;
using Irony.Interpreter;
using Irony.Parsing;
@ -5,6 +6,10 @@ namespace irules.core
{
public class ClauseChecker
{
public TokenList LastScriptTokens => app.LastScript?.Tokens;
public ParseTree LatestParsedTree { get; private set; }
ScriptApp app;
public ClauseChecker()
{
@ -14,9 +19,11 @@ namespace irules.core
app = new ScriptApp(r);
}
public virtual AppStatus Parse(string problem)
{
app.Evaluate(problem);
LatestParsedTree = app.Parser.Parse(problem);
try {
switch (app.Status)
{

@ -27,7 +27,7 @@ public partial class App : Application
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow();
desktop.MainWindow = new MainWindow(checker);
}
base.OnFrameworkInitializationCompleted();

@ -0,0 +1,13 @@
using AvaloniaEdit.Document;
using AvaloniaEdit.Rendering;
namespace red
{
internal class IronyGrammarTransformer : DocumentColorizingTransformer
{
protected override void ColorizeLine(DocumentLine line)
{
throw new System.NotImplementedException();
}
}
}

@ -12,14 +12,16 @@
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
<MenuItem Header="_Open ..." Click="OnOpen"/>
<MenuItem Header="_Save" Click="OnSave"/>
<MenuItem Header="Save _To ..." Click="OnSaveTo"/>
<Separator />
<MenuItem Header="_Exit" Click="OnExit"/>
</MenuItem>
<MenuItem Header="_Edit">
<MenuItem Header="Copy" />
<MenuItem Header="Paste" />
<MenuItem Header="Copy" HotKey="Ctrl+C" />
<MenuItem Header="Paste" HotKey="Ctrl+V"/>
</MenuItem>
<MenuItem Header="_Run">
<MenuItem Header="_Run" Click="OnRun">
</MenuItem>
</Menu>
<StackPanel DockPanel.Dock="Bottom">

@ -1,32 +1,128 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Platform.Storage;
using Avalonia.Rendering;
using Avalonia.Threading;
using Avalonia.VisualTree;
using AvaloniaEdit;
using AvaloniaEdit.Highlighting;
using AvaloniaEdit.Rendering;
using Irony.Interpreter;
using Irony.Parsing;
using irules.core;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Avalonia.Media;
namespace red;
public partial class MainWindow : Window
{
public MainWindow()
ClauseChecker checker;
public MainWindow(ClauseChecker checker)
{
this.checker = checker;
InitializeComponent();
SetupTheme();
src.Text = "Hello !";
src.TextChanged += OnTextChanged;
src.TextArea.TextView.VisualLinesChanged += TextView_VisualLinesChanged;
}
private void TextView_VisualLinesChanged(object sender, EventArgs e)
{
//throw new NotImplementedException();
}
private void SetupTheme()
{
HighlightingColor keywork = new HighlightingColor
{ Foreground = new SimpleHighlightingBrush(Color.FromRgb(255,155,50)) };
HighlightingColor comment = new HighlightingColor
{ FontStyle = Avalonia.Media.FontStyle.Italic,
Foreground = new SimpleHighlightingBrush(Color.FromRgb(150,150,150)) };
HighlightingColor identifier = new HighlightingColor
{ Foreground = new SimpleHighlightingBrush(Color.FromRgb(255,195,255)) };
ColorTheme = new Dictionary<TokenColor, HighlightingColor>
{
{ TokenColor.Text, keywork},
{ TokenColor.Keyword, keywork},
{ TokenColor.Comment, comment},
{ TokenColor.Identifier, identifier},
{ TokenColor.String, comment},
{ TokenColor.Number, identifier}
};
}
Dictionary<TokenColor, HighlightingColor> ColorTheme;
private void OnTextChanged(object sender, EventArgs e)
{
var appstatus = checker.Parse(src.Text);
statusMessage.Text = "Parsing :" +
appstatus.ToString();
switch (appstatus)
{
case AppStatus.Ready:
case AppStatus.SyntaxError:
case AppStatus.WaitingMoreInput:
src.TextArea.TextView.LineTransformers.Clear();
RichTextModel model = new RichTextModel();
checker.LatestParsedTree.Tokens?.ForEach (
token =>
{
switch(token.Category)
{
case TokenCategory.Error:
case TokenCategory.Directive:
case TokenCategory.Content:
case TokenCategory.Comment:
// token.Location.Line
model.ApplyHighlighting(token.Location.Position, token.Length,
ColorTheme[token.EditorInfo.Color]);
break;
}
});
transformer = new RichTextColorizer(model);
src.TextArea.TextView.LineTransformers.Add(transformer);
break;
}
}
public void OnExit(object sender, RoutedEventArgs e)
{
Close();
}
string sourceFileName=null;
private ITextRunConstructionContext context;
private RichTextColorizer transformer;
private ITextRunConstructionContext transformerContext;
public void OnOpen(object sender, RoutedEventArgs e)
{
Task.Run(async () =>
{
FilePickerOpenOptions options = new FilePickerOpenOptions
{
AllowMultiple = true,
Title = "Red"
AllowMultiple = false,
Title = "Open a red file"
};
options.FileTypeFilter = new FilePickerFileType[]
{ new("red"){ Patterns = new string[] { "*.red" } } };
@ -35,11 +131,27 @@ public partial class MainWindow : Window
if (result != null)
{
foreach (var item in result)
var item = result.First();
sourceFileName =
item.Path.AbsolutePath;
Dispatcher.UIThread.Post(() => src.Text = File.ReadAllText(sourceFileName));
System.Diagnostics.Debug.WriteLine($"Opened: {sourceFileName}");
}
});
}
public void OnSave(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine($"Opened: {item.Path}");
if (sourceFileName==null) OnSaveTo(sender, e);
File.WriteAllText(sourceFileName, src.Text);
}
public void OnSaveTo(object sender, RoutedEventArgs e)
{
throw new NotImplementedException();
}
});
public void OnRun(object sender, RoutedEventArgs e)
{
}
}

@ -21,6 +21,7 @@
<ItemGroup>
<PackageReference Include="Avalonia" Version="11.0.5" />
<PackageReference Include="Avalonia.Diagnostics" Version="11.0.5" />
<PackageReference Include="Avalonia.Desktop" Version="11.0.5" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.5" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.0.5" />
@ -29,7 +30,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia.AvaloniaEdit" Version="11.0.5" />
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.0.5" />
<ProjectReference Include="../../irules.core/irules.core.csproj" />

Loading…