Author Posts

February 6, 2018 at 1:35 am

If you are like me, having heavy background in Windows and Linux prior to Powershell coming about. You have probably worn out your backspace key as much as I have after pressing the TAB key and having it autocomplete to the first FULL match.

Unlike the bash shell, which autocompletes up to the next unique character, allowing you to press a single (or a few) keys and continue your autocomplete adventure.

I recently started in a position where I am doing a great deal of tool making, Don said that is where we should live, and usage of autocomplete was important for me.

Most of us who are building Powershell modules are following a similar naming convention as a great deal of the major tool builders are.

Verb-{myModuleId}Noun

My example would be a module named "ThunderCat", might have a myModuleId of Thndr, and commands such as:

Get-ThndrHost
Get-ThndrHostStatus
Get-ThndrLockedServers
Remove-ThndrTempDirectoryFiles
Remove-ThndrLockFile

The names don't really matter too much here, you get the idea.

So, when I type Remove-Thndr{tab} I'm going to get Remove-ThndrLockFile, and if I really wanted the Remove-ThndrTempDirectoryFiles, and there was 20 other Remove-ThndrL* named functions, I either have to backspace, or tab a bunch more times. My solution is fairly simple. Create functions with names where you want the autocomplete to stop at.

[PRE]
Function Remove-Thndr
{
[CmdletBinding()]
Param
(
)

Begin { }
Process{ }
End
{
Get-Command -Module ThunderCat | Where-Object { $_.Name.StartsWith("Remove-Thndr") }
}
}
[/PRE]

Now if you type Remove-Thn{tab} the interface stops at Remove-Thndr and allows you to type the "T" and press tab again to autocomplete to the function that you want.

It isn't perfect and takes a little extra planning if you want to create multiple stop points for sections of similarly named functions where the names get quite long. It saves me some frustration, so I figured I would share.

Of course, if you accidentally press enter at one of these autocomplete stubs, it is nice for it to spit out the commands that match from the point you are currently at.

Hope you are all enjoying life with Powershell...

~cj

February 6, 2018 at 9:18 pm

Shamelessly stolen from Stack Overflow. I had no idea this was a thing.

Set-PSReadlineKeyHandler -Key Tab -Function Complete

or

Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete

February 7, 2018 at 12:54 am

I had not run across Set-PSReadlineKeyHandler previously, and as much as I learn from Stack Overflow. I had not even bothered to search for a solution since I already had a method in mind. If Set-PSReadlineKeyHandler can work the same way as I've setup my modules, I obviously wouldn't go through the time to plan them out this way. Let alone post about it.

Think what you like though, free country.

~cj

February 11, 2018 at 5:00 am

I've given a go using the two options you presented. And while it is a huge step forward, it still isn't quite what I was looking for. Oddly enough, in the Mac version of Powershell, tab completion behaves exactly the same as it does in bash.

The menu popup is alright, though it still brings you fully to the first match on your command line, and you need take an action other than simply typing another character and pressing TAB.

Under a standard powershell window:
For instance, I typed Get-ADC{tab}
PS C:\Users\Christopher.Maahs> Get-ADCentralAccessPolicy
Get-ADCentralAccessPolicy Get-ADClaimTransformPolicy Get-ADComputer
Get-ADCentralAccessRule Get-ADClaimType Get-ADComputerServiceAccount

And as you can see my command line now expanded to the entire first command on the list. While I can now arrow around, I cannot simply use the next key and press tab again.

And in ISE, the experience is much better and very close to what I was looking for. The on the fly filter is quite useful, much like the parameters with validation sets.

I'll likely still plan out my functions in a way that allows me to quickly shortcut my way through using basic tab completion like I do in bash.