PSReadlineHelper.psm1
#not all commands and features of this module will not work with PSReadline version 2.0. $ver = (get-module psreadline).version . $psscriptroot\PSReadlinehelpers.ps1 #region my PSReadlineOptions #my customizations if ($ver -gt 1.2) { $token = @{ Colors = @{String="Cyan"} } } else { $token = @{ TokenKind = "String" ForegroundColor = "Cyan" } } Set-PSReadlineOption @token $options = @{ HistoryNoDuplicates = $True HistorySaveStyle = "SaveIncrementally" DingDuration = 300 DingTone = 440 MaximumHistoryCount = 1000 } Set-PSReadlineOption @options #endregion #region my PSReadlineKey handlers Set-PSReadlineKeyHandler -key F12 -Function CaptureScreen #Add [$($env:username)] to the end of every description so that I can search for my handlers Set-PSReadlineKeyHandler -key Ctrl+h -BriefDescription "Open PSReadlineHistory" -Description "View PSReadline history file with the associated application. [$($env:username)]" -ScriptBlock { #open the history file with the associated application for .txt files, probably Notepad. Invoke-Item -Path $(Get-PSReadlineOption).HistorySavePath } if ($PSedition -eq 'Desktop') { Set-PSReadlineKeyHandler -key Ctrl+Alt+F -BriefDescription "Function Menu" -Description "Display all functions as menu using Out-GridView. [$($env:username)]" -ScriptBlock { $line = $null $cursor = $null [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor) #filter out the built-in functions for changing drives and a few others Get-Childitem -path function: | Where-Object {$_.name -notmatch "([A-Za-z]:)|(Get-Verb)|(prompt)|(cd)|(clear-host)|(more)|(pause)"} | select-object Name, Version, Source, @{Name = "Syntax"; Expression = {(Get-Command $_.name -Syntax|Out-String).Trim()}} | Out-GridView -title "Function Menu: Select one to run" -OutputMode Single | Foreach-Object { Show-Command -Name $_.name } } Set-PSReadlineKeyHandler -Key F7 -BriefDescription HistoryList -Description "Show command history with Out-Gridview. [$($env:username)]" -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 | Select-Object -unique | Out-GridView -Title "PSReadline History - Select a command to insert at the prompt" -OutputMode Single if ($command) { [Microsoft.PowerShell.PSConsoleReadLine]::RevertLine() [Microsoft.PowerShell.PSConsoleReadLine]::Insert(($command -join "`n")) } } Set-PSReadlineKeyHandler -key Alt+F5 -BriefDescription "ListMyHandlers" -Description "List my PSReadlineHandlers [$env:username]" -ScriptBlock { (Get-PSReadlineKeyHandler -bound ).Where( {$_.description -match "\[$env:username\]"}) | Select-Object -Property Key,Description | Out-GridView -title "My handlers" } } #if desktop Set-PSReadlineKeyHandler -Key Shift+F1 -BriefDescription OnlineCommandHelp -LongDescription "Open online help for the current command. [$($env:username)]" -ScriptBlock { $ast = $null $tokens = $null $errors = $null $cursor = $null [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$ast, [ref]$tokens, [ref]$errors, [ref]$cursor) $commandAst = $ast.FindAll( { $node = $args[0] $node -is [System.Management.Automation.Language.CommandAst] -and $node.Extent.StartOffset -le $cursor -and $node.Extent.EndOffset -ge $cursor }, $true) | Select-Object -Last 1 if ($commandAst -ne $null) { $commandName = $commandAst.GetCommandName() if ($commandName -ne $null) { $command = $ExecutionContext.InvokeCommand.GetCommand($commandName, 'All') if ($command -is [System.Management.Automation.AliasInfo]) { $commandName = $command.ResolvedCommandName } if ($commandName -ne $null) { Get-Help $commandName -online } } } } Set-PSReadlineKeyHandler -Key Alt+w -BriefDescription SaveInHistory -LongDescription "Save current line in history but do not execute. [$($env:username)]" -ScriptBlock { $line = $null $cursor = $null [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor) [Microsoft.PowerShell.PSConsoleReadLine]::AddToHistory($line) [Microsoft.PowerShell.PSConsoleReadLine]::RevertLine() } # Ctrl+Alt+j then type a key to mark the current directory. # Alt+J to show the current shortcuts in a popup # Ctrj+j then the same key will change back to that directory without # needing to type cd and won't change the command line. #pre-populate a global variable $PSReadlineMarks = @{ [char]"s" = "c:\scripts" [char]"d" = "~\documents" } Set-PSReadlineKeyHandler -Key Ctrl+Alt+j -BriefDescription MarkDirectory -LongDescription "Mark the current directory. [$($env:username)]" -ScriptBlock { #press a single character to mark the current directory $key = [Console]::ReadKey($true) if ($key.keychar -match "\w") { $global:PSReadlineMarks[$key.KeyChar] = $pwd } else { [Microsoft.PowerShell.PSConsoleReadLine]::Ding() Write-Warning "You entered an invalid character." [Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine() } } Set-PSReadlineKeyHandler -Key Ctrl+j -BriefDescription JumpDirectory -LongDescription "Goto the marked directory.[$($env:username)]" -ScriptBlock { $key = [Console]::ReadKey() $dir = $global:PSReadlineMarks[$key.KeyChar] if ($dir) { set-location $dir [Microsoft.PowerShell.PSConsoleReadLine]::InvokePrompt() } } Set-PSReadlineKeyHandler -Key Alt+j -BriefDescription ShowDirectoryMarks -LongDescription "Show the currently marked directories. [$($env:username)]" -ScriptBlock { $data = $global:PSReadlineMarks.GetEnumerator() | Where-object {$_.key} | Sort-object key $data | foreach-object -begin { $text = @" Key`tDirectory ---`t--------- "@ } -process { $text += "{0}`t{1}`n" -f $_.key, $_.value } if ($PSedition -eq 'Desktop') { $ws = New-Object -ComObject Wscript.Shell $ws.popup($text, 10, "Use Ctrl+J to jump") | Out-Null [Microsoft.PowerShell.PSConsoleReadLine]::InvokePrompt() } else { write-host "`n$text`n" -ForegroundColor Yellow } } #endregion Export-ModuleMember -Variable PSReadlineMarks -Function 'Optimize-PSReadlineHistory','Get-MyPSReadline','Get-MyPSReadlineKey','Get-PSReadlineColorOptions', 'Show-PSReadlineColor','Import-PSReadlineColorOptions' |