Skip to content
Merged
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
10 changes: 10 additions & 0 deletions PSReadLine/BasicEditing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ public static void CancelLine(ConsoleKeyInfo? key = null, object arg = null)
{
_singleton.ClearStatusMessage(false);
_singleton._current = _singleton._buffer.Length;

using var _ = _singleton.PredictionOff();
_singleton.ForceRender();

_singleton._console.Write("\x1b[91m^C\x1b[0m");
Expand Down Expand Up @@ -214,6 +216,8 @@ public static void DeleteCharOrExit(ConsoleKeyInfo? key = null, object arg = nul

private bool AcceptLineImpl(bool validate)
{
using var _ = PredictionOff();

ParseInput();
if (_parseErrors.Any(e => e.IncompleteInput))
{
Expand Down Expand Up @@ -274,6 +278,12 @@ private bool AcceptLineImpl(bool validate)

// Let public API set cursor to end of line incase end of line is end of buffer
SetCursorPosition(_current);
if (_suggestionText != null)
{
ResetSuggestion();
_console.BlankRestOfLine();
}

_console.Write("\n");
_inputAccepted = true;
return true;
Expand Down
6 changes: 6 additions & 0 deletions PSReadLine/Changes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
### Version 2.1.0-beta1

Pre-release notes:

* Experimental support for fish-like suggestions in PSReadLine.

### Version 2.0.1

Bug fixes:
Expand Down
40 changes: 39 additions & 1 deletion PSReadLine/Cmdlets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ public enum AddToHistoryOption
MemoryAndFile
}

public enum PredictionSource
{
None,
History,
}

public class PSConsoleReadLineOptions
{
public const ConsoleColor DefaultCommentColor = ConsoleColor.DarkGreen;
Expand All @@ -78,6 +84,10 @@ public class PSConsoleReadLineOptions
public const ConsoleColor DefaultEmphasisColor = ConsoleColor.Cyan;
public const ConsoleColor DefaultErrorColor = ConsoleColor.Red;

// Use dark black by default for the suggestion text.
// Find the most suitable color using https://stackoverflow.com/a/33206814
public const string DefaultPredictionColor = "\x1b[38;5;238m";
Comment thread
daxian-dbw marked this conversation as resolved.
Resolved

public static EditMode DefaultEditMode = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? EditMode.Windows
: EditMode.Emacs;
Expand Down Expand Up @@ -128,6 +138,11 @@ public class PSConsoleReadLineOptions

public const HistorySaveStyle DefaultHistorySaveStyle = HistorySaveStyle.SaveIncrementally;

/// <summary>
/// The predictive suggestion feature is disabled by default.
/// </summary>
public const PredictionSource DefaultPredictionSource = PredictionSource.None;

/// <summary>
/// How long in milliseconds should we wait before concluding
/// the input is not an escape sequence?
Expand Down Expand Up @@ -155,6 +170,7 @@ public PSConsoleReadLineOptions(string hostName)
HistorySearchCaseSensitive = DefaultHistorySearchCaseSensitive;
HistorySaveStyle = DefaultHistorySaveStyle;
AnsiEscapeTimeout = DefaultAnsiEscapeTimeout;
PredictionSource = DefaultPredictionSource;

var historyFileName = hostName + "_history.txt";
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
Expand Down Expand Up @@ -309,6 +325,11 @@ public object ContinuationPromptColor
public string HistorySavePath { get; set; }
public HistorySaveStyle HistorySaveStyle { get; set; }

/// <summary>
/// Sets the source to get predictive suggestions.
/// </summary>
public PredictionSource PredictionSource { get; set; }

/// <summary>
/// How long in milliseconds should we wait before concluding
/// the input is not an escape sequence?
Expand Down Expand Up @@ -407,6 +428,12 @@ public object SelectionColor
set => _selectionColor = VTColorUtils.AsEscapeSequence(value);
}

public object PredictionColor
{
get => _predictionColor;
set => _predictionColor = VTColorUtils.AsEscapeSequence(value);
}

internal string _defaultTokenColor;
internal string _commentColor;
internal string _keywordColor;
Expand All @@ -421,6 +448,7 @@ public object SelectionColor
internal string _emphasisColor;
internal string _errorColor;
internal string _selectionColor;
internal string _predictionColor;

internal void ResetColors()
{
Expand All @@ -438,6 +466,7 @@ internal void ResetColors()
MemberColor = DefaultNumberColor;
EmphasisColor = DefaultEmphasisColor;
ErrorColor = DefaultErrorColor;
PredictionColor = DefaultPredictionColor;

var bg = Console.BackgroundColor;
if (fg == VTColorUtils.UnknownColor || bg == VTColorUtils.UnknownColor)
Expand Down Expand Up @@ -473,7 +502,8 @@ internal void SetColor(string property, object value)
{"Type", (o, v) => o.TypeColor = v},
{"Number", (o, v) => o.NumberColor = v},
{"Member", (o, v) => o.MemberColor = v},
{"Selection", (o, v) => o.SelectionColor = v },
{"Selection", (o, v) => o.SelectionColor = v},
{"Prediction", (o, v) => o.PredictionColor = v},
};

Interlocked.CompareExchange(ref ColorSetters, setters, null);
Expand Down Expand Up @@ -680,6 +710,14 @@ public ViModeStyle ViModeIndicator
[Parameter]
public ScriptBlock ViModeChangeHandler { get; set; }

[Parameter]
public PredictionSource PredictionSource
{
get => _predictionSource.GetValueOrDefault();
set => _predictionSource = value;
}
internal PredictionSource? _predictionSource;

[Parameter]
public Hashtable Colors { get; set; }

Expand Down
3 changes: 3 additions & 0 deletions PSReadLine/Completion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ private void CompleteImpl(bool menuSelect)
ViInsertWithAppend();
}

// Do not show suggestion text during tab completion.
using var _ = PredictionOff();

var completions = GetCompletions();
if (completions == null || completions.CompletionMatches.Count == 0)
return;
Expand Down
27 changes: 27 additions & 0 deletions PSReadLine/History.cs
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,8 @@ private void UpdateFromHistory(HistoryMoveCursor moveCursor)
}
break;
}

using var _ = PredictionOff();
Render();
}

Expand Down Expand Up @@ -677,6 +679,30 @@ private void HistorySearch(int direction)
}
}

/// <summary>
/// Currently we only select single-line history that is prefixed with the user input,
/// but it can be improved to not strictly use the user input as a prefix, but a hint
/// to extract a partial pipeline or statement from a single-line or multiple-line
/// history entry.
/// </summary>
private string GetHistorySuggestion(string text)
{
Comment thread
daxian-dbw marked this conversation as resolved.
Resolved
for (int index = _history.Count - 1; index >= 0; index --)
{
var line = _history[index].CommandLine.TrimEnd();
if (line.Length > text.Length)
{
bool isMultiLine = line.Contains('\n');
if (!isMultiLine && line.StartsWith(text, Options.HistoryStringComparison))
{
return line;
}
}
}

return null;
}

/// <summary>
/// Move to the first item in the history.
/// </summary>
Expand Down Expand Up @@ -889,6 +915,7 @@ private void InteractiveHistorySearchLoop(int direction)

private void InteractiveHistorySearch(int direction)
{
using var _ = PredictionOff();
SaveCurrentLine();

// Add a status line that will contain the search prompt and string
Expand Down
2 changes: 2 additions & 0 deletions PSReadLine/KeyBindings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,8 @@ public static KeyHandlerGroup GetDisplayGrouping(string function)
case nameof(ViExit):
case nameof(ViInsertMode):
case nameof(WhatIsKey):
case nameof(AcceptSuggestion):
case nameof(AcceptNextSuggestionWord):
return KeyHandlerGroup.Miscellaneous;

case nameof(CharacterSearch):
Expand Down
15 changes: 14 additions & 1 deletion PSReadLine/Movement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,14 @@ public static void ForwardChar(ConsoleKeyInfo? key = null, object arg = null)
{
if (TryGetArgAsInt(arg, out var numericArg, 1))
{
SetCursorPosition(_singleton._current + numericArg);
if (_singleton._current == _singleton._buffer.Length && numericArg > 0)
{
AcceptSuggestion(key, arg);
}
else
{
SetCursorPosition(_singleton._current + numericArg);
}
}
}

Expand Down Expand Up @@ -311,6 +318,12 @@ public static void ForwardWord(ConsoleKeyInfo? key = null, object arg = null)
return;
}

if (_singleton._current == _singleton._buffer.Length && numericArg > 0)
{
AcceptNextSuggestionWord(numericArg);
return;
}

if (numericArg < 0)
{
BackwardWord(key, -numericArg);
Expand Down
8 changes: 8 additions & 0 deletions PSReadLine/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@ private void SetOptionsInternal(SetPSReadLineOption options)
{
Options.PromptText = options.PromptText;
}
if (options._predictionSource.HasValue)
{
if (_console is PlatformWindows.LegacyWin32Console && options.PredictionSource != PredictionSource.None)
{
throw new ArgumentException(PSReadLineResources.PredictiveSuggestionNotSupported);
}
Options.PredictionSource = options.PredictionSource;
}
if (options.Colors != null)
{
IDictionaryEnumerator e = options.Colors.GetEnumerator();
Expand Down
7 changes: 4 additions & 3 deletions PSReadLine/PSReadLine.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
<OutputType>Library</OutputType>
<RootNamespace>Microsoft.PowerShell.PSReadLine</RootNamespace>
<AssemblyName>Microsoft.PowerShell.PSReadLine2</AssemblyName>
<AssemblyVersion>2.0.1.0</AssemblyVersion>
<FileVersion>2.0.1</FileVersion>
<InformationalVersion>2.0.1</InformationalVersion>
<AssemblyVersion>2.1.0.0</AssemblyVersion>
<FileVersion>2.1.0</FileVersion>
<InformationalVersion>2.1.0-beta1</InformationalVersion>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
<TargetFrameworks>net461;netcoreapp2.1</TargetFrameworks>
<LangVersion>8.0</LangVersion>
</PropertyGroup>

<PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1'">
Expand Down
7 changes: 7 additions & 0 deletions PSReadLine/PSReadLine.format.ps1xml
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ $d = [Microsoft.PowerShell.KeyHandler]::GetGroupingDescription($_.Group)
<ListItem>
<PropertyName>AnsiEscapeTimeout</PropertyName>
</ListItem>
<ListItem>
<PropertyName>PredictionSource</PropertyName>
</ListItem>
<ListItem>
<Label>CommandColor</Label>
<ScriptBlock>[Microsoft.PowerShell.VTColorUtils]::FormatColor($_.CommandColor)</ScriptBlock>
Expand Down Expand Up @@ -202,6 +205,10 @@ $d = [Microsoft.PowerShell.KeyHandler]::GetGroupingDescription($_.Group)
<Label>ParameterColor</Label>
<ScriptBlock>[Microsoft.PowerShell.VTColorUtils]::FormatColor($_.ParameterColor)</ScriptBlock>
</ListItem>
<ListItem>
<Label>PredictionColor</Label>
<ScriptBlock>[Microsoft.PowerShell.VTColorUtils]::FormatColor($_.PredictionColor)</ScriptBlock>
</ListItem>
<ListItem>
<Label>SelectionColor</Label>
<ScriptBlock>[Microsoft.PowerShell.VTColorUtils]::FormatColor($_.SelectionColor)</ScriptBlock>
Expand Down
29 changes: 28 additions & 1 deletion PSReadLine/PSReadLineResources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions PSReadLine/PSReadLineResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,12 @@ If there are other parse errors, unresolved commands, or incorrect parameters, s
<data name="InsertLineBelowDescription" xml:space="preserve">
<value>Inserts a new empty line below the current line without attempting to execute the input</value>
</data>
<data name="AcceptSuggestionDescription" xml:space="preserve">
<value>Accept the current inline or selected suggestion</value>
</data>
<data name="AcceptNextSuggestionWordDescription" xml:space="preserve">
<value>Accept the next word of the inline or selected suggestion</value>
</data>
<data name="HistoryFileErrorMessage" xml:space="preserve">
<value>Error reading or writing history file '{0}': {1}</value>
</data>
Expand Down Expand Up @@ -783,4 +789,7 @@ Or not saving history with:
<data name="InvalidColorProperty" xml:space="preserve">
<value>'{0}' is not a valid color property</value>
</data>
<data name="PredictiveSuggestionNotSupported" xml:space="preserve">
<value>The predictive suggestion feature cannot be enabled because the console output doesn't support virtual terminal processing or it's redirected.</value>
</data>
</root>
6 changes: 6 additions & 0 deletions PSReadLine/ReadLine.vi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,9 @@ internal static IDisposable UseViInsertModeTables()

private void ViIndicateCommandMode()
{
// Show suggestion in 'InsertMode' but not 'CommandMode'.
_showSuggestion = false;

if (_options.ViModeIndicator == ViModeStyle.Cursor)
{
_console.CursorSize = _normalCursorSize < 50 ? 100 : 25;
Expand All @@ -541,6 +544,9 @@ private void ViIndicateCommandMode()

private void ViIndicateInsertMode()
{
// Show suggestion in 'InsertMode' but not 'CommandMode'.
_showSuggestion = true;

if (_options.ViModeIndicator == ViModeStyle.Cursor)
{
_console.CursorSize = _normalCursorSize;
Expand Down
Loading