Context sensitive auto-completion using PowerShell, PowerTab and GIT

Posted on October 13, 2008. Filed under: GIT, powershell, ruby, vista, windows |

Powertab is an Awesome PowerShell TabExpansion extension. It extends the default PowerShell autocompletion and shows the results like:

image

The best part is that it is easily customizable.

One way to customize it is by editing it Tab Expansion database file which is located in your powershell profile directory:

TabExpansion.xml

To display some simple git commands in autocompletion all the following entries to it:

   1: <Custom>
   2:   <Filter>git</Filter>
   3:   <Text>status</Text>
   4:   <Type>Custom</Type>
   5: </Custom>
   6: <Custom>
   7:   <Filter>git</Filter>
   8:   <Text>add .</Text>
   9:   <Type>Custom</Type>
  10: </Custom>
  11: <Custom>
  12:   <Filter>git</Filter>
  13:   <Text>pull</Text>
  14:   <Type>Custom</Type>
  15: </Custom>
  16: <Custom>
  17:   <Filter>git</Filter>
  18:   <Text>push</Text>
  19:   <Type>Custom</Type>
  20: </Custom>
  21: <Custom>
  22:   <Filter>git</Filter>
  23:   <Text>commit -m ""</Text>
  24:   <Type>Custom</Type>
  25: </Custom>
  26: <Custom>
  27:   <Filter>git</Filter>
  28:   <Text>commit -a -m ""</Text>
  29:   <Type>Custom</Type>
  30: </Custom>

To invoke this list add the following to TabExpansion.ps1 file which should be in the source directory:

   1: 'git(.*)' {
   2:   if(Test-Path .git) {
   3:     $global:dsTabExpansion.Tables['Custom'].select("filter = 'git' AND type = 'Custom'") | % {$_.text} | Invoke-TabItemSelector  -SelectionHandler $SelectionHandler
   4:   }
   5: }

This should be added in the Main tabcompletion block inside the switch statement. The function is basically matching the current command name with git and then invoking autocompletion.

Now when you type git<tab> then the output should look like below:

image

I am sure this is not the best way to do custom autocompletion but i couldn’t find an easier way.

This is all static stuff. To add dynamic autocompletion (like providing branch names) add following to the TabExpansion.ps1 file:

   1: 'git(.*)' {
   2:   if(Test-Path .git) {
   3:     # git checkout
   4:     if($lastBlock -match 'git checkout'){
   5:       git branch | %{ if($_ -match "^\*?\s*(.*)"){ $matches[1] } } | Invoke-TabItemSelector  -SelectionHandler $SelectionHandler
   6:     }
   7:     else{
   8:       $global:dsTabExpansion.Tables['Custom'].select("filter = 'git' AND type = 'Custom'") | % {$_.text} | Invoke-TabItemSelector  -SelectionHandler $SelectionHandler
   9:     }
  10:   }
  11: }

Now when you type git checkout <tab> then it should show the following in the autocomplete list:

image

This function checks if the user has entered git checkout as the command then it runs the git branch command, parses it and shows the result as autocomplete list.

Here are couple more commands that I wrote while trying this out:

   1: 'git(.*)' {
   2:   if(Test-Path .git) {
   3:     # git checkout
   4:     if($lastBlock -match 'git checkout'){
   5:       git branch | %{ if($_ -match "^\*?\s*(.*)"){ $matches[1] } } | Invoke-TabItemSelector  -SelectionHandler $SelectionHandler
   6:     }
   7:     
   8:     # git add
   9:     Elseif($lastBlock -match 'git add'){
  10:       $s = $False ; git status | %{ if($s -eq $True -and $_ -match "^#\s{1,1}(\S.+)$"){ $matches[1] } ElseIf($_ -match 'Untracked files:'){ $s = $True } } | Invoke-TabItemSelector  -SelectionHandler $SelectionHandler
  11:     }
  12:     
  13:     # git rm
  14:     Elseif($lastBlock -match 'git rm'){
  15:       git status | %{ if($_ -match "^#\s+deleted:\s+(\S.+)$"){ $matches[1] } } | Invoke-TabItemSelector  -SelectionHandler $SelectionHandler
  16:     }
  17:     
  18:     else{
  19:       $global:dsTabExpansion.Tables['Custom'].select("filter = 'git' AND type = 'Custom'") | % {$_.text} | Invoke-TabItemSelector  -SelectionHandler $SelectionHandler
  20:     }
  21:   }
  22: }

These will autocomplete parameters for git add and git rm commands by running the git status command and parsing the output.

For example:

image

 

I think a lot more interesting stuff can be created using PowerTab and GIT.

 

Update 1:

Turns out as pointed by MOW that there is a much easier way to add custom expansions instead of editing the TabExpansion.xml file.

Just run this command inside PowerShell:

Invoke-TabExpansionEditor

It will open up a dialog box like:

image

Here custom items can be added by clicking the Custom link and then the database change can by saved by running the command:

Export-tabExpansionDataBase

Make a Comment

Leave a comment

5 Responses to “Context sensitive auto-completion using PowerShell, PowerTab and GIT”

RSS Feed for Blogging on Technology Comments RSS Feed

Great stuff !

a tip, try

Invoke-TabExpansionEditor

and see if you like that better to change the database.

Enjoy,
Greetings /\/\o\/\/

PS. another thing I noted

you can use custom additions to Powertab Without editing the source by using ^[tab] behind the filter

e.g.

git^[tab]

you can change this shortcut here :

$PowerTabConfig.ShortcutChars

CustomFunction : #
Invoke : &
Custom : ^
Alias : @
Partial : %
Native : !

Greetings again,
/\/\o\/\/

Thanks for the Tips MOW.
I will surely try out Invoke-TabExpansionEditor and update this post.

Yes I noticed that you can add custom auto-completion using the ^ character. But that is one extra character to type. I will look for a cleaner way to add this functionality.

Great creative idea. I took your GIT post and did it for Subversion.

http://dougfinke.com/blog/?p=488

Looks like I need to copy you again 🙂

@Doug: I will be looking forward to your post again 🙂


Where's The Comment Form?

Liked it here?
Why not try sites on the blogroll...