Implement most features the old app had

This commit is contained in:
Stone_Red
2024-05-06 19:32:38 +02:00
parent 8890a203d3
commit 9322e10913
20 changed files with 479 additions and 80 deletions
+2
View File
@@ -1,5 +1,6 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dialogHostAvalonia="clr-namespace:DialogHostAvalonia;assembly=DialogHost.Avalonia"
xmlns:local="using:ClipCmd"
x:Class="ClipCmd.App"
RequestedThemeVariant="Default">
@@ -16,6 +17,7 @@
<Application.Styles>
<FluentTheme />
<dialogHostAvalonia:DialogHostStyles />
<StyleInclude Source="avares://AvaloniaEdit/Themes/Fluent/AvaloniaEdit.xaml" />
</Application.Styles>
</Application>
+1
View File
@@ -37,6 +37,7 @@ public partial class App : Application
desktop.MainWindow.Closing += (sender, e) =>
{
Settings.SaveSettings();
clipCmdCommandHandler.SaveCommands();
};
clipCmdCommandHandler.Start();
+7
View File
@@ -19,6 +19,7 @@
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="$(AvaloniaVersion)" />
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.0.6" />
<PackageReference Include="DialogHost.Avalonia" Version="0.7.7" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.8.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Scripting.Common" Version="4.8.0" />
@@ -30,4 +31,10 @@
<PackageReference Include="SharpHook" Version="5.3.3" />
<PackageReference Include="Speckle.Material.Icons.Avalonia" Version="1.2.0" />
</ItemGroup>
<ItemGroup>
<Compile Update="Views\InputDialogView.axaml.cs">
<DependentUpon>InputDialogView.axaml</DependentUpon>
</Compile>
</ItemGroup>
</Project>
+4 -1
View File
@@ -1,4 +1,7 @@
// This file is used by Code Analysis to maintain SuppressMessage
using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "<Pending>")]
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.
+2 -2
View File
@@ -1,6 +1,6 @@
namespace ClipCmd.Models;
internal class ClipCmdCommand
public class ClipCmdCommand(string script)
{
public string Script { get; set; } = string.Empty;
public string Script { get; set; } = script;
}
+3 -1
View File
@@ -13,7 +13,7 @@ public class Settings
public bool AutoPaste { get; set; } = true;
public int AutoTypeDelay { get; set; }
public int AutoTypeDelay { get; set; } = 100;
public ClipCmdMode Mode { get; set; }
@@ -21,6 +21,8 @@ public class Settings
public string Suffix { get; set; } = "";
public string CommandArgsSeperator { get; set; } = ":";
public static void SaveSettings()
{
if (!Directory.Exists(Configuration.ApplicationDataPath))
+52 -4
View File
@@ -1,4 +1,5 @@
using Avalonia.Controls;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Input.Platform;
using ClipCmd.Models;
@@ -7,8 +8,12 @@ using SharpHook;
using SharpHook.Native;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Management.Automation;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace ClipCmd.Utilities;
@@ -17,13 +22,15 @@ public class ClipCmdCommandHandler(Window window)
{
private readonly IClipboard clipboard = window.Clipboard!;
private readonly EventSimulator simulator = new EventSimulator();
private readonly ConcurrentDictionary<string, ClipCmdCommand> commands = new();
private string lastText = string.Empty;
public AvaloniaDictionary<string, ClipCmdCommand> Commands { get; } = [];
public void Start()
{
_ = new TaskFactory().StartNew(async () =>
{
LoadCommands();
while (true)
{
await Run();
@@ -32,6 +39,33 @@ public class ClipCmdCommandHandler(Window window)
}, TaskCreationOptions.LongRunning);
}
public void ClearCommands()
{
Commands.Clear();
}
public void SaveCommands()
{
string json = JsonSerializer.Serialize(Commands);
File.WriteAllText(Configuration.CommandsPath, json);
}
public void LoadCommands()
{
if (!File.Exists(Configuration.CommandsPath))
{
return;
}
string json = File.ReadAllText(Configuration.CommandsPath);
Commands.Clear();
foreach (KeyValuePair<string, ClipCmdCommand> command in JsonSerializer.Deserialize<ConcurrentDictionary<string, ClipCmdCommand>>(json) ?? new())
{
Commands[command.Key] = command.Value;
}
}
private async Task Run()
{
string? text = await clipboard.GetTextAsync();
@@ -48,14 +82,18 @@ public class ClipCmdCommandHandler(Window window)
return;
}
string commandName = text[Settings.Current.Prefix.Length..^Settings.Current.Suffix.Length];
string input = text[Settings.Current.Prefix.Length..^Settings.Current.Suffix.Length].Replace(Settings.Current.CommandArgsSeperator + Settings.Current.CommandArgsSeperator, "\0");
string[] parts = input.Split(Settings.Current.CommandArgsSeperator);
string commandName = parts[0].Replace("\0", Settings.Current.CommandArgsSeperator);
string[] parameters = parts.Skip(1).Select(p => p.Replace("\0", Settings.Current.CommandArgsSeperator)).ToArray();
StringBuilder outText = new StringBuilder();
if (commands.TryGetValue(commandName, out ClipCmdCommand? command))
if (Commands.TryGetValue(commandName, out ClipCmdCommand? command))
{
PowerShell powerShell = PowerShell.Create();
_ = powerShell.AddScript(command.Script);
_ = powerShell.AddParameters(parameters);
foreach (PSObject commandResult in await powerShell.InvokeAsync())
{
@@ -66,6 +104,10 @@ public class ClipCmdCommandHandler(Window window)
{
return;
}
else if (commandName == "list")
{
_ = outText.AppendLine($"Commands: {string.Join(", ", Commands.Keys)}");
}
else
{
_ = outText.AppendLine("Command not found!");
@@ -90,6 +132,12 @@ public class ClipCmdCommandHandler(Window window)
{
foreach (char c in outText.ToString().TrimEnd())
{
if (c == '\n')
{
_ = simulator.SimulateKeyPress(KeyCode.VcEnter);
continue;
}
_ = simulator.SimulateTextEntry(c.ToString());
await Task.Delay(Settings.Current.AutoTypeDelay);
}
+2
View File
@@ -21,4 +21,6 @@ internal static class Configuration
public static string SettingsFilePath => Path.Combine(ApplicationDataPath, "settings.json");
public static string LogFilePath => Path.Combine(ApplicationDataPath, $"ClipCMD.log");
public static string CommandsPath => Path.Combine(ApplicationDataPath, "commands.json");
}
@@ -0,0 +1,73 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using ClipCmd.Models;
using ClipCmd.Utilities;
using ClipCmd.Views;
using DialogHostAvalonia;
using ReactiveUI;
using System.Collections.Generic;
using System.Windows.Input;
namespace ClipCmd.ViewModels;
public class ClipCmdCommandItemViewModel(string name, ClipCmdCommandHandler clipCmdCommandHandler)
{
public string Name { get; } = name;
public ICommand RemoveCommand => ReactiveCommand.Create(Remove);
public ICommand RenameCommand => ReactiveCommand.Create(Rename);
public ICommand EditCommand => ReactiveCommand.Create(Edit);
private void Remove()
{
_ = clipCmdCommandHandler.Commands.Remove(Name);
clipCmdCommandHandler.SaveCommands();
}
private async void Rename()
{
string? newName = await DialogHost.Show(new InputDialogViewModel("Edit command name:", Name)) as string;
newName = newName?.Trim();
if (!clipCmdCommandHandler.Commands.Remove(Name, out ClipCmdCommand? clipCmdCommand))
{
return;
}
if (string.IsNullOrWhiteSpace(newName))
{
clipCmdCommandHandler.Commands.Add(Name, clipCmdCommand);
return;
}
int counter = 0;
string originalName = newName;
while (clipCmdCommandHandler.Commands.ContainsKey(newName))
{
newName = $"{originalName} ({++counter})";
}
clipCmdCommandHandler.Commands.Add(newName, clipCmdCommand);
clipCmdCommandHandler.SaveCommands();
}
private async void Edit()
{
Avalonia.Controls.Window? mainWindow = Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop ? desktop.MainWindow : null;
EditorWindow editorWindow = new EditorWindow
{
DataContext = new EditorViewModel(Name, clipCmdCommandHandler)
};
await editorWindow.ShowDialog(mainWindow!);
clipCmdCommandHandler.SaveCommands();
}
}
@@ -0,0 +1,10 @@
using Avalonia.Media;
namespace ClipCmd.ViewModels;
internal class EditorMessageViewModel(string message, IBrush color)
{
public string Message { get; } = message;
public IBrush Color { get; } = color;
}
+35
View File
@@ -0,0 +1,35 @@
using ClipCmd.Utilities;
using System.Collections.ObjectModel;
namespace ClipCmd.ViewModels;
internal class EditorViewModel : ViewModelBase
{
private readonly ClipCmdCommandHandler clipCmdCommandHandler;
public string Title => $"ClipCMD Editor - {Name}";
public string Name { get; }
public string Script
{
get => clipCmdCommandHandler.Commands[Name].Script;
set => clipCmdCommandHandler.Commands[Name].Script = value;
}
public ObservableCollection<EditorMessageViewModel> Messages { get; } = [];
public EditorViewModel(string name, ClipCmdCommandHandler clipCmdCommandHandler)
{
Name = name;
this.clipCmdCommandHandler = clipCmdCommandHandler;
}
// Only used for the designer
public EditorViewModel()
{
Name = "Test";
clipCmdCommandHandler = new ClipCmdCommandHandler(new());
}
}
@@ -0,0 +1,18 @@
using DialogHostAvalonia;
using ReactiveUI;
using System.Windows.Input;
namespace ClipCmd.ViewModels;
internal class InputDialogViewModel(string title, string defaultValue = "") : ViewModelBase
{
public string Title { get; set; } = title;
public string Value { get; set; } = defaultValue;
public ICommand OkCommand => ReactiveCommand.Create(() => DialogHost.GetDialogSession(null)!.Close(Value));
public ICommand CancelCommand => ReactiveCommand.Create(() => DialogHost.GetDialogSession(null)!.Close(null));
}
+67 -3
View File
@@ -1,12 +1,22 @@
using ClipCmd.Models;
using ClipCmd.Utilities;
using DialogHostAvalonia;
using ReactiveUI;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Input;
namespace ClipCmd.ViewModels;
public class MainViewModel : ViewModelBase
{
private readonly ClipCmdCommandHandler clipCmdCommandHandler;
public List<ClipCmdCommandItemViewModel> Commands => [.. clipCmdCommandHandler.Commands.Keys.Select(x => new ClipCmdCommandItemViewModel(x, clipCmdCommandHandler))];
public bool AutoTypeModeEnabled
{
get => Settings.Current.Mode == ClipCmdMode.AutoType;
@@ -31,12 +41,12 @@ public class MainViewModel : ViewModelBase
}
}
public int AutoTypeDelay
public int? AutoTypeDelay
{
get => Settings.Current.AutoTypeDelay;
set
{
Settings.Current.AutoTypeDelay = value;
Settings.Current.AutoTypeDelay = value ?? 1;
this.RaisePropertyChanged();
}
}
@@ -71,11 +81,65 @@ public class MainViewModel : ViewModelBase
}
}
public MainViewModel(ClipCmdCommandHandler clipCmdCommandHandler)
public string CommandArgsSeperator
{
get => Settings.Current.CommandArgsSeperator;
set
{
value = value.Replace(Settings.Current.CommandArgsSeperator, string.Empty);
if (string.IsNullOrWhiteSpace(value))
{
value = Settings.Current.CommandArgsSeperator;
}
if (value.Length > 1)
{
value = value[..1];
}
Settings.Current.CommandArgsSeperator = value;
this.RaisePropertyChanged();
}
}
public ICommand AddCommand => ReactiveCommand.Create(Add);
public MainViewModel(ClipCmdCommandHandler clipCmdCommandHandler)
{
this.clipCmdCommandHandler = clipCmdCommandHandler;
clipCmdCommandHandler.Commands.CollectionChanged += (sender, e) =>
{
this.RaisePropertyChanged(nameof(Commands));
};
}
// Only used for the designer
public MainViewModel()
{
clipCmdCommandHandler = new ClipCmdCommandHandler(new());
}
private async void Add()
{
string? name = await DialogHost.Show(new InputDialogViewModel("Enter command name:")) as string;
name = name?.Trim();
if (string.IsNullOrWhiteSpace(name))
{
return;
}
int counter = 0;
string originalName = name;
while (clipCmdCommandHandler.Commands.ContainsKey(name))
{
name = $"{originalName} ({++counter})";
}
clipCmdCommandHandler.Commands.Add(name, new ClipCmdCommand(@$"Write-Output ""{name} command"""));
clipCmdCommandHandler.SaveCommands();
}
}
+27
View File
@@ -0,0 +1,27 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:ClipCmd.ViewModels"
xmlns:AvaloniaEdit="clr-namespace:AvaloniaEdit;assembly=AvaloniaEdit"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="ClipCmd.Views.EditorWindow"
x:DataType="vm:EditorViewModel"
Title="{Binding Title}"
Width="800" Height="450"
WindowStartupLocation="CenterScreen"
Loaded="Window_Loaded">
<Grid RowDefinitions="3* Auto 1*">
<AvaloniaEdit:TextEditor Name="Editor" ShowLineNumbers="True" FontFamily="Cascadia Code,Consolas,Menlo,Monospace" />
<Separator Grid.Row="1" Margin="0" />
<ScrollViewer Grid.Row="2">
<ItemsControl ItemsSource="{Binding Messages}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Label Content="{Binding Message}" Foreground="{Binding Color}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</Window>
+65
View File
@@ -0,0 +1,65 @@
using Avalonia.Controls;
using Avalonia.Media;
using AvaloniaEdit;
using AvaloniaEdit.TextMate;
using ClipCmd.ViewModels;
using System;
using System.Diagnostics;
using System.Management.Automation.Language;
using TextMateSharp.Grammars;
namespace ClipCmd.Views;
public partial class EditorWindow : Window
{
public EditorWindow()
{
InitializeComponent();
}
private void Window_Loaded(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
EditorViewModel editorViewModel = DataContext as EditorViewModel ?? throw new InvalidOperationException("DataContext is not EditorViewModel");
TextEditor textEditor = this.FindControl<TextEditor>("Editor")!;
textEditor.Text = editorViewModel.Script;
textEditor.TextChanged += (s, e) =>
{
editorViewModel.Script = textEditor.Text;
CheckScript(editorViewModel);
};
RegistryOptions registryOptions = new RegistryOptions(ThemeName.DarkPlus);
TextMate.Installation _textMateInstallation = textEditor.InstallTextMate(registryOptions);
_textMateInstallation.SetGrammar(registryOptions.GetScopeByLanguageId(registryOptions.GetLanguageByExtension(".ps1").Id));
CheckScript(editorViewModel);
}
private void CheckScript(EditorViewModel editorViewModel)
{
_ = Parser.ParseInput(editorViewModel.Script, out _, out ParseError[] parseErrors);
editorViewModel.Messages.Clear();
if (parseErrors.Length > 0)
{
foreach (ParseError parseError in parseErrors)
{
Debug.WriteLine(parseError.Message + " at line " + parseError.Extent.StartLineNumber + " and column " + parseError.Extent.StartColumnNumber);
editorViewModel.Messages.Add(new($"Error: {parseError.Message} at line {parseError.Extent.StartLineNumber} and column {parseError.Extent.StartColumnNumber}", Brushes.Red));
}
}
else
{
editorViewModel.Messages.Add(new("No errors", Brushes.Green));
}
}
}
+26
View File
@@ -0,0 +1,26 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:ClipCmd.ViewModels"
xmlns:i="https://github.com/projektanker/icons.avalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="ClipCmd.Views.InputDialogView"
x:DataType="vm:InputDialogViewModel"
MinWidth="300"
MinHeight="100"
Background="{DynamicResource SemiColorBackground0}">
<UserControl.Styles>
<StyleInclude Source="avares://Semi.Avalonia/Themes/Index.axaml" />
</UserControl.Styles>
<StackPanel Spacing="10">
<Label Content="{Binding Title}" />
<TextBox VerticalContentAlignment="Center" Text="{Binding Value}" />
<StackPanel Spacing="10" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="Ok" Width="80" HorizontalContentAlignment="Center" Command="{Binding OkCommand}" />
<Button Content="Cancel" Width="80" HorizontalContentAlignment="Center" Command="{Binding CancelCommand}" />
</StackPanel>
</StackPanel>
</UserControl>
@@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace ClipCmd.Views;
public partial class InputDialogView : UserControl
{
public InputDialogView()
{
InitializeComponent();
}
}
+44 -5
View File
@@ -5,9 +5,10 @@
xmlns:vm="clr-namespace:ClipCmd.ViewModels"
xmlns:i="https://github.com/projektanker/icons.avalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
xmlns:dialogHost="clr-namespace:DialogHostAvalonia;assembly=DialogHost.Avalonia"
x:Class="ClipCmd.Views.MainView"
x:DataType="vm:MainViewModel"
Loaded="UserControl_Loaded" Background="{DynamicResource SemiColorBackground0}">
Background="{DynamicResource SemiColorBackground0}">
<Design.DataContext>
<!-- This only sets the DataContext for the previewer in an IDE,
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
@@ -18,11 +19,17 @@
<StyleInclude Source="avares://Semi.Avalonia/Themes/Index.axaml" />
</UserControl.Styles>
<Grid RowDefinitions="Auto Auto Auto Auto Auto Auto" ColumnDefinitions="Auto * Auto" Margin="10">
<dialogHost:DialogHost CloseOnClickAway="False" DisableOpeningAnimation="True" Background="{DynamicResource SemiColorBackground0}">
<dialogHost:DialogHost.DialogContent>
<!-- put your dialog content here-->
</dialogHost:DialogHost.DialogContent>
<Grid RowDefinitions="Auto * Auto" VerticalAlignment="Stretch">
<Grid RowDefinitions="Auto Auto Auto *" ColumnDefinitions="Auto * Auto" Margin="10">
<Grid RowDefinitions="Auto * Auto * Auto" VerticalAlignment="Stretch">
<TextBox Grid.Row="0" MaxLength="5" InnerLeftContent="Prefix:" Watermark="none" Text="{Binding Prefix}" />
<TextBox Grid.Row="2" MaxLength="5" InnerLeftContent="Suffix:" Watermark="none" Text="{Binding Suffix}" />
<TextBox Grid.Row="4" MaxLength="2" InnerLeftContent="Args seperator:" Text="{Binding CommandArgsSeperator}" />
</Grid>
<Label Grid.Column="1" Content="ClipCMD" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="30" />
@@ -33,12 +40,12 @@
<CheckBox Grid.Row="1" Grid.Column="2" VerticalAlignment="Center" Content="Auto Paste" IsEnabled="{Binding ClipboardModeEnabled}" IsChecked="{Binding AutoPaste}" />
<Separator Grid.Row="2" Grid.ColumnSpan="3" VerticalAlignment="Center" />
<RadioButton Grid.Row="3" VerticalAlignment="Center" Content="Auto Type" IsChecked="{Binding AutoTypeModeEnabled}" />
<NumericUpDown Grid.Row="3" Grid.Column="2" Increment="1" Minimum="0" Maximum="1000" VerticalAlignment="Center" IsEnabled="{Binding AutoTypeModeEnabled}" Value="{Binding AutoTypeDelay}" />
<NumericUpDown Grid.Row="3" Grid.Column="2" Increment="1" Minimum="1" Maximum="1000" VerticalAlignment="Center" IsEnabled="{Binding AutoTypeModeEnabled}" Value="{Binding AutoTypeDelay, FallbackValue=1, TargetNullValue=1}" />
</Grid>
<Separator Grid.Row="1" Grid.ColumnSpan="3" VerticalAlignment="Center" Margin="0 10" />
<Button Grid.Column="0" Grid.Row="2">
<Button Grid.Column="0" Grid.Row="2" Command="{Binding AddCommand}">
<StackPanel Spacing="4" Orientation="Horizontal">
<i:Icon Value="fa-plus" />
<TextBlock>Add Command</TextBlock>
@@ -60,5 +67,37 @@
</StackPanel>
</Button>
</Grid>
<ScrollViewer Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="3" VerticalScrollBarVisibility="Auto" Margin="0 20 0 0" Theme="{DynamicResource StaticScrollViewer}">
<ItemsControl ItemsSource="{Binding Commands}">
<!--Use a StackPanel to display all the modules-->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Spacing="10" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!--This defines the layout for each item (i.e. each module)-->
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border CornerRadius="3" Background="{DynamicResource SemiColorBackground1}" Padding="10 10">
<Grid ColumnDefinitions="* 45 10 45 10 45">
<Label Content="{Binding Name}" VerticalAlignment="Center" />
<Button Grid.Column="1" Command="{Binding RenameCommand}" HorizontalAlignment="Stretch">
<i:Icon Value="fa-edit" />
</Button>
<Button Grid.Column="3" Command="{Binding EditCommand}" HorizontalAlignment="Stretch">
<i:Icon Value="fa-code" />
</Button>
<Button Grid.Column="5" Command="{Binding RemoveCommand}" HorizontalAlignment="Stretch">
<i:Icon Value="fa-trash" />
</Button>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</dialogHost:DialogHost>
</UserControl>
-36
View File
@@ -1,13 +1,5 @@
using Avalonia.Controls;
using AvaloniaEdit;
using AvaloniaEdit.TextMate;
using System.Diagnostics;
using System.Management.Automation.Language;
using TextMateSharp.Grammars;
namespace ClipCmd.Views;
public partial class MainView : UserControl
@@ -16,32 +8,4 @@ public partial class MainView : UserControl
{
InitializeComponent();
}
private void UserControl_Loaded(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
return;
//First of all you need to have a reference for your TextEditor for it to be used inside AvaloniaEdit.TextMate project.
TextEditor? textEditor = this.FindControl<TextEditor>("TextEditor");
textEditor.TextChanged += (s, e) =>
{
_ = Parser.ParseInput(textEditor.Text, out _, out ParseError[] parseErrors);
if (parseErrors.Length > 0)
{
foreach (ParseError parseError in parseErrors)
{
Debug.WriteLine(parseError.Message + " at line " + parseError.Extent.StartLineNumber + " and column " + parseError.Extent.StartColumnNumber);
}
}
};
RegistryOptions registryOptions = new RegistryOptions(ThemeName.DarkPlus);
//Initial setup of TextMate.
TextMate.Installation _textMateInstallation = textEditor.InstallTextMate(registryOptions);
//Here we are getting the language by the extension and right after that we are initializing grammar with this language.
//And that's all 😀, you are ready to use AvaloniaEdit with syntax highlighting!
_textMateInstallation.SetGrammar(registryOptions.GetScopeByLanguageId(registryOptions.GetLanguageByExtension(".ps1").Id));
}
}
+2
View File
@@ -3,10 +3,12 @@
xmlns:vm="using:ClipCmd.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:dialogHost="clr-namespace:DialogHostAvalonia;assembly=DialogHost.Avalonia"
xmlns:views="clr-namespace:ClipCmd.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="ClipCmd.Views.MainWindow"
Icon="/Assets/avalonia-logo.ico"
Title="ClipCmd" Width="800" Height="450">
<views:MainView />
</Window>