Skip to content

Instantly share code, notes, and snippets.

@drandarov-io
Last active November 9, 2025 17:05
Show Gist options
  • Select an option

  • Save drandarov-io/ec6a51a1d4e256c322f496cb47ab704a to your computer and use it in GitHub Desktop.

Select an option

Save drandarov-io/ec6a51a1d4e256c322f496cb47ab704a to your computer and use it in GitHub Desktop.
Personal PowerShell $PROFILE (drandarov-io)
# https://gist.github.com/drandarov-io/ec6a51a1d4e256c322f496cb47ab704a
#########################
# Modules
#########################
# Delayed loading of some modules and completions for startup speed
Register-EngineEvent -SourceIdentifier 'PowerShell.OnIdle' -MaxTriggerCount 1 -Action {
Import-Module Terminal-Icons
Import-Module Microsoft.WinGet.CommandNotFound
Import-Module npm-completion
Import-Module yarn-completion
# if (Get-Command git -ErrorAction SilentlyContinue) { Import-Module posh-git }
# if (Get-Command helm -ErrorAction SilentlyContinue) { helm completion powershell | Out-String | Invoke-Expression }
# if (Get-Command docker -ErrorAction SilentlyContinue) { docker completion powershell | Out-String | Invoke-Expression }
# if (Get-Command podman -ErrorAction SilentlyContinue) { podman completion powershell | Out-String | Invoke-Expression }
# if (Get-Command kubectl -ErrorAction SilentlyContinue) { kubectl completion powershell | Out-String | Invoke-Expression }
# if (Get-Command minikube -ErrorAction SilentlyContinue) { minikube completion powershell | Out-String | Invoke-Expression }
} | Out-Null
Import-Module z
Import-Module UsefulArgumentCompleters
#########################
# Proxy Functions
#########################
# My wishful idea would be to have something that could be used as follows: New-ProxyFunction -Name helf -Command Get-Help -DefaultParameters '-Full' (similar to New-Alias syntax),
# which would create the appropriate proxy function with $PSBoundParameters['Full'] = $true in its begin block or even a String concatination.
# The only idea I'd have, would be to use String manipulation to do this with the resulting String from [Management.Automation.ProxyCommand]::Create(...)
# Forwarding function with autocomplete
# https://stackoverflow.com/questions/78674503/powershell-how-to-do-autocompletion-for-proxy-functions
# https://devblogs.microsoft.com/scripting/proxy-functions-spice-up-your-powershell-core-cmdlets/
# https://www.reddit.com/r/PowerShell/comments/7ht0dk/passthrough_parameters_in_scripts_and_functions/
# https://livebook.manning.com/book/powershell-in-depth/chapter-37/
# https://devblogs.microsoft.com/powershell/extending-andor-modifing-commands-with-proxies/
# TODO Move to POWERFUNCTIONS
# MAKE A PROXY FUNCTIONLIBRARY
# TODO Make compatible with pipelines (?? or Select-Or)
# TODO Check whether it makes sence to create proxy functions with proper names like Get-HelpFull and then as an additional parameter create an alias like helf
# Create method for `Compare-Object -ReferenceObject $allItemsMeasure -DifferenceObject $filteredItemsMeasure -Property ($allItemsMeasure | Get-Member -MemberType Property | Select Name)`
# Fix for Set-Location if z is installed
Set-Alias Set-LocationZ ((Test-Path Function:cdX) ? "cdX" : "Set-Location")
function c { $args ? (code @args) : (code './') }
function c. { Set-LocationZ .. @args }
function c+ { Set-LocationZ + @args }
function c_ { Set-LocationZ - @args }
function cdf { Set-LocationZ (Split-Path $args[0]) } # Change Directory to file parent
function id { $args ? (Invoke-Item @args) : (Invoke-Item ./) } # Invoke Directory # TODO pipelines
function idf { Invoke-Item (Split-Path $args[0]) } # Invoke Directory of file # TODO pipelines
function idc { Write-Host (Get-Command $args[0]).Source; Invoke-Item (Split-Path(Get-Command $args[0]).Source) }
function wtd { wt -d . @args }
function helf { Get-Help -Full @args }
function lr { Get-ChildItem -Recurse @args }
function ll { Get-ChildItem -Force @args }
function lf { Get-ChildItem -File @args }
function lfr { Get-ChildItem -File -Recurse @args }
function co { gh copilot @args }
function coe { gh copilot explain @args }
function cos { gh copilot suggest @args }
function gtc { git clone @args }
function gtp { git pull @args }
function sds { $input | Out-String -Stream | Select-String @args } # grep style
function selext { $input | Select-Object -ExpandProperty @args }
function tablew { $input | Format-Table -Wrap @args }
function sudops { sudo.exe pwsh -e ([Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($args))) }
# Filters
filter md5 { Select-Or $_ $args[0] | Get-FileHash -Algorithm MD5 }
filter sha1 { Select-Or $_ $args[0] | Get-FileHash -Algorithm SHA1 }
filter sha256 { Select-Or $_ $args[0] | Get-FileHash -Algorithm SHA256 }
filter crc32 { 7z h -scrcCRC32 @args }
filter crc64 { 7z h -scrcCRC64 @args }
# Good Test for Pipelines vs Direct
# - s* ABC -> Select-Object -InputObject (gcm Parallel-Transcode) -Property *
# - ABC | s* -> ABC | Select-Object -Property *
filter s* { ($_ ? ($_ | Select-Object * @args) : (Select-Object * @args)) } # Example for Alias for Filters
filter suffix { ($_ ? $_ : $args[0]) -replace '\.[^.]+$', "$($_ ? $args[0] : $args[1])$&" }
filter ext { [IO.Path]::ChangeExtension($_ ? $_ : $args[0], $_ ? $args[0] : $args[1]) }
filter head { $_ ? ($_ | Get-Content -Head ($args[0] ? $args[0] : 10)) : (Get-Content -Head ($args[1] ? $args[1] : 10) $args[0]) }
filter tail { $_ ? ($_ | Get-Content -Tail ($args[0] ? $args[0] : 10)) : (Get-Content -Tail ($args[1] ? $args[1] : 10) $args[0]) }
filter Test-Empty { param([System.Collections.IEnumerable]$InputObject) ($InputObject.Count -eq 0) -or ($InputObject.Length -eq 0) }
filter Test-Blank { param([string]$InputObject) (Test-Empty ($InputObject.Trim())) }
filter Test-Null { Select-InputOrArgs | ForEach-Object { $_ -ne $null } }
#########################
# Alias / Paths
#########################
$UserPaths = @{
dev = "X:/"
tools = "F:/Tools"
res = "F:/Res"
backup = "D:/Backup"
create = "D:/Create"
tmp = "D:/Temp"
img = "P:/Dev/Images"
media = "W:/Media"
lnk = "F:/Tools/.lnk"
dl = "$HOME/Downloads"
config = "$HOME/.d7v"
}
# Winget separated for autocomplete
$WingetFunctions = @{
wu = { winget upgrade @args }
wui = { winget upgrade -i @args }
wuiu = { winget upgrade --include-unknown @args }
wi = { winget install @args }
wii = { winget install -i @args }
wr = { winget uninstall @args }
wri = { winget uninstall -i @args }
ws = { winget search @args }
wsho = { winget show @args }
wl = { winget list @args }
}
$UserPaths.Keys | ForEach-Object { Set-Variable -Scope Global -Name $_ -Value $UserPaths.$_ }
$UserPaths.Keys | ForEach-Object { Set-Item "Function:\global:$_" -Value ([ScriptBlock]::Create("Set-LocationZ $($UserPaths.$_) @args")) }
$WingetFunctions.Keys | ForEach-Object { Set-Item "Function:\global:$_" -Value $WingetFunctions.$_ }
#########################
# Autocompletion
#########################
# TODO Simplify
Register-ArgumentCompleter -Native -CommandName @($WingetFunctions.Keys; 'winget'; 'winget.exe') -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
Write-StringList (Get-VariableRaw $wordToComplete $commandAst $cursorPosition)
$word = $wordToComplete.Replace('"', '""')
$ast = $commandAst.ToString().Replace('"', '""')
$new_ast = $ast -replace '^[a-z]*', {
if ($WingetFunctions.ContainsKey($_.Value)) {
return $WingetFunctions[$_.Value].ToString().Replace("@args", "").Trim()
}
return $_.Value
}
if ($ast -ne $new_ast) { $cursorPosition += $new_ast.Length - $ast.Length}
winget complete --word="$word" --commandline "$new_ast" --position $cursorPosition | ForEach-Object {
[Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
}
# function UserPathCompleter {
# param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
# # Check if the variable $media exists and is a string
# if ($global:media -and ($global:media -is [string])) {
# # Add a trailing slash if not present
# $completion = if ($global:media[-1] -ne '\') { "$global:media\" } else { $global:media }
# # Return completion result
# $completion
# }
# }
# Register-ArgumentCompleter -CommandName Get-ChildItem -ParameterName Path -ScriptBlock $function:UserPathCompleter
# Register-ArgumentCompleter -CommandName * -ParameterName * -ScriptBlock {
# param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
# $proj = "W:/Media"
# [Management.Automation.CompletionResult]::new("~proj", "~proj", 'Variable', "Custom variable for projects directory")
# }
function Add-KeyboardShortcut {
param($shortcut, $text, $description="", [switch]$beep)
Set-PSReadLineKeyHandler $shortcut -Description $description {
[Microsoft.PowerShell.PSConsoleReadLine]::RevertLine()
[Microsoft.PowerShell.PSConsoleReadLine]::RevertLine() # Once doesn't always work 🙄
[Microsoft.PowerShell.PSConsoleReadLine]::Insert($text)
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
if ($beep) { [Microsoft.PowerShell.PSConsoleReadLine]::Ding() }
}.GetNewClosure()
}
#########################
# Aliases
#########################
# General
Set-Alias e Write-Output
Set-Alias l Get-ChildItem
Set-Alias json> ConvertFrom-Json
Set-Alias json< ConvertTo-Json
Set-Alias fromjson ConvertFrom-Json
Set-Alias tojson ConvertTo-Json
Set-Alias table Format-Table
Set-Alias list Format-List
Set-Alias s Select-Object
# Diagnostic
Set-Alias sysinfo Get-ComputerInfo
Set-Alias psd Get-PSDrive
# My functions
Set-Alias ?or Select-Or
Set-Alias ?and Select-And
Set-Alias osl Out-StringList
Set-Alias cop Edit-Profile
# Third party tools
Set-Alias wfe winfetch
Set-Alias wcr wingetcreate
Set-Alias ig ImageGlass
Set-Alias nixgui mkvtoolnix-gui
Set-Alias ai Start-AIShell
###################################
# Prompt
###################################
$env:WINFETCH_CONFIG_PATH = "$($UserPaths.config)/winfetch_config.ps1"
$env:POSH_THEME = "$($UserPaths.config)/d7v.io.omp.json"
$env:CW = Get-Date -UFormat %V
function composh { $env:POSH_COMPACT = if ($env:POSH_COMPACT) { "" } else { "1" }; setx POSH_COMPACT $env:POSH_COMPACT >$null 2>&1 }
oh-my-posh init pwsh --config "$env:POSH_THEME" | Invoke-Expression
# Configuration
Set-PSReadLineOption -PredictionSource HistoryAndPlugin
Set-PSReadLineOption -PredictionViewStyle ListView
Set-PSReadLineOption -MaximumHistoryCount 10000
Set-PSReadLineOption -BellStyle Audible -DingTone 300 -DingDuration 50
Set-PSReadLineOption -ContinuationPrompt ""
Set-PSReadlineKeyHandler Tab MenuComplete
# Shortcuts
Add-KeyboardShortcut Ctrl+Alt+Shift+C -Beep 'Clear-Host' 'Clear the console'
Add-KeyboardShortcut Ctrl+Alt+Shift+R -Beep '. $PROFILE' 'Reload the Powershell profile'
Add-KeyboardShortcut Ctrl+Alt+Shift+F 'composh' 'Switch between POSH compact and full prompt'
Add-KeyboardShortcut Ctrl+UpArrow 'cd ..' 'Navigate to the directory above'
Add-KeyboardShortcut Ctrl+Shift+Z 'cd -' 'Navigate back in directory history'
Add-KeyboardShortcut Ctrl+Shift+X 'cd +' 'Navigate forward in directory history'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment