Created
June 8, 2026 19:47
-
-
Save benjar12sc/92cf6eb83303a17bdcb28c1d5f3965b8 to your computer and use it in GitHub Desktop.
make windows feel more like zsh
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
| # ============================================================================== | |
| # 1. Shell Environment & Initialization | |
| # ============================================================================== | |
| # Eject the default, outdated PSReadLine module from memory | |
| Remove-Module PSReadLine -ErrorAction SilentlyContinue | |
| # Import the newly installed version | |
| Import-Module PSReadLine | |
| # PSReadLine Configurations | |
| Set-PSReadLineOption -PredictionSource History | |
| Set-PSReadLineOption -PredictionViewStyle ListView | |
| # Starship Prompt (Renders the Unix look and feel) | |
| if (Get-Command starship -ErrorAction SilentlyContinue) { | |
| Invoke-Expression (&starship init powershell) | |
| } | |
| # Zoxide (Smart directory jumper) | |
| if (Get-Command zoxide -ErrorAction SilentlyContinue) { | |
| Invoke-Expression (& { (zoxide init powershell | Out-String) }) | |
| } | |
| # ============================================================================== | |
| # 2. Core Unix Utilities & Environment Shims | |
| # ============================================================================== | |
| # Quick Directory Navigation | |
| function .. { Set-Location .. } | |
| function ... { Set-Location ../.. } | |
| function .... { Set-Location ../../.. } | |
| # 'la' and 'll' implementations (Handles hidden files and long lists) | |
| function la { | |
| if (Get-Command eza -ErrorAction SilentlyContinue) { | |
| eza -a @args | |
| } else { | |
| Get-ChildItem -Path $PWD.ProviderPath -Force @args | |
| } | |
| } | |
| function ll { | |
| if (Get-Command eza -ErrorAction SilentlyContinue) { | |
| eza -la @args | |
| } else { | |
| Get-ChildItem -Path $PWD.ProviderPath -Force @args | Format-Table Attributes, Name, @{Name="Size(KB)";Expression={[math]::round($_.Length / 1KB, 2)}}, LastWriteTime | |
| } | |
| } | |
| # 'which' implementation (Returns exact path of executable or function) | |
| function which ($command) { | |
| $cmd = Get-Command $command -ErrorAction SilentlyContinue | |
| if ($cmd) { | |
| $cmd | Select-Object -ExpandProperty Source | |
| } else { | |
| Write-Error "Command not found: $command" | |
| } | |
| } | |
| # 'touch' implementation (Create empty file or update timestamp) | |
| function touch ($file) { | |
| if (Test-Path $file) { | |
| (Get-Item $file).LastWriteTime = Get-Date | |
| } else { | |
| New-Item -ItemType File -Path $file -Force | Out-Null | |
| } | |
| } | |
| # 'ln' implementation (Handles standard symbolic links) | |
| # Usage: ln -s target_path link_path | |
| function ln { | |
| param([string]$arg1, [string]$arg2, [string]$arg3) | |
| if ($arg1 -eq "-s") { | |
| New-Item -ItemType SymbolicLink -Path $arg3 -Value $arg2 | |
| } else { | |
| New-Item -ItemType HardLink -Path $arg2 -Value $arg1 | |
| } | |
| } | |
| # Bash-style 'alias' function wrapper | |
| # Usage: alias ll="ls -la" or alias mycmd="git status" | |
| function alias { | |
| param([string]$expression) | |
| if (-not $expression -or -not ($expression -contains "=")) { | |
| Get-Alias | Select-Object Name, Definition | |
| return | |
| } | |
| $name, $definition = $expression -split '=', 2 | |
| $name = $name.Trim() | |
| $definition = $definition.Trim().Trim('"').Trim("'") | |
| if (-not ($definition -match '\s')) { | |
| Set-Alias -Name $name -Value $definition -Scope Global -Force | |
| } else { | |
| ScriptBlock::Create("function Global:$name { $definition `$args }") | Invoke-Command | |
| } | |
| } | |
| # 'export' implementation (Sets environment variables for the current session) | |
| # Usage: export MY_VAR="value" | |
| function export { | |
| param([string]$expression) | |
| if ($expression -match '=') { | |
| $name, $value = $expression -split '=', 2 | |
| $value = $value.Trim('"').Trim("'") | |
| [System.Environment]::SetEnvironmentVariable($name, $value, "Process") | |
| } | |
| } | |
| # 'ps' implementation (Supports 'aux' syntax and converts objects to searchable text lines) | |
| # Usage: ps aux | grep node | |
| function ps { | |
| param([string]$flags) | |
| if ($flags -match 'a|u|x') { | |
| Get-Process | ForEach-Object { | |
| [PSCustomObject]@{ | |
| PID = $_.Id | |
| Name = $_.ProcessName | |
| CPU = [math]::Round($_.CPU, 2) | |
| WS_MB = [math]::Round($_.WorkingSet / 1MB, 2) | |
| Id = $_.Id | |
| } | |
| } | Out-String -Stream | |
| } else { | |
| Get-Process @args | |
| } | |
| } | |
| # 'pkill' implementation (Kill processes easily by application name) | |
| # Usage: pkill node | |
| function pkill ($name) { | |
| Stop-Process -Name $name -Force -ErrorAction SilentlyContinue | |
| } | |
| # Clear Terminal Shorthand | |
| Set-Alias -Name c -Value Clear-Host | |
| # ============================================================================== | |
| # 3. Modern CLI Upgrades (Dynamic Mappings with Force Teardown) | |
| # ============================================================================== | |
| # Forcefully remove built-in locked aliases so our modern binaries can take over | |
| if (Get-Alias cat -ErrorAction SilentlyContinue) { Remove-Item alias:\cat -Force -ErrorAction SilentlyContinue } | |
| if (Get-Alias ls -ErrorAction SilentlyContinue) { Remove-Item alias:\ls -Force -ErrorAction SilentlyContinue } | |
| if (Get-Alias grep -ErrorAction SilentlyContinue) { Remove-Item alias:\grep -Force -ErrorAction SilentlyContinue } | |
| # Drop-in modern CLI tools if they are available on the machine | |
| if (Get-Command bat -ErrorAction SilentlyContinue) { Set-Alias cat bat } | |
| if (Get-Command eza -ErrorAction SilentlyContinue) { Set-Alias ls eza } | |
| if (Get-Command fd -ErrorAction SilentlyContinue) { Set-Alias find fd } | |
| # Prioritize ripgrep -> system native grep -> custom object function match | |
| if (Get-Command rg -ErrorAction SilentlyContinue) { | |
| Set-Alias grep rg | |
| } elseif (Get-Command grep -ErrorAction SilentlyContinue) { | |
| # Let system-installed native GNU grep.exe execute directly | |
| } else { | |
| function grep ($pattern, $path="*") { Select-String -Pattern $pattern -Path $path } | |
| } | |
| # ============================================================================== | |
| # 4. Custom Functions & Shortcuts | |
| # ============================================================================== | |
| # Fixed Hist Function (Safe from quote parsing errors) | |
| function hist { | |
| param([string]$Find) | |
| $HistoryPath = (Get-PSReadlineOption).HistorySavePath | |
| if (-not $Find) { | |
| Get-Content $HistoryPath | Get-Unique | more | |
| return | |
| } | |
| Write-Host "Searching history for: $Find" -ForegroundColor Cyan | |
| Get-Content $HistoryPath | Where-Object { $_ -like "*$Find*" } | Get-Unique | more | |
| } | |
| # Git Shortcuts | |
| function gs { git status @args } | |
| function ga { git add @args } | |
| function gc { git commit @args } | |
| function gcm { git commit -m $args[0] } | |
| function gp { git push @args } | |
| # ============================================================================== | |
| # 5. External Tooling Integrations (Chocolatey, etc.) | |
| # ============================================================================== | |
| $ChocolateyProfile = "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1" | |
| if (Test-Path($ChocolateyProfile)) { | |
| Import-Module "$ChocolateyProfile" | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment