Thanks to visit codestin.com
Credit goes to github.com

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
24 changes: 23 additions & 1 deletion PSReadLine/KillYank.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation.Language;
using System.Text.RegularExpressions;
using Microsoft.PowerShell.Internal;

namespace Microsoft.PowerShell
Expand All @@ -29,6 +30,10 @@ class YankLastArgState
private YankLastArgState _yankLastArgState;
private int _visualSelectionCommandCount;

// Pattern to check for CLI parameters like '--json'.
// Valid characters are 'a-z', 'A-Z', '0-9', '_' (all covered by '\w'), and '-'.
private static readonly Regex s_cliOptionPattern = new(@"^--[\w-]+$", RegexOptions.Compiled);

/// <summary>
/// Mark the current location of the cursor for use in a subsequent editing command.
/// </summary>
Expand Down Expand Up @@ -480,7 +485,7 @@ public static void SelectCommandArgument(ConsoleKeyInfo? key = null, object arg
var argument = cmdAst.CommandElements[j] switch
{
CommandParameterAst paramAst => paramAst.Argument,
ExpressionAst expAst => expAst,
ExpressionAst exprAst => ProcessExpressionAst(exprAst),
_ => null,
};

Expand Down Expand Up @@ -614,6 +619,7 @@ public static void SelectCommandArgument(ConsoleKeyInfo? key = null, object arg
_singleton.VisualSelectionCommon(() => SetCursorPosition(newEndCursor), forceSetMark: true);


// ===== Local Functions =====
// Get the script block AST's whose extent contains the cursor.
bool GetScriptBlockAst(Ast ast)
{
Expand All @@ -639,6 +645,22 @@ bool GetScriptBlockAst(Ast ast)
? ast.Extent.EndOffset - 1 > cursor
: ast.Extent.EndOffset >= cursor;
}

// Process an expression AST to check if it's a CLI posix style option.
static ExpressionAst ProcessExpressionAst(ExpressionAst exprAst)
{
if (exprAst is StringConstantExpressionAst strAst
&& strAst.StringConstantType is StringConstantType.BareWord
&& strAst.Value.StartsWith("--")
&& s_cliOptionPattern.IsMatch(strAst.Value))
{
// It's a CLI posix style option, like '--json' or '--machine-type',
// so we treat it as a parameter.
return null;
}

return exprAst;
}
}

/// <summary>
Expand Down
50 changes: 50 additions & 0 deletions test/KillYankTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,56 @@ public void SelectCommandArgument_VariousArgs()
_.Escape));
}

[SkippableFact]
public void SelectCommandArgument_CLIArgs()
{
TestSetup(KeyMode.Cmd);

Test("", Keys(
"az webapp --name MyWebApp --resource-group MyResourceGroup",
_.Alt_a, CheckThat(() => AssertScreenIs(1,
TokenClassification.Command, "az",
TokenClassification.None, ' ',
TokenClassification.Selection, "webapp",
TokenClassification.None, ' ',
TokenClassification.Parameter, "--name",
TokenClassification.None, " MyWebApp ",
TokenClassification.Parameter, "--resource-group",
TokenClassification.None, " MyResourceGroup ")),

_.Alt_a, CheckThat(() => AssertScreenIs(1,
TokenClassification.Command, "az",
TokenClassification.None, " webapp ",
TokenClassification.Parameter, "--name",
TokenClassification.None, ' ',
TokenClassification.Selection, "MyWebApp",
TokenClassification.None, ' ',
TokenClassification.Parameter, "--resource-group",
TokenClassification.None, " MyResourceGroup ")),

_.Alt_a, CheckThat(() => AssertScreenIs(1,
TokenClassification.Command, "az",
TokenClassification.None, " webapp ",
TokenClassification.Parameter, "--name",
TokenClassification.None, " MyWebApp ",
TokenClassification.Parameter, "--resource-group",
TokenClassification.None, ' ',
TokenClassification.Selection, "MyResourceGroup")),

// Verify that we can loop through the arguments.
_.Alt_a, CheckThat(() => AssertScreenIs(1,
TokenClassification.Command, "az",
TokenClassification.None, ' ',
TokenClassification.Selection, "webapp",
TokenClassification.None, ' ',
TokenClassification.Parameter, "--name",
TokenClassification.None, " MyWebApp ",
TokenClassification.Parameter, "--resource-group",
TokenClassification.None, " MyResourceGroup ")),

_.Escape));
}

[SkippableFact]
public void SelectCommandArgument_HereStringArgs()
{
Expand Down