Skip to content

Instantly share code, notes, and snippets.

@drandarov-io
Last active April 22, 2025 17:43
Show Gist options
  • Save drandarov-io/ec6a51a1d4e256c322f496cb47ab704a to your computer and use it in GitHub Desktop.
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 -Global
Import-Module npm-completion -Global
Import-Module yarn-completion -Global
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 UsefulArgumentCompleters
Import-Module -ErrorAction Continue Microsoft.WinGet.CommandNotFound
# Fix for Set-Location if z is installed
Set-Alias Set-LocationZ ((Test-Path Function:cdX) ? "cdX" : "Set-Location")
#########################
# Variables
#########################
$UserPaths = @{
dev = "Y:/Dev"
ydev = "Y:/Dev"
xdev = "X:/Dev"
tools = "X:/Tools"
res = "X:/Res"
backup = "D:/Backup"
create = "D:/Create"
tmp = "D:/Temp"
img = "P:/Dev/Images"
media = "W:/Media"
dl = "$HOME/Downloads"
config = "$HOME/.dmi3"
}
Import-UserPaths $UserPaths
#########################
# Proxy Functions
#########################
# 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)`
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 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 }
# 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 }
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 } }
#########################
# Winget
#########################
# 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 }
}
$WingetFunctions.Keys | ForEach-Object { Set-Item function:$_ -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
###################################
# Prompt
###################################
# Configuration
Set-PSReadLineOption -PredictionSource HistoryAndPlugin
Set-PSReadLineOption -PredictionViewStyle ListView
Set-PSReadLineOption -MaximumHistoryCount 10000
Set-PSReadLineOption -BellStyle Audible -DingTone 300 -DingDuration 50
# Shortcuts
Set-PSReadlineKeyHandler Tab MenuComplete
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+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'
$env:WINFETCH_CONFIG_PATH = "$($UserPaths.config)/winfetch_config.ps1"
$env:POSH_THEME = "$($UserPaths.config)/dmitr.io.omp.json"
oh-my-posh init pwsh | Invoke-Expression
###################################
# Function fo migrate to library
###################################
function Expand-Folder {
param ([string]$Pattern, [switch]$PrependFolderName, [switch]$Copy)
$files = Get-ChildItem -Directory -Recurse -Filter $Pattern | Get-ChildItem -File
if (!$files) { Write-Host "No files match '$Pattern'."; return }
if ((Read-Host "$($Copy ? "Copy" : "Move") $($files.Count) files to $(Get-Location)? [Y/n]") -match '^[nN]$') { return }
$files | ForEach-Object {
$dest = $PrependFolderName ? "$(((Resolve-Path -Relative $_.Directory.FullName).Substring(2)) -replace '[\\/]', '_')`_$($_.Name)" : $_.Name
& ($Copy ? 'Copy-Item' : 'Move-Item') $_.FullName $dest
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment