Last active
July 2, 2024 10:09
-
-
Save drandarov-io/ec6a51a1d4e256c322f496cb47ab704a to your computer and use it in GitHub Desktop.
Personal PowerShell $PROFILE (drandarov-io)
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
# https://gist.github.com/drandarov-io/ec6a51a1d4e256c322f496cb47ab704a | |
######################### | |
# Modules | |
######################### | |
# General | |
Import-Module z | |
Import-Module Terminal-Icons | |
Import-Module Microsoft.WinGet.CommandNotFound | |
# Autocompleters | |
Import-Module UsefulArgumentCompleters | |
# Third party autocompleters (call ". cmp" to load) | |
function cmp { | |
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 kubectl -ErrorAction SilentlyContinue) { kubectl completion powershell | Out-String | Invoke-Expression } | |
Write-Host "Autocomplete modules loaded" | |
} | |
# Fix for Set-Location if z is installed | |
Set-Alias Set-LocationZ ((Test-Path Function:cdX) ? "cdX" : "Set-Location") | |
######################### | |
# Variables | |
######################### | |
$Global:USERPATHS = @{ | |
dev = "Y:/Dev" | |
ydev = "Y:/Dev" | |
xdev = "X:/Dev" | |
tools = "X:/Tools" | |
res = "X:/Res" | |
backup = "D:/Backup" | |
create = "D:/Create" | |
temp = "D:/Temp" | |
img = "P:/Dev/Images" | |
media = "W:/Media" | |
dl = "$env:USERPROFILE/Downloads" | |
config = "$env:USERPROFILE/.dmi3" | |
} | |
# Use [scriptblock]::Create() to avoid assigning a temporary variable in the prompt scope, since $_ is not accessible inside a scriptblock (It's about the principle) | |
$USERPATHS.Keys | ForEach-Object { Set-Item function:$_ -Value ([scriptblock]::Create("Set-LocationZ `$USERPATHS.$_ @args")) } | |
$USERPATHS.Keys | ForEach-Object { Set-Variable -Name $_ -Value $USERPATHS.$_ } | |
$Global:WALLPAPER = "$env:APPDATA/Microsoft/Windows/Themes/TranscodedWallpaper" | |
$Global:HOSTSPROFILE = $PROFILE.CurrentUserAllHosts | |
$Global:USERSCRIPTS = "$(Split-Path $PROFILE)/Scripts" | |
######################### | |
# Functions | |
######################### | |
# TODO Make compatible with pipelines | |
# TODO Create somthing like $input ?? $args[0] | ForEach-Object { ... } | |
function Edit-Profile { code $PROFILE @args } | |
function Get-PublicIP { param([switch]$IP6) $IP6 ? (curl -s -6 ipconfig.io) : (curl -s -4 ipconfig.io) } | |
function Get-Wallpaper { "$([Text.Encoding]::Unicode.GetString((Get-ItemProperty 'HKCU:\Control Panel\Desktop' TranscodedImageCache -ErrorAction Stop).TranscodedImageCache) -replace '(.+)([A-Z]:[0-9a-zA-Z\\])+','$2')" } | |
function Get-AdminStatus { ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) } | |
function Get-LocalGroupsAll { Get-LocalGroup | ForEach-Object { $group = $_.Name; Get-LocalGroupMember $group | Select-Object @{Name='GroupName';Expression={$group}}, * } } | |
function Select-And { $args[0] ? $args[0] : $args[1] } | |
function Select-Or { $args[0] ? $args[0] : $args[1] } | |
function Get-VariableRaw { Select-Zip $MyInvocation.Statement.Replace('Get-VariableRaw ', '').Split(' '), $MyInvocation.UnboundArguments | ForEach-Object { [PSCustomObject]@{Name = $_[0]; Value = $_[1]} } } | |
function Out-StringList { param([switch]$Stream) $args | Format-List * | Out-String -Stream:$Stream } | |
function Out-StringTable { param([switch]$Stream) $args | Format-Table * | Out-String -Stream:$Stream } | |
function Out-StringVariables { Out-StringTable (Get-VariableRaw $args) } | |
function Write-StringList { Write-Host (Out-StringList @args) } | |
function Write-StringTable { Write-Host (Out-StringTable @args) } | |
function Write-HLine { param([switch]$NoPadding=$false) Write-Host $("=" * [Console]::WindowWidth) ($NoPadding ? "" : "`n") } | |
function Get-Colors { [enum]::GetValues([ConsoleColor]) | Select-Object @{N='ColorObject';E={$_}}, @{N='ColorName'; E={ If ($_.ToString().substring(0,3) -eq 'Dar' ){ $_.ToString().Substring(4) + 'DARK' } else { $_.ToString() } } } | Sort-Object Colorname } | |
function Write-Colormap { $colors = Get-Colors; foreach ($bgcolor in $colors.ColorObject) { foreach ($fgcolor in $colors.ColorObject) { Write-Host "$fgcolor■" -ForegroundColor $fgcolor -BackgroundColor $bgcolor -NoNewLine; Write-Host " " -NoNewline } Write-Host " on $bgcolor" } } | |
function Get-LatestGitRelease { param($RepoName, $PatternWord) (Invoke-WebRequest "https://api.github.com/repos/$RepoName/releases/latest").Content | Select-String "(https:\/\/github\.com\/[^\/]+\/[^\/]+\/releases\/download\/[^\/]+\/[^\/]*$PatternWord[^\/]*\.zip)" | ForEach-Object { $_.Matches.Value } } | |
function Expand-WebArchive { param($Uri, $Path) $tempFile = New-TemporaryFile; Invoke-WebRequest $uri -OutFile $tempFile; Expand-Archive $tempFile $path; Remove-Item $tempFile } | |
function Add-DirToPath { param($Path=$PWD, [switch]$System) if (-not (Get-AdminStatus) -and $System) { "'-System' requires admin priviledges." } else { [Environment]::SetEnvironmentVariable('Path', "$env:Path;$(($Path | Resolve-Path) -join ';');", $System ? 'Machine' : 'User') } } | |
function Invoke-ParameterTest { process {Get-VariableRaw $params $PSBoundParamters $($input) $_ $args @args } } | |
function Invoke-ParameterTest2 { Get-VariableRaw $params $PSBoundParamters $($input) $_ $args @args } | |
function Invoke-CopyTranscodeIdf { ff copytranscode @args; idf $args[0] } | |
function Update-GitRecurse { Get-ChildItem -Directory -Force -Recurse *.git | ForEach-Object { Set-Location $_.Parent.FullName; Write-Host $_.Parent.FullName; git pull; Write-HLine }; Set-Location .. } # Recusively Update Git Repos | |
######################### | |
# Proxy Functions | |
######################### | |
# TODO Make compatible with pipelines | |
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 | |
function idf { Invoke-Item (Split-Path $args[0]) } # Invoke Directory of file | |
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 mergeobj { $obj1, $prop1, $obj2, $prop2 = $args; $obj1 | ForEach-Object { $p = $_; $obj2 | Where-Object { $p.$prop1 -eq $_.$prop2 } } } | |
# Filters | |
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]) } | |
######################### | |
# Winget | |
######################### | |
# Winget separated for autocomplete | |
$wgFunctions = @{ | |
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 } | |
} | |
$wgFunctions.Keys | ForEach-Object { Set-Item function:$_ -Value $wgFunctions.$_ } | |
######################### | |
# Autocompletion | |
######################### | |
# TODO Simplify | |
Register-ArgumentCompleter -Native -CommandName @($wgFunctions.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 ($wgFunctions.ContainsKey($_.Value)) { | |
return $wgFunctions[$_.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+P -Beep '. $PROFILE' 'Reload the Powershell profile' | |
Add-KeyboardShortcut Ctrl+Alt+Shift+M -Beep '. cmp' 'Load autocompletions' | |
Add-KeyboardShortcut Ctrl+UpArrow 'Set-LocationZ ..' 'Navigate to the directory above' | |
Add-KeyboardShortcut Shift+Ctrl+Alt+Y 'Set-LocationZ -' 'Navigate back in directory history' | |
Add-KeyboardShortcut Shift+Ctrl+Alt+X 'Set-LocationZ +' '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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment