diff --git a/PSReadLine/Cmdlets.cs b/PSReadLine/Cmdlets.cs index 596b1548..02f97fb9 100644 --- a/PSReadLine/Cmdlets.cs +++ b/PSReadLine/Cmdlets.cs @@ -112,6 +112,21 @@ public class PSConsoleReadLineOptions /// public const int DefaultMaximumHistoryCount = 4096; + /// + /// The number of lines in prediction list; + /// + public const int DefaultPredictionListCount = 50; + + /// + /// The number of lines in history prediction list; + /// + public const int DefaultPredictionHistoryCount = 10; + + /// + /// The number of lines to show from prediction list; + /// + public const int DefaultPredictionViewHeight = 10; + /// /// The maximum number of items to store in the kill ring. /// @@ -202,6 +217,9 @@ public PSConsoleReadLineOptions(string hostName, bool usingLegacyConsole) ContinuationPromptColor = Console.ForegroundColor; ExtraPromptLineCount = DefaultExtraPromptLineCount; AddToHistoryHandler = DefaultAddToHistoryHandler; + PredictionListCount = DefaultPredictionListCount; + PredictionHistoryCount = DefaultPredictionHistoryCount; + PredictionViewHeight = DefaultPredictionViewHeight; HistoryNoDuplicates = DefaultHistoryNoDuplicates; MaximumKillRingCount = DefaultMaximumKillRingCount; HistorySearchCursorMovesToEnd = DefaultHistorySearchCursorMovesToEnd; @@ -342,6 +360,9 @@ public object ContinuationPromptColor public int MaximumHistoryCount { get; set; } public int MaximumKillRingCount { get; set; } + public int PredictionListCount { get; set; } + public int PredictionHistoryCount { get; set; } + public int PredictionViewHeight { get; set; } public bool HistorySearchCursorMovesToEnd { get; set; } public bool ShowToolTips { get; set; } public int DingTone { get; set; } @@ -655,6 +676,33 @@ public EditMode EditMode [AllowEmptyString] public string ContinuationPrompt { get; set; } + [Parameter] + [ValidateRange(1, int.MaxValue)] + public int PredictionListCount + { + get => _predictionListCount.GetValueOrDefault(); + set => _predictionListCount = value; + } + internal int? _predictionListCount; + + [Parameter] + [ValidateRange(1, int.MaxValue)] + public int PredictionHistoryCount + { + get => _predictionHistoryCount.GetValueOrDefault(); + set => _predictionHistoryCount = value; + } + internal int? _predictionHistoryCount; + + [Parameter] + [ValidateRange(1, int.MaxValue)] + public int PredictionViewHeight + { + get => _predictionViewHeight.GetValueOrDefault(); + set => _predictionViewHeight = value; + } + internal int? _predictionViewHeight; + [Parameter] public SwitchParameter HistoryNoDuplicates { diff --git a/PSReadLine/Options.cs b/PSReadLine/Options.cs index ffdf0241..ffa71658 100644 --- a/PSReadLine/Options.cs +++ b/PSReadLine/Options.cs @@ -26,6 +26,18 @@ private void SetOptionsInternal(SetPSReadLineOption options) { Options.ContinuationPrompt = options.ContinuationPrompt; } + if (options._predictionListCount.HasValue) + { + Options.PredictionListCount = options.PredictionListCount; + } + if (options._predictionHistoryCount.HasValue) + { + Options.PredictionHistoryCount = options.PredictionHistoryCount; + } + if (options._predictionViewHeight.HasValue) + { + Options.PredictionViewHeight = options.PredictionViewHeight; + } if (options._historyNoDuplicates.HasValue) { Options.HistoryNoDuplicates = options.HistoryNoDuplicates; diff --git a/PSReadLine/PSReadLine.format.ps1xml b/PSReadLine/PSReadLine.format.ps1xml index 62867e76..b3096591 100644 --- a/PSReadLine/PSReadLine.format.ps1xml +++ b/PSReadLine/PSReadLine.format.ps1xml @@ -111,6 +111,9 @@ $d = [Microsoft.PowerShell.KeyHandler]::GetGroupingDescription($_.Group) MaximumHistoryCount + + PredictionViewHeight + ContinuationPrompt diff --git a/PSReadLine/Prediction.Views.cs b/PSReadLine/Prediction.Views.cs index a9145c43..d139c3a7 100644 --- a/PSReadLine/Prediction.Views.cs +++ b/PSReadLine/Prediction.Views.cs @@ -208,9 +208,21 @@ protected List GetPredictionResults() /// private class PredictionListView : PredictionViewBase { - // Item count constants. - internal const int ListMaxCount = 50; - internal const int HistoryMaxCount = 10; + // Physical limit: What can actually fit on the screen? + // We use -2 for the cursor line and the "jitter buffer." + private int PhysicalMax => Math.Max(1, _singleton._console.BufferHeight - 2); + + // Visible View: The smaller of (User Request) and (Physical Space) + internal int PredictionViewHeight => Math.Min(_singleton._options.PredictionViewHeight, PhysicalMax); + + // Global Ceiling: Remains the total scrollable capacity + internal int ListMaxCount => _singleton._options.PredictionListCount; + + // History Fetch: At least enough to fill the view, up to the total ListCount + internal int HistoryMaxCount => Math.Min( + Math.Max(_singleton._options.PredictionHistoryCount, PredictionViewHeight), + ListMaxCount + ); // List view constants. internal const int ListViewMaxHeight = 10; @@ -327,21 +339,31 @@ internal PredictionListView(PSConsoleReadLine singleton) internal override bool HasActiveSuggestion => _listItems != null; /// - /// Calculate the max width and height of the list view based on the current terminal size. + /// Calculate the max width and height of the list view based on option value. /// private (int, int, int, bool) RefreshMaxViewSize() { var console = _singleton._console; int maxListWidth = Math.Min(console.BufferWidth, ListViewMaxWidth); - (int maxListHeight, int maxTooltipHeigth, bool moreCheck) = console.BufferHeight switch - { - > ListViewMaxHeight * 2 => (ListViewMaxHeight, TooltipMaxHeight, false), - > ListViewMaxHeight => (ListViewMaxHeight / 2, TooltipMaxHeight / 2, false), - _ => (ListViewMaxHeight / 3, TooltipMaxHeight / 3, true) - }; + if (HistoryMaxCount == 10) { + // Don't change default behavior + (int maxListHeight, int maxTooltipHeigth, bool moreCheck) = console.BufferHeight switch + { + > ListViewMaxHeight * 2 => (ListViewMaxHeight, TooltipMaxHeight, false), + > ListViewMaxHeight => (ListViewMaxHeight / 2, TooltipMaxHeight / 2, false), + _ => (ListViewMaxHeight / 3, TooltipMaxHeight / 3, true) + }; + + return (maxListWidth, maxListHeight, maxTooltipHeigth, moreCheck); + } else { + int maxListHeight = HistoryMaxCount; + int maxTooltipHeigth = TooltipMaxHeight; - return (maxListWidth, maxListHeight, maxTooltipHeigth, moreCheck); + bool moreCheck = console.BufferHeight < maxListHeight + 2; + + return (maxListWidth, maxListHeight, maxTooltipHeigth, moreCheck); + } } /// @@ -444,7 +466,7 @@ private void AggregateSuggestions() _cacheList2 ??= new List(); // This list holds the final number of suggestions that will be rendered for each of the predictors. int pCount = 0; - int hCount = Math.Min(3, _listItems.Count); + int hCount = Math.Min(HistoryMaxCount, _listItems.Count); int remRows = ListMaxCount - hCount; // Calculate the number of plugins that we need to handle,