Skip to content

Commit a802f22

Browse files
Sébastien GeiserSébastien Geiser
Sébastien Geiser
authored and
Sébastien Geiser
committed
First steps for intellisense in C# Replace field
1 parent 2c231d6 commit a802f22

39 files changed

+872
-55
lines changed

RegexDialog/FodyWeavers.xsd

+39-4
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,27 @@
7878
</xs:element>
7979
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged32Assemblies" type="xs:string">
8080
<xs:annotation>
81-
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with line breaks.</xs:documentation>
81+
<xs:documentation>Obsolete, use UnmanagedWinX86Assemblies instead</xs:documentation>
82+
</xs:annotation>
83+
</xs:element>
84+
<xs:element minOccurs="0" maxOccurs="1" name="UnmanagedWinX86Assemblies" type="xs:string">
85+
<xs:annotation>
86+
<xs:documentation>A list of unmanaged X86 (32 bit) assembly names to include, delimited with line breaks.</xs:documentation>
8287
</xs:annotation>
8388
</xs:element>
8489
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged64Assemblies" type="xs:string">
8590
<xs:annotation>
86-
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with line breaks.</xs:documentation>
91+
<xs:documentation>Obsolete, use UnmanagedWinX64Assemblies instead.</xs:documentation>
92+
</xs:annotation>
93+
</xs:element>
94+
<xs:element minOccurs="0" maxOccurs="1" name="UnmanagedWinX64Assemblies" type="xs:string">
95+
<xs:annotation>
96+
<xs:documentation>A list of unmanaged X64 (64 bit) assembly names to include, delimited with line breaks.</xs:documentation>
97+
</xs:annotation>
98+
</xs:element>
99+
<xs:element minOccurs="0" maxOccurs="1" name="UnmanagedWinArm64Assemblies" type="xs:string">
100+
<xs:annotation>
101+
<xs:documentation>A list of unmanaged Arm64 (64 bit) assembly names to include, delimited with line breaks.</xs:documentation>
87102
</xs:annotation>
88103
</xs:element>
89104
<xs:element minOccurs="0" maxOccurs="1" name="PreloadOrder" type="xs:string">
@@ -122,6 +137,11 @@
122137
<xs:documentation>As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.</xs:documentation>
123138
</xs:annotation>
124139
</xs:attribute>
140+
<xs:attribute name="DisableEventSubscription" type="xs:boolean">
141+
<xs:annotation>
142+
<xs:documentation>The attach method no longer subscribes to the `AppDomain.AssemblyResolve` (.NET 4.x) and `AssemblyLoadContext.Resolving` (.NET 6.0+) events.</xs:documentation>
143+
</xs:annotation>
144+
</xs:attribute>
125145
<xs:attribute name="LoadAtModuleInit" type="xs:boolean">
126146
<xs:annotation>
127147
<xs:documentation>Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.</xs:documentation>
@@ -154,12 +174,27 @@
154174
</xs:attribute>
155175
<xs:attribute name="Unmanaged32Assemblies" type="xs:string">
156176
<xs:annotation>
157-
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with |.</xs:documentation>
177+
<xs:documentation>Obsolete, use UnmanagedWinX86Assemblies instead</xs:documentation>
178+
</xs:annotation>
179+
</xs:attribute>
180+
<xs:attribute name="UnmanagedWinX86Assemblies" type="xs:string">
181+
<xs:annotation>
182+
<xs:documentation>A list of unmanaged X86 (32 bit) assembly names to include, delimited with |.</xs:documentation>
158183
</xs:annotation>
159184
</xs:attribute>
160185
<xs:attribute name="Unmanaged64Assemblies" type="xs:string">
161186
<xs:annotation>
162-
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with |.</xs:documentation>
187+
<xs:documentation>Obsolete, use UnmanagedWinX64Assemblies instead</xs:documentation>
188+
</xs:annotation>
189+
</xs:attribute>
190+
<xs:attribute name="UnmanagedWinX64Assemblies" type="xs:string">
191+
<xs:annotation>
192+
<xs:documentation>A list of unmanaged X64 (64 bit) assembly names to include, delimited with |.</xs:documentation>
193+
</xs:annotation>
194+
</xs:attribute>
195+
<xs:attribute name="UnmanagedWinArm64Assemblies" type="xs:string">
196+
<xs:annotation>
197+
<xs:documentation>A list of unmanaged Arm64 (64 bit) assembly names to include, delimited with |.</xs:documentation>
163198
</xs:annotation>
164199
</xs:attribute>
165200
<xs:attribute name="PreloadOrder" type="xs:string">
+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
using ICSharpCode.AvalonEdit.CodeCompletion;
2+
using ICSharpCode.AvalonEdit.Document;
3+
using ICSharpCode.AvalonEdit.Editing;
4+
using System;
5+
using System.Diagnostics;
6+
using System.Windows;
7+
using System.Windows.Media;
8+
using System.Windows.Media.Imaging;
9+
10+
namespace RegexDialog.Model
11+
{
12+
public class CompletionData : ICompletionData
13+
{
14+
public string Text { get; set; }
15+
public string Description { get; set; }
16+
public CompletionItemKind Kind { get; set; }
17+
18+
public object Content => Text;
19+
public double Priority => 0;
20+
21+
object ICompletionData.Description => Description;
22+
23+
private ImageSource _image;
24+
public ImageSource Image
25+
{
26+
get
27+
{
28+
if (_image == null)
29+
{
30+
_image = GetImageForKind(Kind);
31+
}
32+
return _image;
33+
}
34+
}
35+
36+
public void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs)
37+
{
38+
textArea.Document.Replace(completionSegment, Text);
39+
}
40+
41+
private ImageSource GetImageForKind(CompletionItemKind kind)
42+
{
43+
try
44+
{
45+
// Construire le chemin de l'image en fonction du type
46+
string imageName = kind.ToString();
47+
string resourcePath = $"/RegexDialog;component/img/{imageName}.png";
48+
49+
// Charger l'image depuis les ressources
50+
var uri = new Uri(resourcePath, UriKind.Relative);
51+
var resourceStream = Application.GetResourceStream(uri);
52+
53+
if (resourceStream != null)
54+
{
55+
// Créer une BitmapImage à partir du flux
56+
var bitmap = new BitmapImage();
57+
bitmap.BeginInit();
58+
bitmap.StreamSource = resourceStream.Stream;
59+
bitmap.CacheOption = BitmapCacheOption.OnLoad; // Charger en mémoire et fermer le flux
60+
bitmap.EndInit();
61+
bitmap.Freeze(); // Pour une utilisation thread-safe
62+
63+
return bitmap;
64+
}
65+
66+
// Si l'image spécifique n'est pas trouvée, essayer de charger une image par défaut
67+
if (kind != CompletionItemKind.Other)
68+
{
69+
return GetImageForKind(CompletionItemKind.Other);
70+
}
71+
72+
return null;
73+
}
74+
catch (Exception ex)
75+
{
76+
Debug.WriteLine($"Error loading image for {kind}: {ex.Message}");
77+
return null;
78+
}
79+
}
80+
}
81+
82+
public enum CompletionItemKind
83+
{
84+
Class,
85+
Method,
86+
Extension,
87+
Property,
88+
Field,
89+
Event,
90+
Interface,
91+
Enum,
92+
EnumMember,
93+
Keyword,
94+
Namespace,
95+
Variable,
96+
Constant,
97+
Struct,
98+
Other
99+
}
100+
}

RegexDialog/RegExToolDialog.xaml

+9-8
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
SizeChanged="Root_SizeChanged"
1717
LocationChanged="Root_LocationChanged"
1818
DataContext="{x:Static local:Config.Instance}"
19-
local:WindowHelper.CloseOnKey="Esc"
2019
x:Name="Root">
2120
<Window.Resources>
2221
<BitmapImage x:Key="NewPicture" UriSource="Resources/page_white.png" />
@@ -80,7 +79,7 @@
8079
<DockPanel Background="WhiteSmoke" >
8180
<Menu DockPanel.Dock="Top" BorderBrush="Silver" BorderThickness="0,0,0,1">
8281
<MenuItem Header="_File" >
83-
<MenuItem Header="_New" Click="New_MenuItem_Click" >
82+
<MenuItem Header="_New" Click="New_MenuItem_Click" InputGestureText="Ctrl+N" >
8483
<MenuItem.Icon>
8584
<Image Source="{StaticResource NewPicture}" />
8685
</MenuItem.Icon>
@@ -103,19 +102,19 @@
103102
</MenuItem.Icon>
104103
</MenuItem>
105104
<Separator />-->
106-
<MenuItem Header="_Exit" Click="Exit_MenuItem_Click" >
105+
<MenuItem Header="_Exit" Click="Exit_MenuItem_Click" InputGestureText="Ctrl+F4" >
107106
<MenuItem.Icon>
108107
<Image Source="{StaticResource ExitPicture}" />
109108
</MenuItem.Icon>
110109
</MenuItem>
111110
</MenuItem>
112111
<MenuItem Header="_Actions" >
113-
<MenuItem Header="_Is Match ?" Click="IsMatchButton_Click" InputGestureText="Ctrl+Space">
112+
<MenuItem Header="_Is Match ?" Click="IsMatchButton_Click" InputGestureText="Ctrl+Enter">
114113
<MenuItem.Icon>
115114
<Image Source="{StaticResource IsMatchPicture}" Width="16" Height="16" />
116115
</MenuItem.Icon>
117116
</MenuItem>
118-
<MenuItem Header="_Matches" Click="ShowMatchesButton_Click" InputGestureText="Ctrl+Enter">
117+
<MenuItem Header="_Matches" Click="ShowMatchesButton_Click" InputGestureText="Ctrl+Shift+Enter">
119118
<MenuItem.Icon>
120119
<Image Source="{StaticResource MatchPicture}" Width="16" Height="16" />
121120
</MenuItem.Icon>
@@ -191,12 +190,12 @@
191190
<Style BasedOn="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" TargetType="Button" />
192191
<Style BasedOn="{StaticResource {x:Static ToolBar.ToggleButtonStyleKey}}" TargetType="ToggleButton" />
193192
</WrapPanel.Resources>
194-
<Button x:Name="IsMatchButton" Click="IsMatchButton_Click" ToolTip="Is Match ? [Ctrl+Space]" >
193+
<Button x:Name="IsMatchButton" Click="IsMatchButton_Click" ToolTip="Is Match ? [Ctrl+Enter]" >
195194
<StackPanel Orientation="Horizontal">
196195
<Image Source="{StaticResource IsMatchPicture}" Width="16" Height="16" />
197196
</StackPanel>
198197
</Button>
199-
<Button x:Name="ShowMatchesButton" Click="ShowMatchesButton_Click" ToolTip="Matches [Ctrl+Enter]">
198+
<Button x:Name="ShowMatchesButton" Click="ShowMatchesButton_Click" ToolTip="Matches [Ctrl+Shift+Enter]">
200199
<StackPanel Orientation="Horizontal">
201200
<Image Source="{StaticResource MatchPicture}"
202201
Width="16"
@@ -425,7 +424,9 @@
425424
FontSize="12"
426425
ScrollViewer.HorizontalScrollBarVisibility="Auto"
427426
Margin="-1,-1,1,1"
428-
ShowLineNumbers="{Binding ShowLinesNumbersReplaceEditorOption}">
427+
ShowLineNumbers="{Binding ShowLinesNumbersReplaceEditorOption}"
428+
behaviors:RoslynCompletionBehaviorExtension.EnableCompletion="{Binding IsChecked ,ElementName=CSharpReplaceCheckbox}"
429+
behaviors:RoslynCompletionBehaviorExtension.TemplateCode="{Binding Source={x:Static local:Res.CSharpReplaceAutoCompleteTemplate}}" >
429430
<i:Interaction.Behaviors>
430431
<behaviors:SimplePropertyBindingBehavior PropertyName="Text" Value="{Binding ReplaceEditorText}" PropertyChangedTriggerEventName="TextChanged" />
431432
<behaviors:SimplePropertyBindingBehavior PropertyName="Options.ShowSpaces" Value="{Binding ShowSpaceCharsReplaceEditorOption}" />

RegexDialog/RegExToolDialog.xaml.cs

+41-19
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
using ClosedXML.Excel;
22
using CSScriptLibrary;
3+
using ICSharpCode.AvalonEdit;
4+
using ICSharpCode.AvalonEdit.Editing;
35
using ICSharpCode.AvalonEdit.Highlighting;
46
using ICSharpCode.AvalonEdit.Highlighting.Xshd;
57
using Microsoft.Win32;
68
using Newtonsoft.Json;
79
using Ookii.Dialogs.Wpf;
10+
using RegexDialog.Behaviors;
811
using System;
912
using System.Collections.Generic;
1013
using System.Collections.ObjectModel;
@@ -69,7 +72,7 @@ private string InjectInReplaceScript(string replaceScript)
6972
{
7073
Match beforeMatch = cSharpReplaceBeforePartRegex.Match(ReplaceEditor.Text);
7174
Match afterMatch = cSharpReplaceAfterPartRegex.Match(ReplaceEditor.Text);
72-
75+
7376
return replaceScript
7477
.Replace("//usings", cSharpReplaceUsingsPartRegex.Match(ReplaceEditor.Text).Groups["usings"].Value.Trim())
7578
.Replace("//global", cSharpReplaceGlobalPartRegex.Match(ReplaceEditor.Text).Groups["global"].Value)
@@ -233,7 +236,7 @@ public RegExToolDialog()
233236
private string ConvertToInputGestureText(KeyPressedEventArgs e) =>
234237
$"{(e.Control ? "Ctrl+" : "")}{(e.Alt ? "Alt+" : "")}{(e.Shift ? "Shift+" : "")}{e.Key}";
235238

236-
private Dictionary<string, RoutedUICommand> hotkeyToCommand = new()
239+
private readonly Dictionary<string, RoutedUICommand> hotkeyToCommand = new()
237240
{
238241
["Ctrl+X"] = ApplicationCommands.Cut,
239242
["Ctrl+C"] = ApplicationCommands.Copy,
@@ -251,24 +254,23 @@ private void DelayAction(Action action, int milliseconds = 10)
251254
});
252255
}
253256

254-
private void KeyboardHookManager_KeyPressed(object sender, KeyPressedEventArgs e)
257+
private async void KeyboardHookManager_KeyPressed(object sender, KeyPressedEventArgs e)
255258
{
256-
if(hotkeyToAction == null)
259+
hotkeyToAction ??= new()
257260
{
258-
hotkeyToAction = new()
259-
{
260-
[$"Ctrl+{Key.Enter}"] = ShowMatches,
261-
[$"Ctrl+{Key.Space}"] = IsMatch,
262-
["Ctrl+O"] = OpenRegex,
263-
["Ctrl+S"] = SaveAs,
264-
["Ctrl+Shift+S"] = SelectAllMatches,
265-
["Ctrl+E"] = ExtractAll,
266-
["Ctrl+Shift+E"] = ExtractAll,
267-
["Ctrl+R"] = ReplaceAll,
268-
["Ctrl+Shift+R"] = ReplaceAll,
269-
["Ctrl+Shift+C"] = ShowInCSharp
270-
};
271-
}
261+
[$"Ctrl+{Key.Enter}"] = IsMatch,
262+
[$"Ctrl+Shift+{Key.Enter}"] = ShowMatches,
263+
["Ctrl+N"] = NewRegex,
264+
["Ctrl+O"] = OpenRegex,
265+
["Ctrl+S"] = SaveAs,
266+
["Ctrl+Shift+S"] = SelectAllMatches,
267+
["Ctrl+E"] = ExtractAll,
268+
["Ctrl+Shift+E"] = ExtractAll,
269+
["Ctrl+R"] = ReplaceAll,
270+
["Ctrl+Shift+R"] = ReplaceAll,
271+
["Ctrl+Shift+C"] = ShowInCSharp,
272+
["Ctrl+F4"] = Close
273+
};
272274

273275
try
274276
{
@@ -288,7 +290,22 @@ private void KeyboardHookManager_KeyPressed(object sender, KeyPressedEventArgs e
288290
{
289291
e.Handled = true;
290292
DelayAction(hotkeyToAction[hotkey]);
291-
}
293+
}
294+
else if(hotkey.Equals("Ctrl+Space") && Keyboard.FocusedElement is TextArea textArea)
295+
{
296+
var editor = textArea.FindVisualParent<TextEditor>();
297+
298+
RoslynCompletionBehavior behavior = RoslynCompletionBehaviorExtension.GetBehaviorForEditor(editor);
299+
300+
if (behavior != null)
301+
{
302+
e.Handled = true;
303+
Dispatcher.Invoke(() =>
304+
{
305+
behavior?.ShowCompletionWindowAsync().RunSynchronously();
306+
});
307+
}
308+
}
292309
}
293310
catch { }
294311
}
@@ -1995,6 +2012,11 @@ private void PutInReplaceHistory_Click(object sender, RoutedEventArgs e)
19952012
}
19962013

19972014
private void New_MenuItem_Click(object sender, RoutedEventArgs e)
2015+
{
2016+
NewRegex();
2017+
}
2018+
2019+
public void NewRegex()
19982020
{
19992021
try
20002022
{

0 commit comments

Comments
 (0)