Created
June 7, 2022 00:23
-
-
Save Lunchb0ne/106d90737dcbf2e0e12089880eec03e5 to your computer and use it in GitHub Desktop.
My PowershellCore Profile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ~/Documents/PowerShell/Microsoft.PowerShell_profile.ps1 | |
Invoke-Expression (&starship init powershell) | |
# Zoxide invoker | |
Invoke-Expression (& { | |
$hook = if ($PSVersionTable.PSVersion.Major -lt 6) { 'prompt' } else { 'pwd' } | |
(zoxide init --hook $hook powershell) -join "`n" | |
}) | |
# GitKraken function | |
Function Launch-GitKraken { | |
Start-Process -FilePath "$home\AppData\Local\gitkraken\update.exe" -ArgumentList "--processStart=gitkraken.exe","--process-start-args=`"-p `"$(Get-Location)`"`"" | |
} | |
# Some Aliases | |
Set-Alias -Name "ls" -Value lsd | |
Set-Alias -Name "cat" -Value bat | |
Set-Alias -Name "kraken" -Value Launch-GitKraken | |
# Some Imports that I use | |
Import-Module "$($(Get-Item $(Get-Command scoop).Path).Directory.Parent.FullName)\modules\scoop-completion" | |
(& volta completions powershell) | Out-String | Invoke-Expression # Completions for Volta | |
Import-Module PSReadLine | |
# QOL Functions: | |
Function l { | |
ls -l | |
} | |
Set-PsFzfOption -TabExpansion # Tab Expansion Enable | |
# Enable History search for completions | |
Set-PSReadLineOption -PredictionSource History | |
Set-PSReadLineKeyHandler -Key Tab -ScriptBlock { Invoke-FzfTabCompletion } # Use FZF for completions | |
Set-PsFzfOption -PSReadlineChordProvider 'Ctrl+t' -PSReadlineChordReverseHistory 'Ctrl+r' # Override Ctrl+t and Ctrl+r | |
Set-PSReadLineKeyHandler -Key Alt+Backspace -Function BackwardKillWord | |
Set-PSReadLineKeyHandler -Key Alt+Delete -Function KillWord | |
Set-PSReadLineOption -EditMode Emacs # Force emacs mode | |
Set-PSReadlineOption -BellStyle None #Disable the bell | |
# Clipboard interaction is bound by default in Windows mode, but not Emacs mode. | |
Set-PSReadLineKeyHandler -Key Ctrl+C -Function Copy | |
Set-PSReadLineKeyHandler -Key Ctrl+v -Function Paste | |
# `ForwardChar` accepts the entire suggestion text when the cursor is at the end of the line. | |
# This custom binding makes `RightArrow` behave similarly - accepting the next word instead of the entire suggestion text. | |
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) | |
} | |
} | |
#region Smart Insert/Delete | |
# The next four key handlers are designed to make entering matched quotes | |
# parens, and braces a nicer experience. I'd like to include functions | |
# in the module that do this, but this implementation still isn't as smart | |
# as ReSharper, so I'm just providing it as a sample. | |
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment