Last active
February 6, 2026 11:03
-
-
Save viplyzbytes/5b8c7e835fd7bbfc4d92920c955a7bc2 to your computer and use it in GitHub Desktop.
Customized Powershell Profile
This file contains hidden or 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
| # A 'using' statement must appear before any other statements in a script. | |
| using namespace System.Management.Automation | |
| using namespace System.Management.Automation.Language | |
| # following lines add "ctrl+backspace" key inside vs-code powershell terminal instead of "ctel+w". | |
| <# | |
| if ($env:TERM_PROGRAM -eq "vscode") { | |
| Set-PSReadLineKeyHandler -Chord 'Ctrl+w' -Function BackwardKillWord | |
| } | |
| #> | |
| # fnm config for powershell | |
| fnm env --use-on-cd --version-file-strategy=recursive | Out-String | Invoke-Expression | |
| # Starship config file for powershell | |
| $ENV:STARSHIP_CONFIG = "C:\Users\iam_v\.config\starship-pwsh.toml" | |
| # invoking starship on start of powershell | |
| Invoke-Expression (&starship init powershell) | |
| # PSReadLine Custom Options taken from Scott Hanselman's powershell and tim sneath gists. | |
| Import-Module PSReadLine | |
| Set-PSReadLineKeyHandler -key Tab -Function Complete | |
| Set-PSReadLineOption -PredictionSource HistoryAndPlugin | |
| Set-PSReadLineOption -HistoryNoDuplicates | |
| Set-PSReadLineOption -PredictionViewStyle Inline | |
| Set-PSReadLineOption -EditMode Windows | |
| # This key handler shows the entire or filtered history using Out-GridView. The typed text is used as the substring pattern for filtering. | |
| # A selected command is inserted to the command line without invoking. Multiple command selection is supported, e.g. selected by Ctrl + Click. | |
| 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")) | |
| } | |
| } | |
| # 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) | |
| } | |
| } | |
| } | |
| # F1 for help on the command line - naturally | |
| 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 | |
| } | |
| } | |
| } | |
| } | |
| # Oh-My-Posh settings | |
| <# Install OMP: | |
| winget install JanDeDobbeleer.OhMyPosh -s winget | |
| #> | |
| # Created variables for OMP theme. | |
| # In order to change theme just change .json theme in $OMPThemePath | |
| #$OMPThemesFolder = $($env:APPDATA)+'\..\Local\Programs\oh-my-posh\themes\' | |
| #$OMPThemePath = $OMPThemesFolder + 'powerlevel10k_rainbow.omp.json' | |
| #oh-my-posh init pwsh --config $OMPThemePath | Invoke-Expression | |
| # Terminal Icons | |
| Import-Module -Name Terminal-Icons | |
| # this is single line comment | |
| <# Block-Comment | |
| To change theme, replace name of the theme with the one you want to install, i.e. the word after ..\themes\ and keep extension as ".omp.json" | |
| After changing theme, apply the current profile by giving ".$PROFILE" command in powershell. | |
| My Favoriate themes: | |
| 1. tokyo | |
| 2. quick-term | |
| 3. emodipt-extend | |
| 4. slim | |
| 5. space | |
| 6. plague | |
| 7. powerlevel10k_rainbow | |
| 8. montys | |
| 9. kushal | |
| Install **file type icons** type command: | |
| Install-Module -Name Terminal-Icons -Repository PSGallery | |
| and then add following command to profile file of powershell: | |
| Import-Module -Name Terminal-Icons | |
| To install Z use coommand: | |
| install-module -name z -force | |
| To install PSReadLine: | |
| install-module -name PSReadLine -AllowPrerelease -scope CurrentUser -force -SkipPublisherCheck | |
| Options for PSReadLine: | |
| set-PSReadLineOption -PredictionSource History | |
| restart terminal/shell | |
| set-PSReadLineOption -PredictionViewStyle ListView | |
| #> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment