diff --git a/PSReadLine/SamplePSReadLineProfile.ps1 b/PSReadLine/SamplePSReadLineProfile.ps1 index 9183224f..8ccb8c1e 100644 --- a/PSReadLine/SamplePSReadLineProfile.ps1 +++ b/PSReadLine/SamplePSReadLineProfile.ps1 @@ -600,3 +600,59 @@ Set-PSReadLineKeyHandler -Key RightArrow ` [Microsoft.PowerShell.PSConsoleReadLine]::AcceptNextSuggestionWord($key, $arg) } } + +# Cycle through arguments on current line and select the text. This makes it easier to quickly change the argument if re-running a previously run command from the history +# or if using a psreadline predictor. You can also use a digit argument to specify which argument you want to select, i.e. Alt+1, Alt+a selects the first argument +# on the command line. +Set-PSReadLineKeyHandler -Key Alt+a ` + -BriefDescription SelectCommandArguments ` + -LongDescription "Set current selection to next command argument in the command line. Use of digit argument selects argument by position" ` + -ScriptBlock { + param($key, $arg) + + $ast = $null + $cursor = $null + [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$ast, [ref]$null, [ref]$null, [ref]$cursor) + + $asts = $ast.FindAll( { + $args[0] -is [System.Management.Automation.Language.ExpressionAst] -and + $args[0].Parent -is [System.Management.Automation.Language.CommandAst] -and + $args[0].Extent.StartOffset -ne $args[0].Parent.Extent.StartOffset + }, $true) + + if ($asts.Count -eq 0) { + [Microsoft.PowerShell.PSConsoleReadLine]::Ding() + return + } + + $nextAst = $null + + if ($null -ne $arg) { + $nextAst = $asts[$arg - 1] + } + else { + foreach ($ast in $asts) { + if ($ast.Extent.StartOffset -ge $cursor) { + $nextAst = $ast + break + } + } + + if ($null -eq $nextAst) { + $nextAst = $asts[0] + } + } + + $startOffsetAdjustment = 0 + $endOffsetAdjustment = 0 + + if ($nextAst -is [System.Management.Automation.Language.StringConstantExpressionAst] -and + $nextAst.StringConstantType -ne [System.Management.Automation.Language.StringConstantType]::BareWord) { + $startOffsetAdjustment = 1 + $endOffsetAdjustment = 2 + } + + [Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($nextAst.Extent.StartOffset + $startOffsetAdjustment) + [Microsoft.PowerShell.PSConsoleReadLine]::SetMark($null, $null) + [Microsoft.PowerShell.PSConsoleReadLine]::SelectForwardChar($null, ($nextAst.Extent.EndOffset - $nextAst.Extent.StartOffset) - $endOffsetAdjustment) +}