Skip to content

Commit

Permalink
Displays the details of the Match object returned by the Regex call.… (
Browse files Browse the repository at this point in the history
…#627)

* Displays the details of the Match object  returned by the Regex call.  Handles much of Issues 76 & 481.

* Show Replacement text

* Redesigned details output

* Removed Replacement panel, cleaned up UI.

* Addressed feedback

Co-authored-by: Etienne BAUDOUX <ebaudoux@velersoftware.com>
  • Loading branch information
jamescurran and veler authored Sep 18, 2022
1 parent 6330b70 commit 20befa6
Show file tree
Hide file tree
Showing 8 changed files with 261 additions and 102 deletions.
2 changes: 1 addition & 1 deletion src/dev/DevToys.Startup/Package.appxmanifest
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<Identity
Name="DevToysPreview"
Publisher="CN=etiennebaudoux"
Version="0.0.0.0" />
Version="1.0.9.0" />

<Properties>
<DisplayName>DevToys - Preview</DisplayName>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ internal void Update(IEnumerable<T> newItems)
foreach (T? item in newItems)
{
int indexOfItemInOldMenu = IndexOf(item);
if (indexOfItemInOldMenu > -1)
if (indexOfItemInOldMenu > -1 && insertionIndex < Count)
{
if (indexOfItemInOldMenu != insertionIndex)
{
Expand Down
10 changes: 10 additions & 0 deletions src/dev/impl/DevToys/LanguageManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2417,6 +2417,16 @@ public class RegExStrings : ObservableObject
/// Gets the resource SearchKeywords.
/// </summary>
public string SearchKeywords => _resources.GetString("SearchKeywords");

/// <summary>
/// Gets the resource InputTitle.
/// </summary>
public string InputTitle => _resources.GetString("InputTitle");

/// <summary>
/// Gets the resource OutputTitle.
/// </summary>
public string OutputTitle => _resources.GetString("OutputTitle");
}

public class SearchResultStrings : ObservableObject
Expand Down
6 changes: 6 additions & 0 deletions src/dev/impl/DevToys/Strings/en-US/RegEx.resw
Original file line number Diff line number Diff line change
Expand Up @@ -186,4 +186,10 @@
<data name="SearchKeywords" xml:space="preserve">
<value>Regular expression</value>
</data>
<data name="InputTitle" xml:space="preserve">
<value>Input</value>
</data>
<data name="OutputTitle" xml:space="preserve">
<value>Output</value>
</data>
</root>
49 changes: 33 additions & 16 deletions src/dev/impl/DevToys/UI/Controls/CustomTextBox.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using DevToys.Core;
using DevToys.Core.Settings;
using DevToys.Core.Threading;
using DevToys.MonacoEditor.Monaco;
using Microsoft.Toolkit.Mvvm.Input;
using Windows.ApplicationModel.DataTransfer;
using Windows.Storage;
Expand All @@ -16,6 +17,7 @@
using Windows.UI.Text;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Documents;
using Windows.UI.Xaml.Media;
using Clipboard = Windows.ApplicationModel.DataTransfer.Clipboard;

Expand Down Expand Up @@ -315,9 +317,6 @@ private void ExecuteSelectAllCommand()

public void SetHighlights(IEnumerable<HighlightSpan>? spans)
{
IEnumerable<HighlightSpan>? highlightsToRemove = _highlightedSpans?.Except(spans ?? Array.Empty<HighlightSpan>());
IEnumerable<HighlightSpan>? highlightsToAdd = spans?.Except(_highlightedSpans ?? Array.Empty<HighlightSpan>());

_highlightedSpans = spans;

if (!IsRichTextEdit)
Expand All @@ -328,31 +327,49 @@ public void SetHighlights(IEnumerable<HighlightSpan>? spans)
RichEditBox? richEditBox = GetRichEditBox();
richEditBox.TextDocument.BatchDisplayUpdates();

if (highlightsToRemove is not null)
if (spans is not null && spans.Any())
{
foreach (HighlightSpan span in highlightsToRemove)
HighlightSpan[] spansArray = spans.ToArray();
int clearFormattingStartIndex = 0;
for (int i = 0; i < spansArray.Length; i++)
{
HighlightSpan span = spansArray[i];
ITextRange range
= richEditBox.TextDocument.GetRange(
span.StartIndex,
span.StartIndex + span.Length);
range.CharacterFormat.BackgroundColor = Colors.Transparent;
range.CharacterFormat.ForegroundColor = ActualTheme == ElementTheme.Dark ? Colors.White : Colors.Black;
range.CharacterFormat.BackgroundColor = span.BackgroundColor;
range.CharacterFormat.ForegroundColor = span.ForegroundColor;

if (span.StartIndex - clearFormattingStartIndex > 0)
{
range
= richEditBox.TextDocument.GetRange(
clearFormattingStartIndex,
span.StartIndex);
range.CharacterFormat.BackgroundColor = Colors.Transparent;
range.CharacterFormat.ForegroundColor = ActualTheme == ElementTheme.Dark ? Colors.White : Colors.Black;
}

clearFormattingStartIndex = span.StartIndex + span.Length;
}
}

if (highlightsToAdd is not null)
{
foreach (HighlightSpan span in highlightsToAdd)
if (Text.Length - clearFormattingStartIndex > 0)
{
ITextRange range
= richEditBox.TextDocument.GetRange(
span.StartIndex,
span.StartIndex + span.Length);
range.CharacterFormat.BackgroundColor = span.BackgroundColor;
range.CharacterFormat.ForegroundColor = span.ForegroundColor;
= richEditBox.TextDocument.GetRange(
clearFormattingStartIndex,
Text.Length);
range.CharacterFormat.BackgroundColor = Colors.Transparent;
range.CharacterFormat.ForegroundColor = ActualTheme == ElementTheme.Dark ? Colors.White : Colors.Black;
}
}
else
{
ITextRange range = richEditBox.TextDocument.GetRange(0, Text.Length);
range.CharacterFormat.BackgroundColor = Colors.Transparent;
range.CharacterFormat.ForegroundColor = ActualTheme == ElementTheme.Dark ? Colors.White : Colors.Black;
}

richEditBox.TextDocument.ApplyDisplayUpdates();
}
Expand Down
136 changes: 109 additions & 27 deletions src/dev/impl/DevToys/ViewModels/Tools/Text/RegEx/RegExToolViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
using System;
using System.Collections.Generic;
using System.Composition;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using DevToys.Api.Core;
using DevToys.Api.Core.Settings;
using DevToys.Api.Tools;
using DevToys.Core.Collections;
using DevToys.Core.Threading;
using DevToys.Shared.Core.Threading;
using DevToys.UI.Controls;
Expand Down Expand Up @@ -196,6 +198,40 @@ internal string? Text
}
}

private string? _errorMsg;
internal string? ErrorMsg
{
get => _errorMsg;
set
{
SetProperty(ref _errorMsg, value);
}
}

internal ExtendedObservableCollection<MatchDetails2> MatchGroups { get; } = new();

private string? _inputValue;
internal string? InputValue
{
get => _inputValue;
set
{
SetProperty(ref _inputValue, value);
QueueRegExMatch();
}
}

private string? _outputValue;
internal string? OutputValue
{
get => _outputValue;
set
{
SetProperty(ref _outputValue, value);
QueueRegExMatch();
}
}

internal ICustomTextBox? MatchTextBox { private get; set; }

[ImportingConstructor]
Expand Down Expand Up @@ -225,52 +261,86 @@ private async Task TreatQueueAsync()
await ThreadHelper.RunOnUIThreadAsync(() =>
{
ElementTheme currentTheme = ((Frame)Window.Current.Content).ActualTheme;
string? highlighterBackgroundResourceName = currentTheme == ElementTheme.Light ? "SystemAccentColorLight2" : "SystemAccentColorDark1";
string? highlighterBackgroundResourceName = currentTheme == ElementTheme.Light
? "SystemAccentColorLight2"
: "SystemAccentColorDark1";
highlighterForegroundColor = currentTheme == ElementTheme.Light ? Colors.Black : Colors.White;
highlighterBackgroundColor = (Color)Application.Current.Resources[highlighterBackgroundResourceName];
});

await TaskScheduler.Default;

string errorMsg = "";
while (_regExMatchingQueue.TryDequeue(out (string pattern, string text) data))
{
var spans = new List<HighlightSpan>();

try
MatchCollection? matches = null;
Regex? regex = null;
if (!String.IsNullOrWhiteSpace(data.pattern))
{
string? pattern = data.pattern.Trim('/');

var regex = new Regex(data.pattern, GetOptions());
MatchCollection matches = regex.Matches(data.text);

foreach (Match match in matches)
try
{
int lineCount = CountLines(data.text, match.Index);
spans.Add(
new HighlightSpan()
{
StartIndex = match.Index - lineCount,
Length = match.Length,
BackgroundColor = highlighterBackgroundColor,
ForegroundColor = highlighterForegroundColor
});
string? pattern = data.pattern.Trim('/');
regex = new Regex(data.pattern, GetOptions());
matches = regex.Matches(data.text);
foreach (Match match in matches)
{
int lineCount = CountLines(data.text, match.Index);
spans.Add(
new HighlightSpan()
{
StartIndex = match.Index - lineCount,
Length = match.Length,
BackgroundColor = highlighterBackgroundColor,
ForegroundColor = highlighterForegroundColor
});
}
}
catch (Exception ex)
{
errorMsg = ex.Message;
// TODO: indicate the user that the regex is wrong.
}
}
catch
{
// TODO: indicate the user that the regex is wrong.
}

ThreadHelper.RunOnUIThreadAsync(
ThreadPriority.Low,
() =>
{
MatchTextBox?.SetHighlights(spans);
ErrorMsg = errorMsg;
if (matches != null)
{
MatchTextBox?.SetHighlights(spans);

IEnumerable<MatchDetails2> matchesGroups
= matches
.Cast<Match>()
.SelectMany(
(c, inx) => c.Groups
.Cast<Group>()
.OrderBy(g => g.Index)
.Select(mm => new MatchDetails2
{
Title = (mm.Name == "0" ? $"Match {inx + 1}:" : $" Group \"{mm.Name}\""),
Range = $"{mm.Index}-{mm.Index + mm.Length}",
Value = mm.Value
}));
MatchGroups.Update(matchesGroups);

if (InputValue != null)
{
OutputValue = regex?.Replace(data.text, InputValue);
}

if (spans.Count > 0 && !_toolSuccessfullyWorked)
if (spans.Count > 0 && !_toolSuccessfullyWorked)
{
_toolSuccessfullyWorked = true;
_marketingService.NotifyToolSuccessfullyWorked();
}
}
else
{
_toolSuccessfullyWorked = true;
_marketingService.NotifyToolSuccessfullyWorked();
MatchGroups.Clear();
MatchTextBox?.SetHighlights(null);
}
}).ForgetSafely();
}
Expand Down Expand Up @@ -315,6 +385,11 @@ private RegexOptions GetOptions()

private int CountLines(string input, int maxLength)
{
if (string.IsNullOrEmpty(input))
{
return 0;
}

int lines = 0;
int i = 0;
while (i > -1 && i < maxLength)
Expand All @@ -330,4 +405,11 @@ private int CountLines(string input, int maxLength)
return lines;
}
}

public record MatchDetails2
{
public string Title { get; set; }
public string Range { get; set; }
public string Value { get; set; }
}
}
Loading

0 comments on commit 20befa6

Please sign in to comment.