My goal is to write a function which behaves similarily to what happens when invoking PsReadline's Ctrl-R functionality: insert text on the current command line, but don't accept the line, so that when the function returns the cursor is still on the same line. I tried the following
function Invoke-Foo() {
[Microsoft.PowerShell.PSConsoleReadLine]::Insert('foo')
}
But when calling this, the result is:
PS> Invoke-Foo foo
PS> <cursor position>
What I want instead if that after inserting the text, the cursor stays on that line so
PS> Invoke-Foo foo<cursor position>
I looked into other PSConsoleReadLine functions (as I assume they are the way to go since PsReadline handles the console?) like AddLine/CancelLine/... but none of the combinations do the trick. What does work is calling the function as a PsReadline key handler using Set-PSReadlineKeyHandler -Key 'Ctrl+P' -ScriptBlock {Invoke-Foo}
then hitting Ctrl-P does exactly what I want. So the question is probably: how to hook into PsReadline to mimic a function being called as it's key handler?
update Solution is fairly simple, thanks to Jason for the tip: just bind Enter, and don't accept the line if Invoke-Foo is being called
function DealWithEnterKey() {
$line = $null
$cursor = $null
[Microsoft.PowerShell.PSConsoleReadline]::GetBufferState([ref]$line, [ref]$cursor)
if($line -match 'Invoke-Foo') {
Invoke-Foo
} else {
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
}
}
Set-PSReadlineKeyHandler -Key 'Enter' -ScriptBlock {DealWithEnterKey}
You'll need to either use a custom key handler or simulate keyboard input I think.
I suggest rebinding Enter. If the command line matches your command, run your command and replace the command line. If not, just call the normal handler for Enter.