May, 2017 Update:
Please note that I have switched from ISE to Visual Studio Code a free editor that supports PowerShell with an extension besides a ton of other things. CTRL+P option in VS Code does what is described below very elegantly! Frankly, I like VS Code better than the IDE. Please read on if you still use the ISE.
You can shoot me if you don’t like this!
No, I am kidding about the “shoot me” part đ . However, if you are a hardcore PowerShell developer and you deal with a lot of open tabs in your ISE, wasting half of your workday searching for the correct tab to switch to, in frustration; you will be enthralled with this function – the ultimate weapon of the lazy PoSh dev and those like me, with TSDD (Tab Search Deficit Disorder)!
What is this “ISE – Search and activate”?
This is a function that activates a tab based on a partial search string that you type in the CLI portion of the ISE. Among the numerous tabs you have open in the ISE, to activate a tab that has the word “register”, you would just type in
popt register
That’s it. The tab that has the word “register” will become active.
Why “popt” instead of a standard name?
“popt” is the alias you can create for the real “search and activate function” Pop-FileInISETab. It stands for “poptab”. You don’t want to trade one problem with another by having to type that long name, so, there is functionality to optionally create an alias named “popt” for the function.
The specifics of the matching:
Obviously, there are several combination of factors that determine the nuances.
If FileName is a partial string
Searches all tabs for that string
- (1 match) Activates the if there is exactly one match to a tab
- (0 matches) Writes a warning and quits if there are no matches
- (>1 match) Prompts to input a tab to activate from a list of matches
If FileName is a fully qualified path
- Opens the file in a new tab if not already open
- Activates the tab if file is already open
Walkthrough
- First let me save off my function Pop-FileInISETab to
c:\PowerShell\ISE\Pop-FileInISETab.ps1
- Dot-source the function
. c:\PowerShell\ISE\Pop-FileInISETab.ps1
- Create an alias
Pop-FileInISETab 'zzz' -CreateAliasPOPT: $true
- Now, we are all set to use it!
Let us say I have this insane amount of tabs open. Although this is crazy, I have to admit that I have at least 4 lines of tabs open during my active development
For the screenshot above, I have opened all the functions from DBATools available at https://dbatools.io/Â (Thanks to @CL and the team)
Activate tab that has the word “alert” – Exact match
Now, to activate a tab that I know has the word “alert”, in the CLI portion of the ISE, I would just say:
popt alert
TIP: BTW, you could use CTRL+I and CTRL+D to switch between the code and the blue CLI within the ISE.
Since there was only one file with the word “alert” in it, it got activated as expected
Activate tab that has the word “test” – More than 1 match
In this case, since “test” is a more commonly used verb, there are multiple matches, so “popt” prompts you to choose the right one:
As soon as I type in 10 for example, the corresponding file gets activated. If I type in invalid values, it keeps prompting over and over (CTRL+C to break).
Open and activate a new file with full path:
I could also open and activate a brand-new file on an already open file using the full path
popt c:\Apps\dbatools-master\functions\Copy-SqlAlert.ps1
You should really add this to your profile:
To make this functionality available as soon as you open ISE, you should add this to your PowerShell profile. Here are the steps:
- Edit your profile
Notepad $Profile - Dot source this function from the file
. c:\PowerShell\Functions\Pop-FileInISETab.ps1 - Optionally create an alias by including
Pop-FileInISETab ‘zzz’ -CreateAliasPOPT: $true
SHOW ME THE CODE ALREADY!!
I know that hardcore PowerShell folks don’t read the explanations or text! They just read straight code that is self-describing đ .
Note: Code comments are separate from the code because WordPress messesup the signs used in the comment block..Until I pin-down the issue, they are here as separate blocks just so that code does not get messed up.
<# .SYNOPSIS Pops the tab containing the partial string passed in. Opens file if string is a valid full path file .DESCRIPTION When you have too many tabs open in the ISE, it is hard to locate the tab you need to get to. You roughly know the name but enough to waste precious seconds hunting. Now you can just "Pop" the tab by using this function * If FileName is a partial string, searches all tabs for that string * - (1 match) Activates the if there is exactly one match to a tab * - (0 matches) Writes a warning and quits if there are no matches * - (>1 match) Prompts to input a tab to activate from a list * If FileName is a fully qualified path * - Opens the file in a new tab if not already open * - Activates the tab if file is already open Optionally you can create an alias for this named "popt" by using the switch CreateAliasPOPT .INPUTS FileName - Partial or full file name with path CreateAliasPOPT - $true/$false to create or not create an alias named "popt" for this function .OUTPUTS None. The right ISE tab gets activated .EXAMPLE #Let us say you have a lot of tabs..and one or more having the string "Target" # You can activate the tab by saying Pop-FileInISETab target .EXAMPLE #The same as previous example but also create an alias name "popt" for the function Pop-FileInISETab target -CreateAliasPOPT: $true .EXAMPLE #Simplified call..but same functionality as before popt target .EXAMPLE #Adding this to your PowerShell profile #1) Edit your profile Notepad $Profile #2) Dot source this function from the file . c:\PowerShell\Functions\Pop-FileInISETab.ps1 #3) Optionally create an alias by running Pop-FileInISETab 'zzz' -CreateAliasPOPT: $true .NOTES Created this out of frustration by not being able to locate files in the ISE! Version History v1.0 - Jana Sattainathan [Twitter: @SQLJana] [Blog: sqljana.wordpress.com] .LINK N/A #>
#The actual code without the comments is below. Please combine with the comments from above.
function Pop-FileInISETab { [CmdletBinding()] param ( [Parameter(Mandatory=$true, Position=1)] [string] $FileName, [Parameter(Mandatory=$false, Position=2)] [switch] $CreateAliasPOPT = $false ) [string] $fn = $MyInvocation.MyCommand [string] $stepName = "Begin [$fn]" [int] $counter = 1 [int] $choice = 0 try { $stepName = "[$fn]: Create alias for this command if asked to" #-------------------------------------------- Write-Verbose $stepName $matches = Get-Alias -Name 'popt' -ErrorAction SilentlyContinue if (-not $matches) { New-Alias -Name 'popt' -Value 'Pop-FileInISETab' -Scope Global -Description 'Use this to Pop ISE tab containing a string to match' } $stepName = "[$fn]: Get the matches" #-------------------------------------------- Write-Verbose $stepName $matches = @( $psISE.CurrentPowerShellTab.Files | Where-Object {$_.DisplayName -like "*$FileName*"} | Sort-Object -Property DisplayName ) switch($matches.Count){ #-------------------------------------------------------- # There are no matches in open tabs for the given file name #-------------------------------------------------------- 0 { $stepName = "[$fn]: No matches. Check if this is a valid file with full path..if so, open it" #-------------------------------------------- Write-Verbose $stepName if (Test-Path $FileName -PathType Leaf) { $stepName = ("[$fn]: Opening file in a new tab for FileName: [{0}]" -f $FileName) #-------------------------------------------- Write-Verbose $stepName $psISE.CurrentPowerShellTab.Files.Add($FileName) | Out-Null } else { Write-Warning ('Please refine your search. No matches were found for FileName: [{0}]' -f $FileName) break } } #-------------------------------------------------------- #There is exactly one match - ideal situation #-------------------------------------------------------- 1 { $stepName = ("[$fn]: Activating tab for FileName: [{0}]" -f $matches[0].DisplayName) #-------------------------------------------- Write-Verbose $stepName $psISE.CurrentPowerShellTab.Files.Add($matches[0].FullPath) | Out-Null break } #-------------------------------------------------------- #There are more than 1 matches. Prompt for which one to activate #-------------------------------------------------------- default{ if ($matches.Count -gt 1) { $stepName = ("[$fn]: Display all the matches with a number") #-------------------------------------------- Write-Verbose $stepName foreach($match in $matches) { "[$(($counter++).ToString())] - $($match.DisplayName)" } "`n[0] - To Exit `n" #Loop till the user makes a valid choice do { $stepName = ("[$fn]: Get input file number from user") #-------------------------------------------- Write-Verbose $stepName $choice = Read-Host -Prompt "Type in the FileNumber to activate (between 0 and $($counter-1))" if (-not (($choice -ge 0) -and ($choice -lt $counter))) { Write-Warning "[$choice] is invalid. Enter a valid value (between 0 and $($counter-1)). To quit, enter 0" } } until (($choice -ge 0) -and ($choice -lt $counter)) # #Activate the file if a good choice was made # if ($choice -eq 0) { Write-Warning 'Quitting tab activation!' } else { $stepName = ("[$fn]: Activating tab for FileName: [{0}]" -f $matches[$choice-1].DisplayName) #-------------------------------------------- Write-Verbose $stepName $psISE.CurrentPowerShellTab.Files.Add($matches[$choice-1].FullPath) | Out-Null } } } } $matches = $null } catch { [Exception]$ex = $_.Exception Write-Error ('Unable to activate tab for give string! Error in step: [{0}] {1}' -f ` $stepName, $ex.Message) } }
Popt Pop !!
If you had the above function (Pop-FileInISETab) open in one of the numerous tabs of your IDE, and it is not the currently selected one, then you could activate it by just saying
popt pop
Yes, that would have activated the tab that has the function Pop-FileInISETab!
Update: 2017-Apr-13 – I find myself using this so much that even typing “popt” is too much, so, I just aliased the function to “p” to use it like “p backup” to search and activate file(s) that have the string “backup” in their name. The section of code you need to change is below
$matches = Get-Alias -Name 'p' -ErrorAction SilentlyContinue if (-not $matches) { New-Alias -Name 'p' -Value 'Pop-FileInISETab' -Scope Global -Description 'Use this to Pop ISE tab containing a string to match' }
Conclusion
I would love to see your comments based on your usage and hear if there are opportunities for improvements. Please post them in the comments section below. I hope you find this function useful.
One thought on “PowerShell – No Mouse, Search & Activate A Tab In ISE With Partial String Search – e.g.: “Popt register””