Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mdgrs-mei/PowerShellRun
App, Utility and Function Launcher for PowerShell.
https://github.com/mdgrs-mei/PowerShellRun
cli fuzzy-search launcher powershell terminal tui
Last synced: about 1 month ago
JSON representation
App, Utility and Function Launcher for PowerShell.
- Host: GitHub
- URL: https://github.com/mdgrs-mei/PowerShellRun
- Owner: mdgrs-mei
- License: mit
- Created: 2024-02-23T12:00:34.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2024-04-13T13:42:01.000Z (8 months ago)
- Last Synced: 2024-04-14T12:16:23.168Z (8 months ago)
- Topics: cli, fuzzy-search, launcher, powershell, terminal, tui
- Language: C#
- Homepage:
- Size: 148 KB
- Stars: 127
- Watchers: 2
- Forks: 6
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
- jimsghstars - mdgrs-mei/PowerShellRun - Terminal Based Launcher and Fuzzy Finder for PowerShell. (C# #)
README
# PowerShellRun
[![GitHub license](https://img.shields.io/github/license/mdgrs-mei/PowerShellRun)](https://github.com/mdgrs-mei/PowerShellRun/blob/main/LICENSE)
[![PowerShell Gallery](https://img.shields.io/powershellgallery/p/PowerShellRun)](https://www.powershellgallery.com/packages/PowerShellRun)
[![PowerShell Gallery](https://img.shields.io/powershellgallery/dt/PowerShellRun)](https://www.powershellgallery.com/packages/PowerShellRun)[![Pester Test](https://github.com/mdgrs-mei/PowerShellRun/actions/workflows/pester-test.yml/badge.svg)](https://github.com/mdgrs-mei/PowerShellRun/actions/workflows/pester-test.yml)
[![Hashnode](https://img.shields.io/badge/Hashnode-2962FF?style=for-the-badge&logo=hashnode&logoColor=white)](https://mdgrs.hashnode.dev/streamlining-your-workflow-around-the-powershell-terminal)
App, Utility and Function Launcher for PowerShell.
![Demo](https://github.com/mdgrs-mei/PowerShellRun/assets/81177095/d133be41-be9b-4045-8fa0-5194220a56fe)
*PowerShellRun* is a PowerShell module that lets you fuzzy search applications, utilities and functions you define and launch them
with ease. It is a customizable launcher app on the PowerShell terminal.
## Installation
```powershell
Install-Module -Name PowerShellRun -Scope CurrentUser
```## Requirements
- Windows or macOS
- PowerShell 7.2 or newer## Quick Start
```powershell
Enable-PSRunEntry -Category All
Invoke-PSRun
```This code enables entries of all categories and opens up this TUI:
![Invoke-PSRun](https://github.com/mdgrs-mei/PowerShellRun/assets/81177095/f923bc43-c76b-433a-ada1-c2f49fdaba4e)
Type characters to search entries and hit `Enter` to launch the selected item. There are some other actions that can be performed depending on the item. Hit `Ctrl+k` to open the Action Window and see what actions are available.
![ActionWindow](https://github.com/mdgrs-mei/PowerShellRun/assets/81177095/7abc7a2b-7252-4fc7-9753-796186fcb2ec)
You can assign a shortcut key to quickly launch *PowerShellRun*.
```powershell
Set-PSRunPSReadLineKeyHandler -InvokePsRunChord 'Ctrl+j'
```## Entry Categories
There are some entry categories that you can selectively enable by passing an array of the category names to `Enable-PSRunEntry`.
```powershell
Enable-PSRunEntry -Category Function, Favorite
```### ・🚀 Application
Installed applications are listed by the `Application` category. You can launch (or launch as admin on Windows) the application by pressing the action key.
### ・🔧 Executable
Executable files under the PATH are listed by `Executable` category. You can invoke them on the same console where *PowerShellRun* is running.
### ・🔎 Utility
#### File Manager (PSRun)
`File Manager (PSRun)` navigates the folder hierarchy from the current directory using the PowerShellRun TUI.
![FiileManager](https://github.com/mdgrs-mei/PowerShellRun/assets/81177095/536b0853-0dd2-4c03-b429-c4ec95240cdf)
On the file entries, there is an action described as `"Edit with Default Editor"`. You can customize the script for this action like below:
```powershell
Set-PSRunDefaultEditorScript -ScriptBlock {
param ($path)
& code $path
}
```#### WinGet (PSRun)
`WinGet (PSRun)` helps you install, upgrade and uninstall applications using winget. You need [winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/) and [Microsoft.WinGet.Client](https://github.com/microsoft/winget-cli) module installed to use this utility entry.
![image](https://github.com/mdgrs-mei/PowerShellRun/assets/81177095/225a5e71-cdd7-48ca-ba65-ee0af0dc0dba)
### ・📁 Favorite
You can register folders or files that you frequently access. The available actions are the same as the ones in `File Manager (PSRun)`.
```powershell
Add-PSRunFavoriteFolder -Path 'D:/PowerShellRun'
Add-PSRunFavoriteFile -Path 'D:/PowerShellRun/README.md' -Icon '📖' -Preview @"
-------------------------------
💖 This is a custom preview 💖
-------------------------------
"@
```![Favarites](https://github.com/mdgrs-mei/PowerShellRun/assets/81177095/d174b169-3c3b-49f3-8d11-1997350c85fc)
### ・📝 Function
The ability to call PowerShell functions is what makes *PowerShellRun* special. The functions defined between `Start-PSRunFunctionRegistration` and `Stop-PSRunFunctionRegistration` are registered as entries. The scope of the functions needs to be global so that *PowerShellRun* can call them.
```powershell
Start-PSRunFunctionRegistration#.SYNOPSIS
# git pull with rebase option.
function global:GitPullRebase() {
git pull --rebase
}
# ... Define functions here as many as you want.Stop-PSRunFunctionRegistration
```![FunctionBasic](https://github.com/mdgrs-mei/PowerShellRun/assets/81177095/a70e8a1f-5e08-4dd1-861e-8cd74d23c1d2)
`SYNOPSIS` or `DESCRIPTION` in the comment based help is used as a description of the entry. You can also optionally specify parameters using the `COMPONENT`. It uses [ConvertFrom-StringData](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/convertfrom-stringdata?view=powershell-7.4) to extract the parameters.
```powershell
<#
.SYNOPSIS
git pull with rebase option..COMPONENT
PSRun(
Icon = 🌿
Preview = This is a custom preview.\nNew lines need to be written like this.)
#>
function global:GitPullRebase() {
git pull --rebase
}
```![Function](https://github.com/mdgrs-mei/PowerShellRun/assets/81177095/162b90dd-b51a-4b92-ab75-c8c29b3a385d)
It's even possible to open *PowerShellRun*'s TUI inside a registered function entry using the commands described in the following [section](#powershellrun-as-a-generic-selector). To create a pseudo nested menu, we recommend that you use `Restore-PSRunParentSelector` command to restore the parent menu with `Backspace` key. `File Manager (PSRun)` is a good example of the nested menu.
```powershell
function global:OpenNestedMenu() {
$option = Get-PSRunDefaultSelectorOption
$option.QuitWithBackspaceOnEmptyQuery = $true$result = Get-ChildItem | ForEach-Object {
$entry = [PowerShellRun.SelectorEntry]::new()
$entry.UserData = $_
$entry.Name = $_.Name
$entry
} | Invoke-PSRunSelectorCustom -Option $optionif ($result.KeyCombination -eq 'Backspace') {
Restore-PSRunParentSelector
return
}
# ... Other key handlings here
}
```### ・📘 Script
If you don't want to use the global scope to define function entries, you can use script entries. `Add-PSRunScriptBlock` adds a ScriptBlock and `Add-PSRunScriptFile` adds a `.ps1` file as an entry. They are invoked by pressing `Enter`.
```powershell
Add-PSRunScriptBlock -Name 'Test ScriptBlock' -ScriptBlock {
'This is a test ScriptBlock'
}Add-PSRunScriptFile -Path 'D:\PowerShellRun\tests\TestScriptFile.ps1' -Icon '💎'
```![image](https://github.com/mdgrs-mei/PowerShellRun/assets/81177095/1fbeb3ee-1bf9-45f2-8729-8ebaa9d18e88)
## History Search
History search functionality is provided outside the *PowerShellRun* menu using PSReadLineKeyHandler. It searches PSReadLine history. Multi-line entries are also supported. You can enable it with the following command:
```powershell
Set-PSRunPSReadLineKeyHandler -PSReadLineHistoryChord 'Ctrl+r'
```![image](https://github.com/mdgrs-mei/PowerShellRun/assets/81177095/350afb04-4862-408b-b6b5-3e3c86d90264)
## Options
You can customize *PowerShellRun*'s behavior and themes through options. Create a `SelectorOption` instance and pass it to `Set-PSRunDefaultSelectorOption`.
```powershell
$option = [PowerShellRun.SelectorOption]::new()
$option.Prompt = 'Type words👉 '
$option.QuitWithBackspaceOnEmptyQuery = $true
Set-PSRunDefaultSelectorOption $option
Invoke-PSRun
```The option you set as default can be returned by `Get-PSRunDefaultSelectorOption`. Note that the returned option is always deep cloned. It is useful when you create a nested menu.
```powershell
$option = Get-PSRunDefaultSelectorOption
$option.Prompt = 'Nested menu prompt > '
$option.QuitWithBackspaceOnEmptyQuery = $true
'a', 'b' | Invoke-PSRunSelector -Option $option
```### ・Key Bindings
Key bindings are stored in `$option.KeyBinding`. You can set a string of `KeyModifier` and `Key` concatenated with `+` to the key.
```powershell
$keyBinding = $option.KeyBinding
$keyBinding.QuitKeys = @(
'Escape'
'Ctrl+j'
)
$keyBinding.MarkerKeys = 'Ctrl+f'
```#### Key Remap Mode
There are two key binding modes, `Normal Mode` and `Key Remap Mode`. You can toggle the remap mode by pressing `RemapModeEnterKeys` and `RemapModeExitKeys`. In Key Remap mode, the keys you specify are remapped to other keys. This is useful if you'd like to achieve something like Vim Normal mode and Insert mode. Vim style `hjkl` navigation is set up like this:
```powershell
$theme.KeyRemapModeConsoleCursorShape = 'BlinkingBlock'
$keyBinding.InitialRemapMode = $true
$keyBinding.EnableTextInputInRemapMode = $false
$keyBinding.RemapModeEnterKeys = 'Escape'
$keyBinding.RemapModeExitKeys = 'i'
$keyBinding.RemapKeys = @(
[PowerShellRun.RemapKey]::new('h', 'LeftArrow')
[PowerShellRun.RemapKey]::new('j', 'DownArrow')
[PowerShellRun.RemapKey]::new('k', 'UpArrow')
[PowerShellRun.RemapKey]::new('l', 'RightArrow')
[PowerShellRun.RemapKey]::new('Shift+j', 'Shift+DownArrow')
[PowerShellRun.RemapKey]::new('Shift+k', 'Shift+UpArrow')
)
```It starts in Key Remap mode, and `hjkl` keys are remapped to arrow keys. `i` key enables typing, and you can go back to the `hjkl` navigation by `Escape` key.
### ・Theme
The theme can be customized with `$option.Theme` property. We hope someone creates a cool theme library for *PowerShellRun*🙏.
```powershell
$default = [PowerShellRun.FontColor]::FromHex('#CBCCC6')
$gray = [PowerShellRun.FontColor]::FromHex('#707070')
$highlight = [PowerShellRun.FontColor]::FromHex('#61FFCA')
$focusHighlight = [PowerShellRun.FontColor]::FromHex('#4CBF99')
$roundBorder = [PowerShellRun.BorderSymbol]::new()
$roundBorder.TopLeft = '╭'
$roundBorder.TopRight = '╮'
$roundBorder.BottomLeft = '╰'
$roundBorder.BottomRight = '╯'$option.Prompt = ' '
$theme = $option.Theme
$theme.CanvasHeightPercentage = 80
$theme.Cursor = '▸ '
$theme.IconEnable = $false
$theme.PreviewPosition = [PowerShellRun.PreviewPosition]::Right
$theme.CanvasBorderFlags = [PowerShellRun.BorderFlag]::All
$theme.SearchBarBorderFlags = [PowerShellRun.BorderFlag]::None
$theme.CanvasBorderSymbol = $roundBorder
$theme.PreviewBorderSymbol = $roundBorder
$theme.DefaultForegroundColor = $default
$theme.CanvasBorderForegroundColor = $gray
$theme.PromptForegroundColor = $gray
$theme.PreviewBorderForegroundColor = $gray
$theme.EntryScrollBarForegroundColor = $gray
$theme.PreviewScrollBarForegroundColor = $gray
$theme.CursorForegroundColor = $highlight
$theme.NameHighlightForegroundColor = $highlight
$theme.DescriptionHighlightForegroundColor = $highlight
$theme.NameFocusHighlightBackgroundColor = $focusHighlight
$theme.DescriptionFocusHighlightBackgroundColor = $focusHighlight
```![Theme](https://github.com/mdgrs-mei/PowerShellRun/assets/81177095/3b91109f-2d7e-4985-a85f-67df6e402779)
# *PowerShellRun* as a Generic Selector
The underlying fuzzy selector in *PowerShellRun* is accessible with the following commands.
## Invoke-PSRunSelector
`Invoke-PSRunSelector` is designed to be used interactively on the terminal. It takes an array of **objects** and returns **objects**. It uses `Name`, `Description` and `Preview` properties of the object by default but you can change them with parameters like `-NameProperty`, `-DescriptionProperty` and `-PreviewProperty`.
```powershell
Get-ChildItem | Invoke-PSRunSelector -DescriptionProperty FullName -MultiSelection
```![SelectorDemo](https://github.com/mdgrs-mei/PowerShellRun/assets/81177095/799397eb-7a31-4349-a4b1-a0e671a4674c)
`-Expression` parameter is useful if you need to build custom strings.
```powershell
Get-ChildItem | Invoke-PSRunSelector -Expression {@{
Name = $_.Name
Preview = Get-Item $_ | Out-String
}}
```## Invoke-PSRunSelectorCustom
`Invoke-PSRunSelectorCustom` offers you a full access to the selector and is designed to create your own tool. It takes an array of `SelectorEntry` instances and returns a `SelectorResult` object. A `SelectorResult` object holds information such as the selected entry and the pressed key.
```powershell
PS> Get-ChildItem | ForEach-Object {
$entry = [PowerShellRun.SelectorEntry]::new()
$entry.UserData = $_
$entry.Name = $_.Name
$entry.Preview = $_.FullName
$entry
} | Invoke-PSRunSelectorCustomFocusedEntry MarkedEntries KeyCombination Context
------------ ------------- -------------- -------
PowerShellRun.SelectorEntry Enter PowerShellRun.SelectorContext
```### ・PreviewAsyncScript
By using `PreviewAsyncScript`, it's even possible to show information that takes some time to generate without blocking the UI. If you have [bat](https://github.com/sharkdp/bat) installed for syntax highlighting, you can build a Select-String viewer with this script:
```powershell
$word = Read-Host 'Type word to search for'
$filter = Read-Host 'Type path filter (e.g. "*.cs")'$option = [PowerShellRun.SelectorOption]::new()
$option.Prompt = "Searching for word '{0}'> " -f $word$matchLines = Get-ChildItem $filter -Recurse | Select-String $word
$result = $matchLines | ForEach-Object {
$entry = [PowerShellRun.SelectorEntry]::new()
$entry.UserData = $_
$entry.Name = '{0}:{1}' -f $_.Filename, $_.LineNumber
$entry.Description = $_.Path
$entry.PreviewAsyncScript = {
param($match)
& bat --color=always --highlight-line $match.LineNumber $match.Path
}
$entry.PreviewAsyncScriptArgumentList = $_
$entry.PreviewInitialVerticalScroll = $_.LineNumber
$entry
} | Invoke-PSRunSelectorCustom -Option $option$match = $result.FocusedEntry.UserData
if ($match -and ($result.KeyCombination -eq 'Enter')) {
$argument = '{0}:{1}' -f $match.Path, $match.LineNumber
code --goto $argument
}
```![Invoke-PSRunSelectorCustom](https://github.com/mdgrs-mei/PowerShellRun/assets/81177095/c963be6f-88cb-457b-a966-a94def3f057a)
### ・SearchablePattern
You can set Regex pattern to `NameSearchablePattern` and `DescriptionSearchablePattern` properties to define which parts of a string are hit by query.
#### Example1: The second word split by space is searchable
```powershell
# 'bbb' and 'eee' are searchable.
$pattern = [Regex]::new('(?<=^\S*\s).*?(?=\s|$)')
'aaa bbb ccc', 'ddd eee fff' | ForEach-Object {
$entry = [PowerShellRun.SelectorEntry]::new()
$entry.Name = $_
$entry.NameSearchablePattern = $pattern
$entry
} | Invoke-PSRunSelectorCustom
```#### Example2: All words inside [] are searchable
```powershell
# 'bbb', 'ccc' and 'ddd' are searchable.
$pattern = [Regex]::new('(?<=\[).*?(?=\])')
'aaa [bbb] [ccc]', '[ddd] eee fff' | ForEach-Object {
$entry = [PowerShellRun.SelectorEntry]::new()
$entry.Name = $_
$entry.NameSearchablePattern = $pattern
$entry
} | Invoke-PSRunSelectorCustom
```## Invoke-PSRunPrompt
`Invoke-PSRunPrompt` can be used to get user input in the same style as `Invoke-PSRunSelectorCustom` but without any entries. It reflects `SelectorOption` and returns the input, `KeyCombination` and the context. `WinGet (PSRun)` is a practical example.
```powershell
Invoke-PSRunPrompt
```![image](https://github.com/mdgrs-mei/PowerShellRun/assets/81177095/90a9537f-afbd-4256-8ebb-af3d8e940d76)
```powershell
Input KeyCombination Context
----- -------------- -------
hello Enter PowerShellRun.PromptContext
```## Major Limitations
- No history support
- Some emojis break the rendering## Changelog
Changelog is available [here](https://github.com/mdgrs-mei/PowerShellRun/blob/main/CHANGELOG.md).
# Contributing
## Code of Conduct
Please read our [Code of Conduct](https://github.com/mdgrs-mei/PowerShellRun/blob/main/CODE_OF_CONDUCT.md) to foster a welcoming environment. By participating in this project, you are expected to uphold this code.
## Have a question or want to showcase something?
Please come to our [Discussions](https://github.com/mdgrs-mei/PowerShellRun/discussions) page and avoid filing an issue to ask a question.
## Want to file an issue or make a PR?
Please see our [Contribution Guidelines](https://github.com/mdgrs-mei/PowerShellRun/blob/main/CONTRIBUTING.md).
# Credits
*PowerShellRun* uses:
- Wcwidth
https://github.com/spectreconsole/wcwidthHeavily inspired by:
- fzf
https://github.com/junegunn/fzf
- PowerToys Run
https://github.com/microsoft/PowerToys