diff --git a/PSReadLine/KillYank.cs b/PSReadLine/KillYank.cs
index f05fc8ba0..77fe33f1b 100644
--- a/PSReadLine/KillYank.cs
+++ b/PSReadLine/KillYank.cs
@@ -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
@@ -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);
+
///
/// Mark the current location of the cursor for use in a subsequent editing command.
///
@@ -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,
};
@@ -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)
{
@@ -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;
+ }
}
///
diff --git a/test/KillYankTest.cs b/test/KillYankTest.cs
index 3433f7dab..8705faab6 100644
--- a/test/KillYankTest.cs
+++ b/test/KillYankTest.cs
@@ -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()
{