PowerShell – No Mouse, Search & Activate A Tab In ISE With Partial String Search – e.g.: “Popt register”

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

  1. First let me save off my function Pop-FileInISETab to
    c:\PowerShell\ISE\Pop-FileInISETab.ps1
  2. Dot-source the function
    . c:\PowerShell\ISE\Pop-FileInISETab.ps1
  3. Create an alias
    Pop-FileInISETab 'zzz' -CreateAliasPOPT: $true
  4. 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

ise_open_tabs

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

ise_tab_selected-jpb

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:

ise_choices

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:

  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 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.

Advertisements

One thought on “PowerShell – No Mouse, Search & Activate A Tab In ISE With Partial String Search – e.g.: “Popt register”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s