From 94358d1c9ef39e41a27d6bc24cae95cf7e45e8cc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 26 Feb 2026 11:45:47 +0000 Subject: [PATCH 1/3] Initial plan From b4ce9a53d49bb4b8c86d6fd788e9010a0b391980 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 26 Feb 2026 11:51:17 +0000 Subject: [PATCH 2/3] Fix: auto-select exact match in Select prompt when multiple items share a common prefix Co-authored-by: shibayan <1356444+shibayan@users.noreply.github.com> --- Sharprompt.Tests/PaginatorTests.cs | 41 ++++++++++++++++++++++++++++++ Sharprompt/Internal/Paginator.cs | 13 ++++++++++ 2 files changed, 54 insertions(+) diff --git a/Sharprompt.Tests/PaginatorTests.cs b/Sharprompt.Tests/PaginatorTests.cs index 3d9b8c9..de733d9 100644 --- a/Sharprompt.Tests/PaginatorTests.cs +++ b/Sharprompt.Tests/PaginatorTests.cs @@ -87,4 +87,45 @@ public void SelectedItem_EmptyList() Assert.False(selected); } + + [Fact] + public void SelectedItem_ExactMatch() + { + var items = new[] { "Select", "SelectWithEnum", "MultiSelect", "MultiSelectWithEnum" }; + var paginator = new Paginator(items, items.Length, Optional.Empty, x => x); + + paginator.UpdateFilter("Select"); + + var selected = paginator.TryGetSelectedItem(out var selectedItem); + + Assert.True(selected); + Assert.Equal("Select", selectedItem); + } + + [Fact] + public void SelectedItem_ExactMatch_CaseInsensitive() + { + var items = new[] { "Select", "SelectWithEnum", "MultiSelect", "MultiSelectWithEnum" }; + var paginator = new Paginator(items, items.Length, Optional.Empty, x => x); + + paginator.UpdateFilter("select"); + + var selected = paginator.TryGetSelectedItem(out var selectedItem); + + Assert.True(selected); + Assert.Equal("Select", selectedItem); + } + + [Fact] + public void SelectedItem_NoExactMatch() + { + var items = new[] { "Select", "SelectWithEnum", "MultiSelect", "MultiSelectWithEnum" }; + var paginator = new Paginator(items, items.Length, Optional.Empty, x => x); + + paginator.UpdateFilter("Sel"); + + var selected = paginator.TryGetSelectedItem(out _); + + Assert.False(selected); + } } diff --git a/Sharprompt/Internal/Paginator.cs b/Sharprompt/Internal/Paginator.cs index d94e7c2..2c8f424 100644 --- a/Sharprompt/Internal/Paginator.cs +++ b/Sharprompt/Internal/Paginator.cs @@ -49,6 +49,19 @@ public bool TryGetSelectedItem([NotNullWhen(true)] out T? selectedItem) if (_selectedIndex == -1 || _filteredItems.Length == 0) { + if (!string.IsNullOrEmpty(FilterKeyword)) + { + foreach (var item in _filteredItems) + { + if (_textSelector(item).Equals(FilterKeyword, StringComparison.OrdinalIgnoreCase)) + { + selectedItem = item; + + return true; + } + } + } + selectedItem = default; return false; From 9cc7a30a67446bf9865b2df686353b148b4ada81 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Mar 2026 02:39:01 +0000 Subject: [PATCH 3/3] Resolve merge conflicts by rebasing test additions on top of master's new tests Co-authored-by: shibayan <1356444+shibayan@users.noreply.github.com> --- Sharprompt.Tests/PaginatorTests.cs | 193 +++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) diff --git a/Sharprompt.Tests/PaginatorTests.cs b/Sharprompt.Tests/PaginatorTests.cs index de733d9..87aa7ad 100644 --- a/Sharprompt.Tests/PaginatorTests.cs +++ b/Sharprompt.Tests/PaginatorTests.cs @@ -88,6 +88,199 @@ public void SelectedItem_EmptyList() Assert.False(selected); } + [Fact] + public void PreviousItem() + { + var paginator = new Paginator(Enumerable.Range(0, 20), 5, Optional.Empty, x => x.ToString()); + + paginator.NextItem(); + paginator.NextItem(); + paginator.PreviousItem(); + + var selected = paginator.TryGetSelectedItem(out var selectedItem); + + Assert.True(selected); + Assert.Equal(0, selectedItem); + } + + [Fact] + public void PreviousPage() + { + var paginator = new Paginator(Enumerable.Range(0, 20), 5, Optional.Empty, x => x.ToString()); + + paginator.NextPage(); + paginator.NextPage(); + paginator.PreviousPage(); + + var currentItems = paginator.CurrentItems; + + Assert.Equal(5, currentItems.Length); + Assert.Equal(new[] { 5, 6, 7, 8, 9 }, currentItems.ToArray()); + } + + [Fact] + public void PreviousPage_WrapsAround() + { + var paginator = new Paginator(Enumerable.Range(0, 20), 5, Optional.Empty, x => x.ToString()); + + paginator.PreviousPage(); + + var currentItems = paginator.CurrentItems; + + Assert.Equal(5, currentItems.Length); + Assert.Equal(new[] { 15, 16, 17, 18, 19 }, currentItems.ToArray()); + } + + [Fact] + public void NextPage_WrapsAround() + { + var paginator = new Paginator(Enumerable.Range(0, 20), 5, Optional.Empty, x => x.ToString()); + + paginator.NextPage(); + paginator.NextPage(); + paginator.NextPage(); + paginator.NextPage(); + + var currentItems = paginator.CurrentItems; + + Assert.Equal(5, currentItems.Length); + Assert.Equal(new[] { 0, 1, 2, 3, 4 }, currentItems.ToArray()); + } + + [Fact] + public void PageCount() + { + var paginator = new Paginator(Enumerable.Range(0, 20), 5, Optional.Empty, x => x.ToString()); + + Assert.Equal(4, paginator.PageCount); + } + + [Fact] + public void TotalCount() + { + var paginator = new Paginator(Enumerable.Range(0, 20), 5, Optional.Empty, x => x.ToString()); + + Assert.Equal(20, paginator.TotalCount); + } + + [Fact] + public void TotalCount_WithFilter() + { + var paginator = new Paginator(Enumerable.Range(0, 20), 5, Optional.Empty, x => x.ToString()); + + paginator.UpdateFilter("1"); + + Assert.Equal(11, paginator.TotalCount); + } + + [Fact] + public void FilterKeyword() + { + var paginator = new Paginator(Enumerable.Range(0, 20), 5, Optional.Empty, x => x.ToString()); + + paginator.UpdateFilter("test"); + + Assert.Equal("test", paginator.FilterKeyword); + } + + [Fact] + public void DefaultValue_SetsSelectedItem() + { + var paginator = new Paginator(Enumerable.Range(0, 20), 5, new Optional(7), x => x.ToString()); + + var selected = paginator.TryGetSelectedItem(out var selectedItem); + + Assert.True(selected); + Assert.Equal(7, selectedItem); + Assert.Equal(1, paginator.CurrentPage); + } + + [Fact] + public void LoopingSelection_NextItem_WrapsWithinPage() + { + var paginator = new Paginator(Enumerable.Range(0, 20), 5, Optional.Empty, x => x.ToString()); + paginator.LoopingSelection = true; + + // 6 calls: -1 -> 0 -> 1 -> 2 -> 3 -> 4 -> 0 (wrap) + for (var i = 0; i < 6; i++) + { + paginator.NextItem(); + } + + var selected = paginator.TryGetSelectedItem(out var selectedItem); + + Assert.True(selected); + Assert.Equal(0, selectedItem); + Assert.Equal(0, paginator.CurrentPage); + } + + [Fact] + public void UpdatePageSize() + { + var paginator = new Paginator(Enumerable.Range(0, 20), 5, Optional.Empty, x => x.ToString()); + + paginator.UpdatePageSize(10); + + var currentItems = paginator.CurrentItems; + + Assert.Equal(10, currentItems.Length); + Assert.Equal(new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, currentItems.ToArray()); + } + + [Fact] + public void UpdatePageSize_SameSize_NoChange() + { + var paginator = new Paginator(Enumerable.Range(0, 20), 5, Optional.Empty, x => x.ToString()); + + paginator.NextPage(); + paginator.UpdatePageSize(5); + + Assert.Equal(1, paginator.CurrentPage); + } + + [Fact] + public void GetEnumerator() + { + var paginator = new Paginator(Enumerable.Range(0, 5), 5, Optional.Empty, x => x.ToString()); + + var items = paginator.ToList(); + + Assert.Equal(new[] { 0, 1, 2, 3, 4 }, items); + } + + [Fact] + public void SinglePage_NextPage_NoChange() + { + var paginator = new Paginator(Enumerable.Range(0, 3), 5, Optional.Empty, x => x.ToString()); + + paginator.NextPage(); + + Assert.Equal(0, paginator.CurrentPage); + } + + [Fact] + public void SinglePage_PreviousPage_NoChange() + { + var paginator = new Paginator(Enumerable.Range(0, 3), 5, Optional.Empty, x => x.ToString()); + + paginator.PreviousPage(); + + Assert.Equal(0, paginator.CurrentPage); + } + + [Fact] + public void SingleFilteredItem_AutoSelects() + { + var paginator = new Paginator(Enumerable.Range(0, 20), 5, Optional.Empty, x => x.ToString()); + + paginator.UpdateFilter("19"); + + var selected = paginator.TryGetSelectedItem(out var selectedItem); + + Assert.True(selected); + Assert.Equal(19, selectedItem); + } + [Fact] public void SelectedItem_ExactMatch() {