My Technical Notes

Tuesday, 23 February 2016

Making PowerShell's Select-String's output clickable within Notepad++ and Visual Studio

Abstract

PowerShell's `Select-String` is quite a useful function which has the same purpose as Unix's `grep`, which is to search within files for a string. `Select-String` is overall more flexible and useful than any one editor's in-built search capability. However, after searching for text, we cannot as easily "jump" to a search result as can when using Notepad++'s (or Visual Studio's) "Find in Files" feature.

Below describes a method of using the output of `Select-String` within Notepad++ and Visual Studio, so that each result is clickable and opens the file at the specified line number.

Define Out-Sls PowerShell function

There needs to be an output location for our `Select-String` searches that our external editor will look at. Therefore we define an `Out-Sls` function. All this function does is, write the incoming search results to a text file at `C:\TEMP\sls.txt`, mapping it in a way that Visual Studio can read it and work out the line numbers:


Function Out-Sls {
    $input | ForEach-Object { '{0}({1}): {2}' -f $_.Path, $_.LineNumber, $_.Line } | Set-Content C:\TEMP\sls.txt;
}

If, for example, a large number of results are returned by `Select-String`, we would pipe the results to `Out-Sls`. For example:


dir -r *.txt | sls -simplematch 'john' | out-sls

after which we would view them using Notepad++ or Visual Studio.

(The function name `Out-Sls` and its associated output file location `C:\TEMP\sls.txt` are arbitrary: they could have been anything.)

Viewing Out-Sls'ed output using Notepad++

Install NppExec

Install the NppExec plugin to Notepad++. This can be installed using Plugins → Plugin Manager → Show Plugin Manager.

NppExec allows us to run a command and display its output. NppExec is normally used to invoke a compiler and to show resultant error messages within its own console window. We will, instead, use it to show the output of `Select-String`.

Console Output Filters

Now we configure NppExec to display the contents of `C:\TEMP\sls.txt` within its Console window.

Our `Out-Sls` outputs file and line information in the following format:


    <file-path>(<line-number>):<line-text>
    

For example, this is the search result for `Out-Sls`, using our `Out-Sls`


    C:\Users\TH\My Documents\WindowsPowerShell\Modules\Utils\Utils.psm1(107):Function Out-Sls {
    

Therefore we have to configure NppExec to look for lines of this format to make them clickable.

Go to Plugins → NppExec → Console Output Filters. Add a highlight mask:


    %FILE%(%LINE%):*
    
Outputting sls.txt to Notepad++ NppExec's console

A command is needed to write the contents of `sls.txt` to NppExec's console, in which the file-line-clicking takes place.

Go to Plugins → NppExec → Execute (or press F6), and enter the following command:


    cmd.exe /c type c:\temp\sls.txt
    

and press `OK`. This command invokes the `type` command which outputs the contents of a file to NppExec's Console window. We can now double-click on any line within this window and and it will open within Notepad++ at that line.

To make this whole process faster, in the Execute dialog, after entering a command, we can click `Save` and enter a name `View Select-String Output`, which will add it to the command drop down list.

We can add a menu item for it by going to Advanced Options within Plugins → NppExec. Within Associated Script, we select `View Select-String Output` (it auto-populates the item name), then click on `Add-Modify` and then tick `Place to the Macros submenu`. It will prompt you to restart Notepad++. This gives us two ways of invoking `View Select-String Output`:

  • Press F6, or go to Plugins → NppExec → Execute, and then select the command from the drop down list (it may already be selected) and then press `OK`.
  • Go to the macro menu and click on `View Select-String Output`, which should be at the bottom of the menu.

We can add a shortcut key, by going to Macro → Modify Shortcut/Delete Macro, on the Plugin commands tab, we double click the associated row and add a shortcut key.

Typical Workflow using Notepad++

Within PowerShell (I am using it within ConEmu), we would run a command involving `Select-String` and pipe the output to `Out-Sls`:


    dir -r *.html | sls 'hello world' | out-sls
    

Then within Notepad++, we click on Macro → `View Select-String Output`. This will open the NppExec's Console with all the lines listed. Then we can double click on any of the lines as you would normally do within the "Find In Files" results window.

Viewing Out-Sls'ed output using Visual Studio

Set up the External Tool

Within Visual Studio do:

  • Select `Tools` → `External Tools`
  • Select `Add`, set a title of `View Select-String Output`
  • Set the command to `cmd.exe`
  • Set the Arguments to `/c type c:\temp\sls.txt`
  • Check `Use Output window`.
Using the External Tool

After having piped out our search results to `Out-Sls`, we can click on `Tools` → `View Select-String Output`.

No comments: