Add to Technorati Favorites
Welcome to ThePowerShellGuy.com Sign in | Join | Help

PowerTab 0.93 PowerShell Tab Expansion scripts library

PowerTab 0.93 is released

PowerTab093.Zip Download  or get it from the Overview Page !

If you are using PowerTab  for the first time with this version , as there is a lot of functionality added to the standard tab completion in PowerShell to make best use of it, be sure to check out the rest of the series !,

For more information about the PowerTab suite see the PowerTab Overview Page where you allways can find the latest version for download, or you can use the TagList PowerTab to get a list of all former posts about the PowerTab library.

* Upgraders note * , from version 0.92 you can just replace the files  :

 

and a lengthy Excuse for posting this version ;-)

Just when I, just as Jeffrey Snover  at a former stage in the PowerTab evolution , did think the PowerTab library was getting at feature complete level. I thought the main tab expansion functionality coverage of PowerTab was becoming pretty complete, my feature wish and idea  list was mostly empty,  and hence I expected not much more big functionality changes soon.

A lot of new functionality was added to the PowerTab library lately , hence the code is in need of a good cleaning up and I have a lot of re-factoring to-do's on my list for the next version to make the code more clear and improve the performance. I mostly focused on the features lately and the development method I use for the PowerTab library is primary "Dog Fooding" .I run the latest version on my laptop and all my work and home computers. To make changes I basically edit the running version of PowerTab on-the-fly while working with it for small changes. If the change to much work for a direct fix or needs to be refined I implement or complete it later when I get the chance. I do this independent of which computer I'm using at that moment and I keep the versions on the other machines in sync on every change I make by updating the scripts first next time I use them.

History of PowerTab

The possibility to customize Tab Expansion in PowerShell was added in Monad Beta 2 ( see  The new TabExpansion feature... on the PowerShell team blog ). I made my first addition to the Tab Expansion function a short time later when I added Tab-completion for static methods and properties on .NET types ( see : PowerShell Tab Completion  on my old blog.) This was my first customization to this function  and over the last year, this first simple addition to the standard TabExpansion function, has grown into the current Powertab library.

I use my own TabExpansion function exclusively for over a year now, it was under constant development often patched and changed on the fly using notepad and copying blocks of code. This way of development works great for prototyping and self use (my-ware) but it also tends make a mess of the Code over time, and the PowerTab library could use some cleaning at the moment.

So I planned a refactoring round as the first planned action for the next version of PowerTab , the functionality added and usage scenarios covered by PowerTab did grow fast and are getting so massive, hence it can take a while for a user to find all the functionality it offers and to get most out the the PowerTab library, so I'm working on a quick-sheet and more usage examples also

The library scripts are also very basic, I added most of this library scripts more as an examples and starting point for learning about the workings of PowerTab and how to tune exactly to your needs by customizing the Tab Expansion library. but most functions are very simple only a couple of lines and good for learning this way this was not very high on my list.

Added Functionality

But it went a bit different, when I started with Microsoft Solution Accelerator for Business Desktop Deployment 2007 from PowerShell

 see also :PowerTab 0.93 and BDD 2007 teaser and PowerTab 0.93 and BDD 2007 teaser Part 2 

I did find an area I did not cover in PowerTab 0.93 , Tab Completion on static Methods and Properties where not supported yet.

Then , when I did work with BDD, PowerShell and script a colleague wrote, I found some other scenarios I did not cover yet with PowerTab 0.92, and I got errors loading the BDD types into that TabExpansion  database so instead of cleaning up, I added more functionality in a quick-and-Dirty fashion.

But as I resolved the error ( not sure if it really was a bug in PowerTab or in the BDD assembly, as this is the first time a had this problem with adding types from the assembly of a external managed DLL loaded into PowerShell ) and to enable PowerShell users interested in working with BDD to try the examples for them self , after the teaser and the Ben Hunter I could not wait till I had time to clean it up so I posted my own current version as 0.93. As the needed changes are more cosmetic I do not have the time to do the cleaning soon and I think that the added value for 0.93 is enough to an upgrade, so here it is

But it's a promise, I will do some cleaning work for next version, Updates for version 0.93

Expansion of variables to text

when loading the DLL I wanted to "walk" to the DLL using tabcompletion but as I used a environment variable to "find" the program files directory I could not use tabcompletion so I decided to fix this.

In 0.92 I added already some shortcuts like this to for example resolve the $profile Path on \[tab] , but I think most people will not even know about them and I do not think I even mentioned them as a feature when I did add them but I like them a lot :

#'.*\$PsHome.*' {$matches[0] -replace '\$PsHome',$pshome}

Now I wanted this functionality for a environment variable ( in this case $env:ProgramFiles ) As a lot but not all environment variables contain a Path, I did not want more hard coded shortcuts

So to keep it simple I decided to use the \ and then TAB to enable expansion of ALL variables to there text version"ToString()" and used this RegEx for it :

'.*(\$+*)\\$'

I did think before I added it that it might give other unwanted side-effects, but till now it seems to work ok, I'm not sure if it is a function the general PowerTab user will use much or will be excited about, but for me for me this functionality is very useful works great and I do really like it !

Keeping the variable is better for use in a script but this resolving is great for interactive use when creating a path, or this method can be used to generate the complete path to generate the script line interactive like this and then we can add the variable again to the script later.

In the Flash example here : PowerTab 0.93 and BDD 2007 teaser you can see this in action and how great it fits in with the other PowerTab functions used to almost completely create the following line by using PowerTab TabExpansion typing only a few letters and [TAB].

[System.Reflection.Assembly]::LoadFile("$env:ProgramFiles\BDD 2007\bin\Microsoft.BDD.ConfigManager.dll")

 

Error on loading TypeInfo of the BDD assembly

When loading the types into PowerTab 0.92 after importing the DDL  using Update-TabExpansionTypes, I got an error like in the example below (using the new function Get-Assembly I made while this troubleshooting this error and added it to the PowerTab 0.93 library 

 

PoSH> Get-Assembly bdd                                                                              
                                                                                                    
GAC    Version        Location                                                                      
---    -------        --------                                                                      
False  v2.0.50727     F:\Program Files\BDD 2007\bin\Microsoft.BDD.ConfigManager.dll                 
                                                                                                    
                                                                                                    
PoSH> (Get-Assembly bdd).GetTypes()                                                                 
Exception calling "GetTypes" with "0" argument(s): "Unable to load one or more of the requested typ 
es. Retrieve the LoaderExceptions property for more information."                                   
At line:1 char:28                                                                                   
+ (Get-Assembly bdd).GetTypes( <<<< )                                                               
PoSH> (Get-Assembly bdd).GetExportedTypes() | select -First 5                                       
                                                                                                    
IsPublic IsSerial Name                                     BaseType                                 
-------- -------- ----                                     --------                                 
True     False    PEManager                                System.Object                            
False    True     PEVersionEnum                            System.Enum                              
False    True     ComponentEnum                            System.Enum                              
False    True     StatusDelegate                           System.MulticastDelegate                 
False    False    StatusEventArgs                          System.EventArgs                         
                                                                                                    
                                                                                                    
PoSH>                                                               

 Using PowerTab tabcompletion I found the GetExportedTypes() method so I tried to use that method instead and it did work

I changed GetTypes() into GetExportedTypes() also for the Update-TabExpansionTypes function so now all types get loaded this way I did not encounter this error before but for safety I changed it also as for powershell usage this might method might be better anyway (accessibility namespace gone for example )

So this was an easy fix again, but as the update-TabExpansionTypes does clear the types database first, and then does fill it again with the types of all the assembly's loaded in PowerShell at that moment, this is not always what you want as the database  can contain types from assemblies that you added already and do not want to lose but that are not loaded in the current session.

 

Added Add-TabExpansionTypes function to add single Assembly to Tabcompletion

 

I noticed this already in version 0.8, but as I provided the Lib as examples to get users started ,I never updated it in the library as I did hope this would be a trigger for users to take a look a the scripts in the Library and to extend them, meanwhile learning about the workings and how to adapt the library. 

I do use a couple of different TabExpansion Databases myself that I edited and that are tuned for different tasks, and after loading new types I merge in the new information myself also as the Tab Expansion database is not saved by default, the update-TabExpansion function will only affect the current session and as long as you do not run the Export-TabExpansion function the database on disk will not change so when you only need the extra type information and do not have the need to add the loaded namespaces to tabcompletion permanently, doing the complete refresh of the types database doesn't matter as you can only use the loaded assemblies anyway.  

 for the same reason I never added much parameters to the helper functions in the library, in spite of the fact that there are a lot of places where this would be easy and add much value, to keep the scripts as simple as possible.

but while troubleshooting the bug with reading the types from the BDD Assembly, Hence I quickly adapted the update-TabExpansion function to handle only one assembly, and created an Add-TabExpansionTypes function that provides a way to select a single Assembly and to add only that single assembly to the Tab Expansion database without a complete refresh of the current content.

As I  made it anyway, for version 0.93 I also added the Add-TabExpansionTypes function to the script library, as it is created by copying the Update-Tabexpansion function, by just removing the loop and unneeded code till I had a working version for only one assembly it is very ugly code and still does a lot unneeded work, as the whole database is checked for namespaces without types, using a very ineffective method that I needed to change anyway, I made a much better way, but the current method was a quick fix I did make as I did not have the code handy and was in need of a quick fix, I did forget the specifics of what I did make before so I made a quick "anything that works", as while loading all Assemblies this was only a small part of the time used I never came to replacing it, but on the BDD Assembly only it is taking 90 % of the time that the script needs to run.

Still this is not a problem for PowerTab usage as it is not used that often, the extra time does not matter that much, but I will make a decent version for next version

Also I added the get-Assembly function I made in the Troubleshooting process to the library, that can be used to list loaded assemblies and to get a reference to the Assembly needed.

 

Expansion of methods and properties of static methods or properties

 

In PowerTab version 0.92 the variable method and property expansion was already multilevel but it did not work on static properties and methods that had properties and methods again themselves, I added tabcompletion for static methods but you could not use this multilevel, in the example of BDD to use tab completion on the OSManager object we needed to put it into a variable first

[Microsoft.BDD.ConfigManager.Manager]::OSManager
$osm = [Microsoft.BDD.ConfigManager.Manager]::OSManager

But now in PowerTab version 0.93 we can use tabcompletion again on the static property or method, and after that again multilevel as with a variable

[Microsoft.BDD.ConfigManager.Manager]::OSManager.GetDataTable()

[Microsoft.BDD.ConfigManager.Manager]::OSManager.GetDataTable().WriteXml('os.xml')

Also this did not work as you put the type itself into a variable, static Properties and methods where not supported on variables, I added this also (again quick and dirty by copying the complete code of the "normal" static method handler and then I just changed the regex.) 

Now we can do things like this :

$bdd = [Microsoft.BDD.ConfigManager.Manager]
$bdd::OSManager

$bdd::OSManager.GetDataTable()

As I would never do this like this myself (I would start with object returned by the static method or property as I did in the first example with the OSmanager static property storing the Osmanager object in the $osm variable)

I did this to be complete in coverage, and make it possible for users that like this way of storing the type in a variable , to still use PowerTab tab completion.

call gettype if :: is used on object to get the type first

While testing I found that static completion on variables also can be confusing if you use it on a variable that does not contain a type but an object, you will get tabcompletion on the static members of the type but this will not work

PoSH> [string]::Join('',(1,2,3))
123
PoSH> $s = "123"
PoSH> $s::Join('',(1,2,3))
Method invocation failed because [System.String] doesn't contain a method named 'Join'.
At line:1 char:9
+ $s::Join( <<<< '',(1,2,3))
PoSH> $s = [string]
PoSH> $s::Join('',(1,2,3))
123

As static members need to be called on the type not on the object, the next line will work :

PoSH> $s.GetType()::Join('',(1,2,3))
123

that got me thinking and instead of just disabling the tabcompletion if the variable does not contain a type the getType() method is added to the completion so if the variable does not contain a type PowerTab will add the GetType automaticly, providing a shortcut to get to the type, if you do not like it you can change the if statement to return, and it will just not complete if it's not a type.

A Flash movie showing a good example of using PowerTab 0.93 with the  Microsoft Solution Accelerator for Business Desktop Deployment 2007 managed DLL, to list all of the Operating Systems in BDD 2007  you can find here : PowerTab 0.93 and BDD 2007 teaser Part 2

 

Enjoy,

Greetings /\/\o\/\/

Published Thursday, June 14, 2007 1:34 PM by MoW

Comments

# BDD 2007 - BDD and PowerTab - Be teased no more!

I am sure that many of you a very keen to use the functionality demonstrated in the PowerShell Guy's

Thursday, June 14, 2007 7:42 PM by Ben Hunter

# re: PowerTab 0.93 PowerShell Tab Expansion scripts library

I love PowerTab, and I have been using it for quite a while.  Since version .92, however, I am having a problem.  My TabExpansion database doesn't appear to be imported when I start a new shell.  If I call Get-TabExpansion, I get this error:

You cannot call a method on a null-valued expression.

At <blah blah blah>\TabExpansionLib.ps1:159 char:43

+       $dsTabExpansion.Tables[$Type].select( <<<< "Filter LIKE '$Filter'")

Out-ConsoleList doesn't get invoked at all for Cmdlets and functions, and functions defined in  dot-sourced scripts, including the PowerTab scripts, are not included.  It appears to work for Cmdlet parameters but not script parameters.  In order to get everything back, I have to run PowerShellSetup.ps1 again.  Any idea what the problem is?

Friday, June 15, 2007 1:04 AM by Jeff

# re: PowerTab 0.93 PowerShell Tab Expansion scripts library

Excellent tool!

Friday, June 15, 2007 1:34 AM by Michael Niehaus

# re: PowerTab 0.93 PowerShell Tab Expansion scripts library

I love PowerTab, and I have been using it for quite a while.  Since version .92, however, I am having a problem.  My TabExpansion database doesn't appear to be imported when I start a new shell.  If I call Get-TabExpansion, I get this error:

You cannot call a method on a null-valued expression.

At <blah blah blah>\TabExpansionLib.ps1:159 char:43

+       $dsTabExpansion.Tables[$Type].select( <<<< "Filter LIKE '$Filter'")

Out-ConsoleList doesn't get invoked at all for Cmdlets and functions, and functions defined in  dot-sourced scripts, including the PowerTab scripts, are not included.  It appears to work for Cmdlet parameters but not script parameters.  In order to get everything back, I have to run PowerShellSetup.ps1 again.  Any idea what the problem is?

Friday, June 15, 2007 2:34 AM by Jeff

# re: PowerTab 0.93 PowerShell Tab Expansion scripts library

on line 134, should "if ($answer) {Export-TabExpansion}" actually be "if ($answer) {Export-TabExpansionDatabase}"?

It should be in the default install of PowerShell.

Keep up the good work on PowerTab.

Friday, June 15, 2007 3:08 AM by MarcoR

# The PowerShell Guy : PowerTab

Friday, June 15, 2007 5:58 AM by The PowerShell Guy : PowerTab

# re: PowerTab 0.93 PowerShell Tab Expansion scripts library

@ Jeff,

you can save the database, by running export-TabExpansionDataBase

Greetings /\/\o\/\/

Friday, June 15, 2007 6:06 AM by MoW

# re: PowerTab 0.93 PowerShell Tab Expansion scripts library

@ MarcoR and Jeff, :

Argg, I re-introduced that bug from the 0.92 version again.

Updated the download

Greetings /\/\o\/\/

Friday, June 15, 2007 6:10 AM by MoW

# re: PowerTab 0.93 PowerShell Tab Expansion scripts library

I got the updated download, but I am still having the same problems, both at work(XP SP2) and at home(Vista Ultimate).  TabExpansion.xml looks just fine, but Load-TabExpansionDatabase doesn't seem to be working like it should; I have tried calling it directly, but I get the same error when I call Get-TabExpansion.  The Out-ConsoleList handler is still only coming up for Cmdlet parameters, and dot-sourced script functions are still not in the list at all.

Friday, June 15, 2007 8:50 AM by Jeff

# re: PowerTab 0.93 PowerShell Tab Expansion scripts library

Jeff, did you have an old version installed before ? as Load-TabExpansion is replaced by Import-TabExpansionDatabase in version 0.92

I can find no references anymore to load-Tabexpansion in my version here.

if you used an old version remove it from profile and let the setup update the profile again.

Greetings /\/\o\/\/

Friday, June 15, 2007 10:48 AM by MoW

# re: PowerTab 0.93 PowerShell Tab Expansion scripts library

I have been using this since 0.7. It is without question what makes PowerShell the ultimate tool for me.

In your comments you mentioned that you had hoped users would get interested in the library and learn and extend- Well it worked for me. I have drawn on this and many other examples in your blog extensively in my learning to use PowerShell productively.

I have been adding a section for some time to use with svn repos (and sometimes IE) where if it's a valid path and ends in = (I just picked something not in use at the time) it creates a new Uri and returns the AbsoluteUri. This is much nicer than changing all the \ to / etc. So C:\abc\def\myfile.htm becomes file:///C:/abc/def/myfile.htm

You have a great Blog. Thanks for all the time you spend teaching others.

Regards,

-Alan

Friday, June 15, 2007 4:04 PM by Alan

# re: PowerTab 0.93 PowerShell Tab Expansion scripts library

Alan,

Great to hear about your experiences !

Thanks for sharing them

Greetings /\/\o\/\/

Saturday, June 16, 2007 10:34 AM by MoW

# re: PowerTab 0.93 PowerShell Tab Expansion scripts library

I actually meant to say "Import-TabExpansionDatabase" in that last comment; it is the function I was calling.  I'm not sure how this happened on both my home and work machines, but I somehow had an old copy of PowerShellSetup.ps1; all the other files were new.  Once I updated it with the new one, everything was good again.  Thanks for your help with this.

Sunday, June 17, 2007 10:05 PM by Jeff

# Tab/Esc/Tab bug

Firstly, great tool, MoW, I use it all the time and love it! :-)

A little bug:

1. Type Get-[Tab]

2. Hit [Esc] to dismiss the list

3. Hit [Tab] again. Nothing happens

Thank you, / Alex

Tuesday, June 19, 2007 1:52 PM by Alex

# re: PowerTab 0.93 PowerShell Tab Expansion scripts library

Hi Alex,

thanks for your reaction

about the not expanding for the socond time on the same text.

this is actualy not a bug in PowerTab but a "feature" of powershell, you haver to change at least one character to invoke Tabcompletion again, so PowerTab will not get invoked at all in this case.

if you try this without Powertab loaded you will see the same behavour only with PowerTab you notice it more.

Greetings /\/\o\/\/

Wednesday, June 20, 2007 5:41 AM by MoW

# PowerTab 0.95 teaser

As promised in the entry PowerTab 0.93 PowerShell Tab Expansion scripts library , I'm working on a new

Thursday, July 12, 2007 2:17 PM by The PowerShell Guy

# Dinah Benita Talks &raquo; Blog Archive &raquo; BDD 2007 - BDD and PowerTab - Be teased no more!

# Ring Gideon Talks &raquo; Blog Archive &raquo; BDD 2007 - BDD and PowerTab - Be teased no more!

# re: error on adding single assembly

Trying to load some of the framework 3.5 assemblies, I tried to load "system.core" but got the error:

You cannot call a method on a null-valued expression.

At TabExpansionLib.ps1:147 char:83

+     $nl |% {[void]$global:dsTabExpansion.tables['Types'].rows.add("Dummy",$_.split( <<<< '.').count ,$_)}

Any idea?

Thanks

Tuesday, April 08, 2008 7:16 AM by domdomz
Anonymous comments are disabled