Skip to content

Commit 256db70

Browse files
committed
PossibleCompletions fixes
Fixes to PossibleCompletions: * Truncate when list item/tooltip has `n * Prompt when too many (default 100) completions * Add option to configure how many completions before prompting
1 parent 2046536 commit 256db70

File tree

4 files changed

+78
-6
lines changed

4 files changed

+78
-6
lines changed

PSReadLine/Cmdlets.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ public class PSConsoleReadlineOptions
4949

5050
public const int DefaultDingDuration = 50;
5151

52+
public const int DefaultCompletionQueryItems = 100;
53+
5254
/// <summary>
5355
/// When ringing the bell, what should be done?
5456
/// </summary>
@@ -70,6 +72,7 @@ public PSConsoleReadlineOptions()
7072
DingDuration = DefaultDingDuration;
7173
DingTone = DefaultDingTone;
7274
BellStyle = DefaultBellStyle;
75+
CompletionQueryItems = DefaultCompletionQueryItems;
7376
}
7477

7578
public string ContinuationPrompt { get; set; }
@@ -100,6 +103,7 @@ public PSConsoleReadlineOptions()
100103
public bool HistorySearchCursorMovesToEnd { get; set; }
101104
public bool ShowToolTips { get; set; }
102105
public int DingTone { get; set; }
106+
public int CompletionQueryItems { get; set; }
103107

104108
/// <summary>
105109
/// When ringing the bell, how long (in ms)?
@@ -329,6 +333,14 @@ public BellStyle BellStyle
329333
}
330334
internal BellStyle? _bellStyle;
331335

336+
[Parameter(ParameterSetName = "OptionsSet")]
337+
public int CompletionQueryItems
338+
{
339+
get { return _completionQueryItems.GetValueOrDefault(); }
340+
set { _completionQueryItems = value; }
341+
}
342+
internal int? _completionQueryItems;
343+
332344
[Parameter(ParameterSetName = "ColorSet", Position = 0, Mandatory = true)]
333345
public TokenClassification TokenKind
334346
{

PSReadLine/PSReadLineResources.Designer.cs

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

PSReadLine/PSReadLineResources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,4 +249,7 @@
249249
<data name="ReplacementLengthTooBig" xml:space="preserve">
250250
<value>length is too big</value>
251251
</data>
252+
<data name="DisplayAllPossibilities" xml:space="preserve">
253+
<value>Display all {0} possibilities? (y or n)</value>
254+
</data>
252255
</root>

PSReadLine/ReadLine.cs

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Management.Automation;
77
using System.Management.Automation.Language;
88
using System.Text;
9+
using System.Text.RegularExpressions;
910

1011
namespace PSConsoleUtilities
1112
{
@@ -1113,16 +1114,32 @@ public static void PossibleCompletions(ConsoleKeyInfo? key = null, object arg =
11131114
var coords = _singleton.ConvertOffsetToCoordinates(_singleton._buffer.Length);
11141115
_singleton.PlaceCursor(0, coords.Y + 1);
11151116

1117+
if (completions.CompletionMatches.Count >= _singleton._options.CompletionQueryItems)
1118+
{
1119+
if (!PromptYesOrNo(string.Format(PSReadLineResources.DisplayAllPossibilities, completions.CompletionMatches.Count)))
1120+
{
1121+
_singleton.PlaceCursor(0, coords.Y + 1);
1122+
WriteLine("");
1123+
_singleton.PlaceCursor(coords.X, coords.Y);
1124+
return;
1125+
}
1126+
}
1127+
11161128
var sb = new StringBuilder();
1117-
var minColWidth = completions.CompletionMatches.Max(c => c.ListItemText.Length);
1129+
var matches = completions.CompletionMatches.Select(
1130+
completion =>
1131+
new {ListItemText = Regex.Replace(completion.ListItemText, "\n.*", "..."),
1132+
ToolTip = Regex.Replace(completion.ToolTip, "\n.*", "...")})
1133+
.ToArray();
1134+
var minColWidth = matches.Max(c => c.ListItemText.Length);
11181135
minColWidth += 2;
11191136

11201137
if (_singleton.Options.ShowToolTips)
11211138
{
11221139
const string seperator = "- ";
11231140
var maxTooltipWidth = Console.BufferWidth - minColWidth - seperator.Length;
11241141

1125-
foreach (var match in completions.CompletionMatches)
1142+
foreach (var match in matches)
11261143
{
11271144
sb.Append(match.ListItemText);
11281145
var spacesNeeded = minColWidth - match.ListItemText.Length;
@@ -1148,9 +1165,9 @@ public static void PossibleCompletions(ConsoleKeyInfo? key = null, object arg =
11481165
for (var col = 0; col < displayColumns; col++)
11491166
{
11501167
var index = row + (displayRows * col);
1151-
if (index >= completions.CompletionMatches.Count)
1168+
if (index >= matches.Length)
11521169
break;
1153-
var item = completions.CompletionMatches[index].ListItemText;
1170+
var item = matches[index].ListItemText;
11541171
sb.Append(item);
11551172
sb.Append(' ', minColWidth - item.Length);
11561173
}
@@ -2070,7 +2087,7 @@ public static void Ding()
20702087
// The unit test framework redirects stdout - so it would see Console.WriteLine calls.
20712088
// Unfortunately, we are testing exact placement of characters on the screen, so redirection
20722089
// doesn't work for us.
2073-
static private void WriteLine(string s)
2090+
static private void WriteImpl(string s)
20742091
{
20752092
Debug.Assert(s.Length <= Console.BufferWidth);
20762093

@@ -2097,10 +2114,37 @@ static private void WriteLine(string s)
20972114
Right = (short) s.Length
20982115
};
20992116
NativeMethods.WriteConsoleOutput(handle, buffer, bufferSize, bufferCoord, ref writeRegion);
2117+
}
2118+
2119+
static private void WriteLine(string s)
2120+
{
2121+
Debug.Assert(s.Length <= Console.BufferWidth);
2122+
2123+
var spaces = Console.BufferWidth - s.Length;
2124+
if (spaces > 0)
2125+
{
2126+
s = s + new string(' ', spaces);
2127+
}
2128+
WriteImpl(s);
21002129

21012130
_singleton.PlaceCursor(0, Console.CursorTop + 1);
21022131
}
21032132

2133+
static private void Write(string s)
2134+
{
2135+
WriteImpl(s);
2136+
2137+
_singleton.PlaceCursor(s.Length, Console.CursorTop);
2138+
}
2139+
2140+
static private bool PromptYesOrNo(string s)
2141+
{
2142+
Write(s);
2143+
2144+
var key = ReadKey();
2145+
return key.Key == ConsoleKey.Y;
2146+
}
2147+
21042148
private void RenderDemoWindow(int windowStart)
21052149
{
21062150
int i;
@@ -2344,6 +2388,10 @@ private void SetOptionsInternal(SetPSReadlineOption options)
23442388
{
23452389
Options.BellStyle = options.BellStyle;
23462390
}
2391+
if (options._completionQueryItems.HasValue)
2392+
{
2393+
Options.CompletionQueryItems = options.CompletionQueryItems;
2394+
}
23472395
if (options.ResetTokenColors)
23482396
{
23492397
Options.ResetColors();

0 commit comments

Comments
 (0)