Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Sharprompt.Example/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Text;
using System.Text.Json;

Expand Down Expand Up @@ -79,6 +80,7 @@ private static void RunSelectSample()
private static void RunMultiSelectSample()
{
var options = Prompt.MultiSelect("Which cities would you like to visit?", new[] { "Seattle", "London", "Tokyo", "New York", "Singapore", "Shanghai" }, pageSize: 3, defaultValues: new[] { "Tokyo" });

Console.WriteLine($"You picked {string.Join(", ", options)}");
}

Expand Down
17 changes: 10 additions & 7 deletions Sharprompt.Tests/PaginatorTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using System;
using System.Linq;

using Sharprompt.Internal;

Expand All @@ -8,10 +9,12 @@ namespace Sharprompt.Tests;

public class PaginatorTests
{
private readonly Func<int, string, bool> _containsTextInputFilter = (item, keyword) => item.ToString().Contains(keyword, StringComparison.OrdinalIgnoreCase);

[Fact]
public void Basic()
{
var paginator = new Paginator<int>(Enumerable.Range(0, 20), 5, Optional<int>.Empty, x => x.ToString());
var paginator = new Paginator<int>(Enumerable.Range(0, 20), 5, Optional<int>.Empty, x => x.ToString(), _containsTextInputFilter);

var currentItems1 = paginator.CurrentItems;

Expand All @@ -29,7 +32,7 @@ public void Basic()
[Fact]
public void Filter_NotEmpty()
{
var paginator = new Paginator<int>(Enumerable.Range(0, 20), 5, Optional<int>.Empty, x => x.ToString());
var paginator = new Paginator<int>(Enumerable.Range(0, 20), 5, Optional<int>.Empty, x => x.ToString(), _containsTextInputFilter);

paginator.UpdateFilter("0");

Expand All @@ -42,7 +45,7 @@ public void Filter_NotEmpty()
[Fact]
public void Filter_Empty()
{
var paginator = new Paginator<int>(Enumerable.Range(0, 20), 5, Optional<int>.Empty, x => x.ToString());
var paginator = new Paginator<int>(Enumerable.Range(0, 20), 5, Optional<int>.Empty, x => x.ToString(), _containsTextInputFilter);

paginator.UpdateFilter("x");

Expand All @@ -54,7 +57,7 @@ public void Filter_Empty()
[Fact]
public void SelectedItem()
{
var paginator = new Paginator<int>(Enumerable.Range(0, 20), 5, Optional<int>.Empty, x => x.ToString());
var paginator = new Paginator<int>(Enumerable.Range(0, 20), 5, Optional<int>.Empty, x => x.ToString(), _containsTextInputFilter);

paginator.NextPage();
paginator.NextItem();
Expand All @@ -68,7 +71,7 @@ public void SelectedItem()
[Fact]
public void SelectedItem_NotSelected()
{
var paginator = new Paginator<int>(Enumerable.Range(0, 20), 5, Optional<int>.Empty, x => x.ToString());
var paginator = new Paginator<int>(Enumerable.Range(0, 20), 5, Optional<int>.Empty, x => x.ToString(), _containsTextInputFilter);

var selected = paginator.TryGetSelectedItem(out _);

Expand All @@ -78,7 +81,7 @@ public void SelectedItem_NotSelected()
[Fact]
public void SelectedItem_EmptyList()
{
var paginator = new Paginator<int>(Enumerable.Range(0, 20), 5, Optional<int>.Empty, x => x.ToString());
var paginator = new Paginator<int>(Enumerable.Range(0, 20), 5, Optional<int>.Empty, x => x.ToString(), _containsTextInputFilter);

paginator.UpdateFilter("x");
paginator.NextItem();
Expand Down
2 changes: 1 addition & 1 deletion Sharprompt/Forms/MultiSelectForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public MultiSelectForm(MultiSelectOptions<T> options)
options.EnsureOptions();

_options = options;
_paginator = new Paginator<T>(options.Items, Math.Min(options.PageSize, Height - 2), Optional<T>.Empty, options.TextSelector)
_paginator = new Paginator<T>(options.Items, Math.Min(options.PageSize, Height - 2), Optional<T>.Empty, options.TextSelector, options.TextInputFilter)
{
LoopingSelection = options.LoopingSelection
};
Expand Down
2 changes: 1 addition & 1 deletion Sharprompt/Forms/SelectForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public SelectForm(SelectOptions<T> options)
options.EnsureOptions();

_options = options;
_paginator = new Paginator<T>(options.Items, Math.Min(options.PageSize, Height - 2), Optional<T>.Create(options.DefaultValue), options.TextSelector)
_paginator = new Paginator<T>(options.Items, Math.Min(options.PageSize, Height - 2), Optional<T>.Create(options.DefaultValue), options.TextSelector, options.TextInputFilter)
{
LoopingSelection = options.LoopingSelection
};
Expand Down
8 changes: 5 additions & 3 deletions Sharprompt/Internal/Paginator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,19 @@ namespace Sharprompt.Internal;

internal class Paginator<T> : IEnumerable<T> where T : notnull
{
public Paginator(IEnumerable<T> items, int pageSize, Optional<T> defaultValue, Func<T, string> textSelector)
public Paginator(IEnumerable<T> items, int pageSize, Optional<T> defaultValue, Func<T, string> textSelector, Func<T, string, bool> textInputFilter)
{
_items = items.ToArray();
_pageSize = pageSize <= 0 ? _items.Length : Math.Min(pageSize, _items.Length);
_textSelector = textSelector;
_filterFunc = textInputFilter;

InitializeDefaults(defaultValue);
}

private readonly T[] _items;
private readonly Func<T, string> _textSelector;
private readonly Func<T, string, bool> _filterFunc;

private int _pageSize;
private T[] _filteredItems = Array.Empty<T>();
Expand Down Expand Up @@ -144,8 +146,8 @@ public void UpdatePageSize(int newPageSize)

private void UpdateFilteredItems()
{
_filteredItems = _items.Where(x => _textSelector(x).IndexOf(FilterKeyword, StringComparison.OrdinalIgnoreCase) != -1)
.ToArray();
_filteredItems = _items.Where(x => _filterFunc(x, FilterKeyword))
.ToArray();

PageCount = (_filteredItems.Length - 1) / _pageSize + 1;

Expand Down
2 changes: 2 additions & 0 deletions Sharprompt/MultiSelectOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public MultiSelectOptions()

public Func<T, string> TextSelector { get; set; } = x => x.ToString()!;

public Func<T, string, bool> TextInputFilter { get; set; } = (item, keyword) => item.ToString().Contains(keyword, StringComparison.OrdinalIgnoreCase);

public Func<int, int, int, string> Pagination { get; set; } = (count, current, total) => string.Format(Resource.Message_Pagination, count, current, total);

public bool LoopingSelection { get; set; } = true;
Expand Down
16 changes: 14 additions & 2 deletions Sharprompt/Prompt.Basic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public static T Select<T>(Action<SelectOptions<T>> configure) where T : notnull
return Select(options);
}

public static T Select<T>(string message, IEnumerable<T>? items = default, int pageSize = int.MaxValue, object? defaultValue = default, Func<T, string>? textSelector = default) where T : notnull
public static T Select<T>(string message, IEnumerable<T>? items = default, int pageSize = int.MaxValue, object? defaultValue = default, Func<T, string>? textSelector = default, Func<T, string, bool>? textInputFilter = default) where T : notnull
{
return Select<T>(options =>
{
Expand All @@ -124,6 +124,11 @@ public static T Select<T>(string message, IEnumerable<T>? items = default, int p
{
options.TextSelector = textSelector;
}

if (textInputFilter is not null)
{
options.TextInputFilter = textInputFilter;
}
});
}

Expand All @@ -143,7 +148,9 @@ public static IEnumerable<T> MultiSelect<T>(Action<MultiSelectOptions<T>> config
return MultiSelect(options);
}

public static IEnumerable<T> MultiSelect<T>(string message, IEnumerable<T>? items = null, int pageSize = int.MaxValue, int minimum = 1, int maximum = int.MaxValue, IEnumerable<T>? defaultValues = default, Func<T, string>? textSelector = default) where T : notnull
public static IEnumerable<T> MultiSelect<T>(string message,
IEnumerable<T>? items = null, int pageSize = int.MaxValue, int minimum = 1, int maximum = int.MaxValue,
IEnumerable<T>? defaultValues = default, Func<T, string>? textSelector = default, Func<T, string, bool>? textInputFilter = default) where T : notnull
{
return MultiSelect<T>(options =>
{
Expand All @@ -167,6 +174,11 @@ public static IEnumerable<T> MultiSelect<T>(string message, IEnumerable<T>? item
{
options.TextSelector = textSelector;
}

if (textInputFilter is not null)
{
options.TextInputFilter = textInputFilter;
}
});
}

Expand Down
2 changes: 2 additions & 0 deletions Sharprompt/SelectOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public SelectOptions()

public Func<T, string> TextSelector { get; set; } = x => x.ToString()!;

public Func<T, string, bool> TextInputFilter { get; set; } = (item, keyword) => item.ToString().Contains(keyword, StringComparison.OrdinalIgnoreCase);

public Func<int, int, int, string> Pagination { get; set; } = (count, current, total) => string.Format(Resource.Message_Pagination, count, current, total);

public bool LoopingSelection { get; set; } = true;
Expand Down