Skip to content

About

A command-line predictor written in F# that suggests code snippets based on the input. This module requires PowerShell 7.2 or higher and PSReadLine 2.2.2. or higher.

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Repository files navigation

SnippetPredictor

PowerShell Gallery PowerShell Gallery Test main status codecov Top Language License: MIT

SnippetPredictor is a command-line predictor written in F#. It suggests code snippets based on the input. This module requires PowerShell 7.2 and PSReadLine 2.2.2.

This project builds upon the following article:

How to create a command-line predictor - PowerShell | Microsoft Learn

Installation

Install SnippetPredictor from the PowerShell Gallery:

PowerShell Gallery | SnippetPredictor

# Recommended: PSResourceGet (PowerShellGet 3.0)
Install-PSResource -Name SnippetPredictor

# Alternatively, if you are using PowerShellGet 2.x:
Install-Module -Name SnippetPredictor

Before using SnippetPredictor, ensure that your PowerShell PredictionSource equals HistoryAndPlugin1:

# PredictionSource = HistoryAndPlugin required.
Get-PSReadLineOption | Select-Object PredictionSource
#
# PredictionSource
# ----------------
# HistoryAndPlugin

Import the SnippetPredictor module and verify that the predictor loads:

Import-Module SnippetPredictor

# Confirm SnippetPredictor(Snippet) loaded.
Get-PSSubsystem -Kind CommandPredictor
#
# Kind              SubsystemType      IsRegistered Implementations
# ----              -------------      ------------ ---------------
# CommandPredictor  ICommandPredictor          True {Snippet, Windows Package Manager - WinGet}

Set the prediction view style to ListView2:

Set-PSReadLineOption -PredictionViewStyle ListView

Optionally enable SnippetPredictor completion in PSReadLine:

Enable-SnippetPredictorKeyHandler

By default, Tab and Shift+Tab complete :snp and configured group identifiers. They accept : or a partial identifier. After a complete identifier, they cycle through matching snippets. The :tip identifier isn't included in this completion.

Completion requires the cursor at the end of the line. Every character before the identifier must be whitespace. Other input uses standard PSReadLine completion. The prediction ListView remains navigable with the standard UpArrow and DownArrow bindings.

To expand identifiers or select snippets without accepting the line, specify -AcceptChord:

Enable-SnippetPredictorKeyHandler -AcceptChord Enter

The accept chord expands a partial identifier to the first matching complete identifier. It replaces a complete identifier with its snippet when one matches. When more than one snippet matches, it selects the first prediction. The line remains open for these operations. An exact unknown group identifier remains in the buffer. It invokes PSReadLine's Ding() action for Audible and None. For Visual, it emits a terminal BEL. PSReadLine's Ding() has no visual effect in this case. The terminal handles the BEL according to its notification settings. Other inputs without a matching candidate use the standard PSReadLine AcceptLine action.

Use Disable-SnippetPredictorKeyHandler to remove the bindings. See Enable-SnippetPredictorKeyHandler.md for input, fallback, and cleanup details. Use New-SnippetPredictorKeyHandler.md to compose custom handlers.

Cmdlet help

Refer to the following documents for detailed cmdlet help:

Usage

Create snippets

First, set up your ~/.snippet-predictor.json file. The easiest way to do this is to run the Add-Snippet command:

Add-Snippet "echo 'hello'" -Tooltip 'say hello' -Group 'greeting'

This will create a file with the following content. You can also create the file manually if you prefer.

{
  "Snippets": [
    {
      "Snippet": "echo 'hello'",
      "Tooltip": "say hello.",
      "Group": "greeting"
    }
  ]
}

Search snippets

Filter snippets in your ~/.snippet-predictor.json file using the following keywords:

  • Use :snp {input} to search for {input} in the Snippet field.
  • Use :tip {input} to search for {input} in the Tooltip field.
  • Use :{group} {input} to search for {input} in the Snippet field for snippets in a specified Group.
    • Allowed characters for the Group field: ^[a-zA-Z0-9]+$. (Group names must consist of alphanumeric characters.)
    • Typing a partial group name (e.g., :p) suggests matching groups like :pwsh.

Predictions rank exact matches first, followed by prefix, word-start, and other substring matches. Word-start matches follow a separator. Unicode letters, digits, combining marks, and connector punctuation such as _ aren't separators. Plain input, :snp, and group searches rank the Snippet field; :tip ranks the Tooltip field. Matches with the same rank keep their configuration order. Without a search term, snippets keep their configuration order. Matching identifiers appear before snippets. This ranking doesn't change the candidate order used by completion or accept handlers.

Predict after commands and comments

For top-level commands, predictions search the final command after ;, |, or a block comment. Selecting a prediction replaces that command and its arguments, keeping the preceding input. For example, registered snippets can produce these predictions:

Write-Host 'start.'; git status
<# note #> git status
Get-Process | Select-Object Name

The search targets the final command even when the cursor is elsewhere in the line. Matching doesn't check whether a snippet accepts pipeline input. Redirections, invocation operators, script-block arguments, and subexpressions aren't supported. These commands use the existing whole-line search instead. Replacement inside strings or comments isn't supported.

Configure predictions

By default, the predictor searches snippets in a case-insensitive manner. To enable case-sensitive search, set SearchCaseSensitive to true in .snippet-predictor.json. The default value is false.

Set PredictOnlyWithIdentifier to true to suppress predictions for ordinary input. Edit .snippet-predictor.json:

{
  "PredictOnlyWithIdentifier": true,
  "Snippets": [
    {
      "Snippet": "git status",
      "Tooltip": "Show working tree status",
      "Group": "git"
    }
  ]
}

Identifier-based predictions keep their existing behavior. :snp, :tip, group and partial identifiers, and standalone : aren't affected. Omitting the setting or using false or null keeps the default behavior. This setting affects predictions, not completion or accept handlers.

List and remove snippets

You can list your registered snippets with the Get-Snippet command.

To remove a snippet, use the Remove-Snippet command.

Remove-Snippet "echo 'hello'"

You can also delete it directly from ~/.snippet-predictor.json.

By combining Get-Snippet and Remove-Snippet, you can remove snippets that match a specific pattern. Perform this in one step:

Get-Snippet | Where-Object -Property Tooltip -like *test* | Remove-Snippet

Benchmarks

The solution includes the benchmark test project in the normal build and lint tasks. Performance measurements run separately from unit tests. They measure cache prediction and ICommandPredictor.GetSuggestion. Measurements cover time and managed allocations, excluding configuration setup and cleanup.

Run from the repository root:

dotnet build src/SnippetPredictor.Benchmark -c Release
dotnet run --project src/SnippetPredictor.Benchmark -c Release --no-build -- --filter '*' --job short --exporters json --artifacts BenchmarkDotNet.Artifacts/ranking-baseline

For before-and-after comparisons, keep the benchmark code and job settings unchanged. Use the same SDK, runtime, and hardware, with a different artifact directory for each run. Compare time, allocated bytes, and GC in the generated reports. ShortRun uses three measured iterations. Collect more samples before interpreting differences with overlapping uncertainty. Use --job Dry to check setup, execution, and cleanup, not performance.

Managed allocations don't represent retained or native memory. These benchmarks don't measure PSReadLine rendering or initial prediction latency.

The PR benchmark workflow also compares base and head measurements.

Footnotes

  1. Using predictors in PSReadLine - PowerShell | Microsoft Learn ↩

  2. Using predictors in PSReadLine - PowerShell | Microsoft Learn ↩

About

A command-line predictor written in F# that suggests code snippets based on the input. This module requires PowerShell 7.2 or higher and PSReadLine 2.2.2. or higher.

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages