Bash-like Tab Completion in PowerShell
Thursday, 13 September 2012
When PowerShell first came on the scene, Unix folks were among the first to notice. They’d enjoyed a powerful shell and a vigorous heritage of automation for years – and “when I’m forced to use Windows, PowerShell rocks” was a phrase we heard many times.
This natural uptake was no mistake. There are many on the team that come from a deep Unix background, and similarities to traditional Unix shells were no mistake.
When coming from a Unix background, through, we still hear the occasional grumble that tab completion feels weird. Ctrl-R doesn’t invoke history search? Tab cycles through matches, rather than list them? Abhorrent!
In PowerShell V1 and V2, there was nothing you could reasonably do to address this. PowerShell reads its input from the console in what is known as “Cooked Mode” – where the Windows Console subsystem handles all the keypresses, fancy F7 menus, and more. When you press ENTER or TAB, PowerShell got the text of what you had typed so far, but that’s it. There was no way to know that you had pressed Ctrl-R, Ctrl-A, Ctrl-E, etc.
We resolved this issue in PowerShell version three. Windows does, of course, offer a “Raw Mode” for user input. While we wouldn’t want to replace PowerShell’s default ReadLine() implementation with that of Bash, some enterprising soul might want to. To support this, we introduced the PSConsoleHostReadLine function in PowerShell version three. If this function exists, we call that instead of the Cooked Mode ReadLine(). And that’s it – the rest is up to you.
It turns out that some enterprising soul does exist, and he’s in fact one of our MVPs: Oisin Grehan. By building on the ReadLine() implementation in Mono, he’s developed a module that offers Bash-style line editing in PowerShell.