580 lines
22 KiB
PowerShell
580 lines
22 KiB
PowerShell
using namespace System.Management.Automation
|
|
using namespace System.Management.Automation.Language
|
|
|
|
if (Get-Command Set-PSReadLineOption -ErrorAction SilentlyContinue) {
|
|
# Set EditMode Windows first to ensure all subsequent registrations target the correct keymap
|
|
Set-PSReadLineOption -EditMode Windows
|
|
|
|
# Searching for commands with up/down arrow is really handy.
|
|
Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward
|
|
Set-PSReadLineKeyHandler -Key DownArrow -Function HistorySearchForward
|
|
|
|
# This key handler shows the entire or filtered history using Out-GridView.
|
|
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"))
|
|
}
|
|
}
|
|
|
|
# CaptureScreen is good for blog posts or email showing a transaction
|
|
Set-PSReadLineKeyHandler -Chord 'Ctrl+d,Ctrl+c' -Function CaptureScreen
|
|
|
|
# The built-in word movement uses character delimiters, but token based word movement is also very useful
|
|
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
|
|
|
|
#region Smart Insert/Delete
|
|
|
|
Set-PSReadLineKeyHandler -Key '"', "'" `
|
|
-BriefDescription SmartInsertQuote `
|
|
-LongDescription "Insert paired quotes if not already on a quote" `
|
|
-ScriptBlock {
|
|
param($key, $arg)
|
|
|
|
$quote = $key.KeyChar
|
|
|
|
$selectionStart = $null
|
|
$selectionLength = $null
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::GetSelectionState([ref]$selectionStart, [ref]$selectionLength)
|
|
|
|
$line = $null
|
|
$cursor = $null
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
|
|
|
|
# If text is selected, just quote it without any smarts
|
|
if ($selectionStart -ne -1) {
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::Replace($selectionStart, $selectionLength, $quote + $line.SubString($selectionStart, $selectionLength) + $quote)
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($selectionStart + $selectionLength + 2)
|
|
return
|
|
}
|
|
|
|
$ast = $null
|
|
$tokens = $null
|
|
$parseErrors = $null
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$ast, [ref]$tokens, [ref]$parseErrors, [ref]$null)
|
|
|
|
function FindToken {
|
|
param($tokens, $cursor)
|
|
|
|
foreach ($token in $tokens) {
|
|
if ($cursor -lt $token.Extent.StartOffset) { continue }
|
|
if ($cursor -lt $token.Extent.EndOffset) {
|
|
$result = $token
|
|
$token = $token -as [StringExpandableToken]
|
|
if ($token) {
|
|
$nested = FindToken $token.NestedTokens $cursor
|
|
if ($nested) { $result = $nested }
|
|
}
|
|
|
|
return $result
|
|
}
|
|
}
|
|
return $null
|
|
}
|
|
|
|
$token = FindToken $tokens $cursor
|
|
|
|
# If we're on or inside a **quoted** string token (so not generic), we need to be smarter
|
|
if ($token -is [StringToken] -and $token.Kind -ne [TokenKind]::Generic) {
|
|
# If we're at the start of the string, assume we're inserting a new string
|
|
if ($token.Extent.StartOffset -eq $cursor) {
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("$quote$quote ")
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursor + 1)
|
|
return
|
|
}
|
|
|
|
# If we're at the end of the string, move over the closing quote if present.
|
|
if ($token.Extent.EndOffset -eq ($cursor + 1) -and $line[$cursor] -eq $quote) {
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursor + 1)
|
|
return
|
|
}
|
|
}
|
|
|
|
if ($null -eq $token -or
|
|
$token.Kind -eq [TokenKind]::RParen -or $token.Kind -eq [TokenKind]::RCurly -or $token.Kind -eq [TokenKind]::RBracket) {
|
|
if ($line[0..$cursor].Where{ $_ -eq $quote }.Count % 2 -eq 1) {
|
|
# Odd number of quotes before the cursor, insert a single quote
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::Insert($quote)
|
|
}
|
|
else {
|
|
# Insert matching quotes, move cursor to be in between the quotes
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("$quote$quote")
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursor + 1)
|
|
}
|
|
return
|
|
}
|
|
|
|
# If cursor is at the start of a token, enclose it in quotes.
|
|
if ($token.Extent.StartOffset -eq $cursor) {
|
|
if ($token.Kind -eq [TokenKind]::Generic -or $token.Kind -eq [TokenKind]::Identifier -or
|
|
$token.Kind -eq [TokenKind]::Variable -or $token.TokenFlags.hasFlag([TokenFlags]::Keyword)) {
|
|
$end = $token.Extent.EndOffset
|
|
$len = $end - $cursor
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::Replace($cursor, $len, $quote + $line.SubString($cursor, $len) + $quote)
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($end + 2)
|
|
return
|
|
}
|
|
}
|
|
|
|
# We failed to be smart, so just insert a single quote
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::Insert($quote)
|
|
}
|
|
|
|
Set-PSReadLineKeyHandler -Key '(', '{', '[' `
|
|
-BriefDescription InsertPairedBraces `
|
|
-LongDescription "Insert matching braces" `
|
|
-ScriptBlock {
|
|
param($key, $arg)
|
|
|
|
$closeChar = switch ($key.KeyChar) {
|
|
<#case#> '(' { [char]')'; break }
|
|
<#case#> '{' { [char]'}'; break }
|
|
<#case#> '[' { [char]']'; break }
|
|
}
|
|
|
|
$selectionStart = $null
|
|
$selectionLength = $null
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::GetSelectionState([ref]$selectionStart, [ref]$selectionLength)
|
|
|
|
$line = $null
|
|
$cursor = $null
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
|
|
|
|
if ($selectionStart -ne -1) {
|
|
# Text is selected, wrap it in brackets
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::Replace($selectionStart, $selectionLength, $key.KeyChar + $line.SubString($selectionStart, $selectionLength) + $closeChar)
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($selectionStart + $selectionLength + 2)
|
|
}
|
|
else {
|
|
# No text is selected, insert a pair
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("$($key.KeyChar)$closeChar")
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursor + 1)
|
|
}
|
|
}
|
|
|
|
Set-PSReadLineKeyHandler -Key ')', ']', '}' `
|
|
-BriefDescription SmartCloseBraces `
|
|
-LongDescription "Insert closing brace or skip" `
|
|
-ScriptBlock {
|
|
param($key, $arg)
|
|
|
|
$line = $null
|
|
$cursor = $null
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
|
|
|
|
if ($line[$cursor] -eq $key.KeyChar) {
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursor + 1)
|
|
}
|
|
else {
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("$($key.KeyChar)")
|
|
}
|
|
}
|
|
|
|
Set-PSReadLineKeyHandler -Key Backspace `
|
|
-BriefDescription SmartBackspace `
|
|
-LongDescription "Delete previous character or matching quotes/parens/braces" `
|
|
-ScriptBlock {
|
|
param($key, $arg)
|
|
|
|
$line = $null
|
|
$cursor = $null
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
|
|
|
|
if ($cursor -gt 0) {
|
|
$toMatch = $null
|
|
if ($cursor -lt $line.Length) {
|
|
switch ($line[$cursor]) {
|
|
<#case#> '"' { $toMatch = '"'; break }
|
|
<#case#> "'" { $toMatch = "'"; break }
|
|
<#case#> ')' { $toMatch = '('; break }
|
|
<#case#> ']' { $toMatch = '['; break }
|
|
<#case#> '}' { $toMatch = '{'; break }
|
|
}
|
|
}
|
|
|
|
if ($toMatch -ne $null -and $line[$cursor - 1] -eq $toMatch) {
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::Delete($cursor - 1, 2)
|
|
}
|
|
else {
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::BackwardDeleteChar($key, $arg)
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion Smart Insert/Delete
|
|
|
|
# Sometimes you enter a command but realize you forgot to do something else first.
|
|
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()
|
|
}
|
|
}
|
|
|
|
# Sometimes you want to get a property of invoke a member on what you've entered so far
|
|
Set-PSReadLineKeyHandler -Key 'Alt+(' `
|
|
-BriefDescription ParenthesizeSelection `
|
|
-LongDescription "Put parenthesis around the selection or entire line and move the cursor to after the closing parenthesis" `
|
|
-ScriptBlock {
|
|
param($key, $arg)
|
|
|
|
$selectionStart = $null
|
|
$selectionLength = $null
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::GetSelectionState([ref]$selectionStart, [ref]$selectionLength)
|
|
|
|
$line = $null
|
|
$cursor = $null
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
|
|
if ($selectionStart -ne -1) {
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::Replace($selectionStart, $selectionLength, '(' + $line.SubString($selectionStart, $selectionLength) + ')')
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($selectionStart + $selectionLength + 2)
|
|
}
|
|
else {
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::Replace(0, $line.Length, '(' + $line + ')')
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::EndOfLine()
|
|
}
|
|
}
|
|
|
|
# Cycle through quote styles on current token
|
|
Set-PSReadLineKeyHandler -Key "Alt+'" `
|
|
-BriefDescription ToggleQuoteArgument `
|
|
-LongDescription "Toggle quotes on the argument under the cursor" `
|
|
-ScriptBlock {
|
|
param($key, $arg)
|
|
|
|
$ast = $null
|
|
$tokens = $null
|
|
$errors = $null
|
|
$cursor = $null
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$ast, [ref]$tokens, [ref]$errors, [ref]$cursor)
|
|
|
|
$tokenToChange = $null
|
|
foreach ($token in $tokens) {
|
|
$extent = $token.Extent
|
|
if ($extent.StartOffset -le $cursor -and $extent.EndOffset -ge $cursor) {
|
|
$tokenToChange = $token
|
|
|
|
# If the cursor is at the end of the previous token, we only want to change the previous token if there is no token under the cursor
|
|
if ($extent.EndOffset -eq $cursor -and $foreach.MoveNext()) {
|
|
$nextToken = $foreach.Current
|
|
if ($nextToken.Extent.StartOffset -eq $cursor) {
|
|
$tokenToChange = $nextToken
|
|
}
|
|
}
|
|
break
|
|
}
|
|
}
|
|
|
|
if ($tokenToChange -ne $null) {
|
|
$extent = $tokenToChange.Extent
|
|
$tokenText = $extent.Text
|
|
if ($tokenText[0] -eq '"' -and $tokenText[-1] -eq '"') {
|
|
# Switch to no quotes
|
|
$replacement = $tokenText.Substring(1, $tokenText.Length - 2)
|
|
}
|
|
elseif ($tokenText[0] -eq "'" -and $tokenText[-1] -eq "'") {
|
|
# Switch to double quotes
|
|
$replacement = '"' + $tokenText.Substring(1, $tokenText.Length - 2) + '"'
|
|
}
|
|
else {
|
|
# Add single quotes
|
|
$replacement = "'" + $tokenText + "'"
|
|
}
|
|
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::Replace(
|
|
$extent.StartOffset,
|
|
$tokenText.Length,
|
|
$replacement)
|
|
}
|
|
}
|
|
|
|
# Replace aliases on command line with full commands
|
|
Set-PSReadLineKeyHandler -Key "Alt+%" `
|
|
-BriefDescription ExpandAliases `
|
|
-LongDescription "Replace all aliases with the full command" `
|
|
-ScriptBlock {
|
|
param($key, $arg)
|
|
|
|
$ast = $null
|
|
$tokens = $null
|
|
$errors = $null
|
|
$cursor = $null
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$ast, [ref]$tokens, [ref]$errors, [ref]$cursor)
|
|
|
|
$startAdjustment = 0
|
|
foreach ($token in $tokens) {
|
|
if ($token.TokenFlags -band [TokenFlags]::CommandName) {
|
|
$alias = $ExecutionContext.InvokeCommand.GetCommand($token.Extent.Text, 'Alias')
|
|
if ($alias -ne $null) {
|
|
$resolvedCommand = $alias.ResolvedCommandName
|
|
if ($resolvedCommand -ne $null) {
|
|
$extent = $token.Extent
|
|
$length = $extent.EndOffset - $extent.StartOffset
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::Replace(
|
|
$extent.StartOffset + $startAdjustment,
|
|
$length,
|
|
$resolvedCommand)
|
|
|
|
# Adjust by the difference in length
|
|
$startAdjustment += ($resolvedCommand.Length - $length)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# F1 for help on the command line
|
|
Set-PSReadLineKeyHandler -Key F1 `
|
|
-BriefDescription CommandHelp `
|
|
-LongDescription "Open the help window for the current command" `
|
|
-ScriptBlock {
|
|
param($key, $arg)
|
|
|
|
$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 [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 [AliasInfo]) {
|
|
$commandName = $command.ResolvedCommandName
|
|
}
|
|
|
|
if ($commandName -ne $null) {
|
|
Get-Help $commandName -ShowWindow
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Directory Marks Jumping system
|
|
$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()
|
|
}
|
|
|
|
# Make RightArrow accept the next word in prediction suggestion instead of whole line
|
|
Set-PSReadLineKeyHandler -Key RightArrow `
|
|
-BriefDescription ForwardCharAndAcceptNextSuggestionWord `
|
|
-LongDescription "Move cursor one character to the right in the current editing line and accept the next word in suggestion when it's at the end of current editing line" `
|
|
-ScriptBlock {
|
|
param($key, $arg)
|
|
|
|
$line = $null
|
|
$cursor = $null
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
|
|
|
|
if ($cursor -lt $line.Length) {
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::ForwardChar($key, $arg)
|
|
}
|
|
else {
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptNextSuggestionWord($key, $arg)
|
|
}
|
|
}
|
|
|
|
# Cycle/Select Command Arguments
|
|
Set-PSReadLineKeyHandler -Key Alt+a `
|
|
-BriefDescription SelectCommandArguments `
|
|
-LongDescription "Set current selection to next command argument in the command line. Use of digit argument selects argument by position" `
|
|
-ScriptBlock {
|
|
param($key, $arg)
|
|
|
|
$ast = $null
|
|
$cursor = $null
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$ast, [ref]$null, [ref]$null, [ref]$cursor)
|
|
|
|
$asts = $ast.FindAll( {
|
|
$args[0] -is [ExpressionAst] -and
|
|
$args[0].Parent -is [CommandAst] -and
|
|
$args[0].Extent.StartOffset -ne $args[0].Parent.Extent.StartOffset
|
|
}, $true)
|
|
|
|
if ($asts.Count -eq 0) {
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::Ding()
|
|
return
|
|
}
|
|
|
|
$nextAst = $null
|
|
|
|
if ($null -ne $arg) {
|
|
$nextAst = $asts[$arg - 1]
|
|
}
|
|
else {
|
|
foreach ($ast in $asts) {
|
|
if ($ast.Extent.StartOffset -ge $cursor) {
|
|
$nextAst = $ast
|
|
break
|
|
}
|
|
}
|
|
|
|
if ($null -eq $nextAst) {
|
|
$nextAst = $asts[0]
|
|
}
|
|
}
|
|
|
|
$startOffsetAdjustment = 0
|
|
$endOffsetAdjustment = 0
|
|
|
|
if ($nextAst -is [StringConstantExpressionAst] -and
|
|
$nextAst.StringConstantType -ne [StringConstantType]::BareWord) {
|
|
$startOffsetAdjustment = 1
|
|
$endOffsetAdjustment = 2
|
|
}
|
|
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($nextAst.Extent.StartOffset + $startOffsetAdjustment)
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::SetMark($null, $null)
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::SelectForwardChar($null, ($nextAst.Extent.EndOffset - $nextAst.Extent.StartOffset) - $endOffsetAdjustment)
|
|
}
|
|
|
|
Set-PSReadLineOption -PredictionSource History
|
|
Set-PSReadLineOption -PredictionViewStyle ListView
|
|
|
|
# dotnet build macro
|
|
Set-PSReadLineKeyHandler -Key Ctrl+Shift+b `
|
|
-BriefDescription BuildCurrentDirectory `
|
|
-LongDescription "Build the current directory" `
|
|
-ScriptBlock {
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::RevertLine()
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("dotnet build")
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
|
|
}
|
|
|
|
# dotnet test macro
|
|
Set-PSReadLineKeyHandler -Key Ctrl+Shift+t `
|
|
-BriefDescription BuildCurrentDirectory `
|
|
-LongDescription "Build the current directory" `
|
|
-ScriptBlock {
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::RevertLine()
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("dotnet test")
|
|
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
|
|
}
|
|
|
|
Set-PSReadLineOption -Colors @{
|
|
"Parameter" = [ConsoleColor]::DarkBlue
|
|
}
|
|
}
|
|
|
|
function DisableReadline {
|
|
if (Get-Command Set-PSReadLineOption -ErrorAction SilentlyContinue) {
|
|
Set-PSReadLineOption -PredictionSource None
|
|
}
|
|
}
|
|
|
|
function EnableReadline {
|
|
if (Get-Command Set-PSReadLineOption -ErrorAction SilentlyContinue) {
|
|
Set-PSReadLineOption -PredictionSource History
|
|
}
|
|
}
|