PSReadLine最强PowerShell模块
2022-07-10 • 预计阅读时间 2 分钟
2022-07-10 • 预计阅读时间 2 分钟
PowerShell其实从设计理念上来说是一直强于bash的.毕竟不是一个时代的产物.但是bash的好处是经历了足够长的时间发展,有良好的周边支持.
Readline 就是其中一个很棒的功能.主要包含了根据你输入的内容进行搜索历史,提示命令,删除文字之类的功能.能够在日常使用的时候大大的提升便利性.
PSReadLine 则是 A bash inspired readline implementation for PowerShell
. 提供了增加的Tab 自动补全和命令预测功能.最新的版本v2.2.6还提供了插件来增强不全功能.
安装的话只需要owerShellGet的版本高于 1.6.0
就可以通过如下的命令安装或者升级
Install-Module -Name PowerShellGet -Force
PSReadLine
的可配置项可以参考sample profile file.
下面是我的配置.
Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward
Set-PSReadLineKeyHandler -Key DownArrow -Function HistorySearchForward
Set-PSReadLineOption -EditMode Emacs
Set-PSReadLineOption -PredictionSource HistoryAndPlugin
Set-PSReadLineKeyHandler -Chord 'Ctrl+d,Ctrl+c' -Function CaptureScreen
Set-PSReadLineKeyHandler -Key Alt+d -Function ShellKillWord
Set-PSReadLineKeyHandler -Key Alt+Backspace -Function ShellBackwardKillWord
Set-PSReadLineKeyHandler -Key Alt+b -Function ShellBackwardWord
Set-PSReadLineKeyHandler -Key Alt+f -Function ShellForwardWord
Set-PSReadLineKeyHandler -Key Alt+B -Function SelectShellBackwardWord
Set-PSReadLineKeyHandler -Key Alt+F -Function SelectShellForwardWord
#endregion
#region git
#git status
Set-PSReadLineKeyHandler -Key Alt+s -LongDescription "git status" `
-ScriptBlock {
[Microsoft.PowerShell.PSConsoleReadLine]::RevertLine()
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("git status")
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
}
# git pull
Set-PSReadLineKeyHandler -Key Alt+p -LongDescription "git pull" `
-ScriptBlock {
[Microsoft.PowerShell.PSConsoleReadLine]::RevertLine()
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("git pull")
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
}
# git push
Set-PSReadLineKeyHandler -Key Alt+P -LongDescription "git push" `
-ScriptBlock {
[Microsoft.PowerShell.PSConsoleReadLine]::RevertLine()
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("git push")
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
}
#git show
Set-PSReadLineKeyHandler -Key Ctrl+Alt+s -LongDescription "git show" `
-ScriptBlock {
[Microsoft.PowerShell.PSConsoleReadLine]::RevertLine()
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("git show")
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
}
#endregion
#region utils
# 保存当前命令到历史中,但是并不执行
Set-PSReadLineKeyHandler -Key Alt+w `
-BriefDescription SaveInHistory `
-LongDescription "Save current line in history but do not execute" `
-ScriptBlock {
param($key, $arg)
$line = $null
$cursor = $null
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
[Microsoft.PowerShell.PSConsoleReadLine]::AddToHistory($line)
[Microsoft.PowerShell.PSConsoleReadLine]::RevertLine()
}
# Insert text from the clipboard as a here string
Set-PSReadLineKeyHandler -Key Ctrl+V `
-BriefDescription PasteAsHereString `
-LongDescription "Paste the clipboard text as a here string" `
-ScriptBlock {
param($key, $arg)
Add-Type -Assembly PresentationCore
if ([System.Windows.Clipboard]::ContainsText()) {
# Get clipboard text - remove trailing spaces, convert \r\n to \n, and remove the final \n.
$text = ([System.Windows.Clipboard]::GetText() -replace "\p{Zs}*`r?`n", "`n").TrimEnd()
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("@'`n$text`n'@")
}
else {
[Microsoft.PowerShell.PSConsoleReadLine]::Ding()
}
}
# F7 弹出一个GUI的历史命令列表
Set-PSReadLineKeyHandler -Key F7 `
-BriefDescription History `
-LongDescription 'Show command history' `
-ScriptBlock {
$pattern = $null
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$pattern, [ref]$null)
if ($pattern) {
$pattern = [regex]::Escape($pattern)
}
$history = [System.Collections.ArrayList]@(
$last = ''
$lines = ''
foreach ($line in [System.IO.File]::ReadLines((Get-PSReadLineOption).HistorySavePath)) {
if ($line.EndsWith('`')) {
$line = $line.Substring(0, $line.Length - 1)
$lines = if ($lines) {
"$lines`n$line"
}
else {
$line
}
continue
}
if ($lines) {
$line = "$lines`n$line"
$lines = ''
}
if (($line -cne $last) -and (!$pattern -or ($line -match $pattern))) {
$last = $line
$line
}
}
)
$history.Reverse()
$command = $history | Out-GridView -Title History -PassThru
if ($command) {
[Microsoft.PowerShell.PSConsoleReadLine]::RevertLine()
[Microsoft.PowerShell.PSConsoleReadLine]::Insert(($command -join "`n"))
}
}
#
# Ctrl+Shift+j then type a key to mark the current directory.
# Ctrj+j then the same key will change back to that directory without
# needing to type cd and won't change the command line.
$global:PSReadLineMarks = @{}
Set-PSReadLineKeyHandler -Key Ctrl+J `
-BriefDescription MarkDirectory `
-LongDescription "Mark the current directory" `
-ScriptBlock {
param($key, $arg)
$key = [Console]::ReadKey($true)
$global:PSReadLineMarks[$key.KeyChar] = $pwd
}
Set-PSReadLineKeyHandler -Key Ctrl+j `
-BriefDescription JumpDirectory `
-LongDescription "Goto the marked directory" `
-ScriptBlock {
param($key, $arg)
$key = [Console]::ReadKey()
$dir = $global:PSReadLineMarks[$key.KeyChar]
if ($dir) {
cd $dir
[Microsoft.PowerShell.PSConsoleReadLine]::InvokePrompt()
}
}
Set-PSReadLineKeyHandler -Key Alt+j `
-BriefDescription ShowDirectoryMarks `
-LongDescription "Show the currently marked directories" `
-ScriptBlock {
param($key, $arg)
$global:PSReadLineMarks.GetEnumerator() | % {
[PSCustomObject]@{Key = $_.Key; Dir = $_.Value } } |
Format-Table -AutoSize | Out-Host
[Microsoft.PowerShell.PSConsoleReadLine]::InvokePrompt()
}
#endregion