Skip to content

Commit 8eccca8

Browse files
committed
WIP: Fixing bugs - -Filter is not working right
Enhanced the filtering functionality by introducing `_filterErrorView` to display filter-related errors and updated the `ApplyFilter` method to handle `RegexParseException` gracefully. Adjusted `_header` positioning dynamically based on `_filterErrorView` and ensured `ListView` selection defaults to the first item if none is selected. Refactored `ListViewSource_MarkChanged` to handle null `_inputSource` safely. Simplified `StatusBar` creation and improved `filterErrorView` behavior with `Dim.Auto` for dynamic height and error-specific styling. Updated `launchSettings.json` with new configurations (`OCGV -Filter`, `OCGV`, `OCGV -MinUi`) for better debugging flexibility. Cleaned up redundant code, improved null safety, and adjusted `Window` dimensions for `MinUI` mode.
1 parent ab76e4a commit 8eccca8

File tree

2 files changed

+66
-27
lines changed

2 files changed

+66
-27
lines changed

src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Linq;
99
using System.Reflection;
1010
using System.Text;
11+
using System.Text.RegularExpressions;
1112
using Terminal.Gui.App;
1213
using Terminal.Gui.Configuration;
1314
using Terminal.Gui.Drawing;
@@ -27,6 +28,7 @@ internal sealed class ConsoleGui : IDisposable
2728
private bool _cancelled;
2829
private Label? _filterLabel;
2930
private TextField? _filterField;
31+
private View? _filterErrorView;
3032
private Label? _header;
3133
private ListView? _listView;
3234
// _inputSource contains the full set of Input data and tracks any items the user
@@ -119,15 +121,15 @@ void OnWinSubViewLayout(object? sender, EventArgs e)
119121

120122
_header!.Text = GridViewHelpers.GetPaddedString(gridHeaders, _gridViewDetails!.ListViewOffset,
121123
_gridViewDetails.ListViewColumnWidths);
122-
ApplyFilter();
123124
UpdateDisplayStrings(_listViewSource);
125+
ApplyFilter();
124126
}
125127
}
126128

127129
private GridViewDataSource LoadData()
128130
{
129131
var items = new List<GridViewRow>();
130-
if (_applicationData == null)
132+
if (_applicationData == null)
131133
return new GridViewDataSource(items);
132134

133135
for (int i = 0; i < _applicationData.DataTable.Data.Count; i++)
@@ -173,25 +175,57 @@ private void ApplyFilter()
173175
// The ListView is always filled with a (filtered) copy of _inputSource.
174176
// We listen for `MarkChanged` events on this filtered list and apply those changes up to _inputSource.
175177

178+
GridViewRow? selectedItem = null;
179+
176180
if (_listViewSource != null)
177181
{
178-
_listViewSource.MarkChanged -= ListViewSource_MarkChanged;
182+
// Get the item that is currently selected so we can restore selection after re-applying filter
183+
selectedItem = _listViewSource?.GridViewRowList.ElementAtOrDefault(_listView?.SelectedItem ?? 0);
184+
_listViewSource!.MarkChanged -= ListViewSource_MarkChanged;
179185
_listViewSource = null;
180186
}
181187

182188
if (_inputSource is null)
183189
{
184190
_inputSource = LoadData();
185191
}
192+
193+
186194
if (_applicationData != null)
187-
_listViewSource = new GridViewDataSource(GridViewHelpers.FilterData(_inputSource.GridViewRowList, _applicationData.Filter ?? string.Empty));
195+
{
196+
try
197+
{
198+
_listViewSource = new GridViewDataSource(GridViewHelpers.FilterData(_inputSource.GridViewRowList,
199+
_applicationData.Filter ?? string.Empty));
200+
}
201+
catch (RegexParseException ex)
202+
{
203+
_filterErrorView!.Text = ex.Message;
204+
}
205+
}
206+
188207
_listViewSource?.MarkChanged += ListViewSource_MarkChanged;
189208
_listView?.Source = _listViewSource;
209+
210+
// Restore selection - find the previously selected item in the new filtered list
211+
if (selectedItem is not null && _listViewSource != null)
212+
{
213+
int newIndex =
214+
_listViewSource.GridViewRowList.FindIndex(i => i.OriginalIndex == selectedItem.OriginalIndex);
215+
if (newIndex >= 0)
216+
{
217+
_listView!.SelectedItem = newIndex;
218+
}
219+
}
220+
if (_listView?.SelectedItem == -1)
221+
{
222+
_listView!.SelectedItem = 0;
223+
}
190224
}
191225

192226
private void ListViewSource_MarkChanged(object? s, GridViewDataSource.RowMarkedEventArgs a)
193227
{
194-
_inputSource.GridViewRowList[a.Row.OriginalIndex].IsMarked = a.Row.IsMarked;
228+
_inputSource?.GridViewRowList[a.Row.OriginalIndex].IsMarked = a.Row.IsMarked;
195229
}
196230

197231
private static void Accept()
@@ -211,12 +245,6 @@ private Window CreateTopLevelWindow()
211245
var win = new Window
212246
{
213247
Title = _applicationData!.Title ?? "Out-ConsoleGridView",
214-
X = _applicationData.MinUI ? -1 : 0,
215-
Y = _applicationData.MinUI ? -1 : 0,
216-
217-
// By using Dim.Fill(), it will automatically resize without manual intervention
218-
Width = Dim.Fill(_applicationData.MinUI ? -1 : 0),
219-
Height = Dim.Fill(_applicationData.MinUI ? -1 : 1)
220248
};
221249

222250
if (_applicationData.MinUI)
@@ -293,14 +321,12 @@ private void AddStatusBar(Window win, bool visible)
293321
$"{Application.Driver} v{FileVersionInfo.GetVersionInfo(Assembly.GetAssembly(typeof(Application))!.Location).ProductVersion}", null));
294322
}
295323

296-
var statusBar = new StatusBar(shortcuts);
297-
statusBar.Visible = visible;
298-
win.Add(statusBar);
324+
win.Add(new StatusBar(shortcuts));
299325
}
300326

301327
private void CalculateColumnWidths(List<string> gridHeaders)
302328
{
303-
_gridViewDetails.ListViewColumnWidths = new int[gridHeaders.Count];
329+
_gridViewDetails!.ListViewColumnWidths = new int[gridHeaders.Count];
304330
var listViewColumnWidths = _gridViewDetails.ListViewColumnWidths;
305331

306332
for (int i = 0; i < gridHeaders.Count; i++)
@@ -371,33 +397,35 @@ private void AddFilter(Window win)
371397
_filterField.KeyBindings.Remove(Key.A.WithCtrl);
372398
_filterField.KeyBindings.Remove(Key.D.WithCtrl);
373399

374-
var filterErrorLabel = new Label
400+
_filterErrorView = new View
375401
{
376402
Text = string.Empty,
377403
X = Pos.Right(_filterLabel) + 1,
378404
Y = Pos.Top(_filterLabel) + 1,
379-
Width = Dim.Fill() - _filterLabel.Text!.Length
405+
Width = Dim.Fill() - _filterLabel.Text!.Length,
406+
// This enables the height to go 0, and the view to disappear when there is no error
407+
Height = Dim.Auto(DimAutoStyle.Text),
408+
SchemeName = "Error"
380409
};
381410

382411
_filterField.TextChanged += (sender, e) =>
383412
{
384413
string? filterText = _filterField.Text?.ToString();
385414
try
386415
{
387-
filterErrorLabel.Text = " ";
388-
filterErrorLabel.SetNeedsDraw();
389-
_applicationData!.Filter = filterText;
416+
_filterErrorView.Text = string.Empty;
417+
_filterErrorView.SetNeedsDraw();
418+
_applicationData!.Filter = filterText!;
390419
ApplyFilter();
391420

392421
}
393422
catch (Exception ex)
394423
{
395-
filterErrorLabel.Text = ex.Message;
396-
filterErrorLabel.SchemeName = "Error";
424+
_filterErrorView.Text = ex.Message;
397425
}
398426
};
399427

400-
win.Add(_filterLabel, _filterField, filterErrorLabel);
428+
win.Add(_filterLabel, _filterField, _filterErrorView);
401429

402430
_filterField.Text = _applicationData.Filter ?? string.Empty;
403431
_filterField.CursorPosition = _filterField.Text.Length;
@@ -415,7 +443,7 @@ private void AddHeaders(Window win, List<string> gridHeaders)
415443
}
416444
else
417445
{
418-
_header.Y = 2;
446+
_header.Y = Pos.Bottom(_filterErrorView!);
419447
}
420448
win.Add(_header);
421449

@@ -451,8 +479,7 @@ private void AddListView(Window win)
451479
_listView.AllowsMarking = _applicationData.OutputMode != OutputModeOption.None;
452480
_listView.AllowsMultipleSelection = _applicationData.OutputMode == OutputModeOption.Multiple;
453481

454-
// In Terminal.Gui v2, key bindings work differently
455-
// The ListView already handles Space for toggling marks by default
482+
_listView.SelectedItem = 0;
456483

457484
win.Add(_listView);
458485
}

src/Microsoft.PowerShell.ConsoleGuiTools/Properties/launchSettings.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,23 @@
55
"commandLineArgs": "C:\\Program Files\\PowerShell\\7\\pwsh.exe -NoLogo -NoExit -Command \"& { Import-Module '$(TargetPath)'; Get-Process | Out-ConsoleGridView }\"",
66
"workingDirectory": "$(TargetDir)"
77
},
8-
"Debug OCGV": {
8+
"OCGV -Filter": {
9+
"commandName": "Executable",
10+
"executablePath": "C:\\Program Files\\PowerShell\\7-preview\\pwsh.exe",
11+
"commandLineArgs": "-NoProfile -NoLogo -NoExit -Command \"& { Import-Module '$(TargetPath)'; Get-Process | Out-ConsoleGridView -Filter com }\"",
12+
"workingDirectory": "$(TargetDir)"
13+
},
14+
"OCGV": {
915
"commandName": "Executable",
1016
"executablePath": "C:\\Program Files\\PowerShell\\7-preview\\pwsh.exe",
1117
"commandLineArgs": "-NoProfile -NoLogo -NoExit -Command \"& { Import-Module '$(TargetPath)'; Get-Process | Out-ConsoleGridView }\"",
1218
"workingDirectory": "$(TargetDir)"
19+
},
20+
"OCGV -MinUi": {
21+
"commandName": "Executable",
22+
"executablePath": "C:\\Program Files\\PowerShell\\7-preview\\pwsh.exe",
23+
"commandLineArgs": "-NoProfile -NoLogo -NoExit -Command \"& { Import-Module '$(TargetPath)'; Get-Process | Out-ConsoleGridView -MinUi }\"",
24+
"workingDirectory": "$(TargetDir)"
1325
}
1426
}
1527
}

0 commit comments

Comments
 (0)