PSReadLine最强PowerShell模块

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
softpowershell

wentao

写点代码,解决点问题。

wezterm的workspace配置

读《万千微尘纷坠心田》