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}
Invoke-Foo, hit Enter, and then want PowerShell to executeInvoke-Fooin such a way that the existing line becomesInvoke-Foo foo? What should happen if you hit Enter again -- do you getInvoke-Foo foo foo? It seems like a convoluted way to do custom argument completion, for which there are better solutions.Invoke-Foo, PS executes it (which will call fzf.exe underneath allowing to select a directory or file) and the existing line becomes just the selected file/dir, so I can edit it further (e.g. insert 'cd' or 'cat' in front of it). So yes I could just use a function likeInvoke-Foo -Command { cd $_ }, but since I saw Ctrl-R or any other PSReadLine keyhandler basically does what I want (edit commandline in-place) I thought maybe there's a way to have a function do that as well.Copy-Item Invoke-Foo Invoke-Foowork would require altering the parser.