-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMicrosoft.PowerShell_profile.ps1
More file actions
229 lines (201 loc) · 9.35 KB
/
Microsoft.PowerShell_profile.ps1
File metadata and controls
229 lines (201 loc) · 9.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# ===================================================================================
# PowerShell Profile for the Advanced User
# Author: Jules
# Focus: Performance, Efficiency, and Powerful Keyboard-Driven Workflows
# ===================================================================================
# --- 1. CORE SETUP & PERFORMANCE ---
# Record start time for performance metrics.
$script:ProfileLoadStart = Get-Date
# Centralized directory for logs and cache.
$script:ProfileDataDir = Join-Path $HOME ".powershell_profile"
if (-not (Test-Path $script:ProfileDataDir)) {
New-Item -ItemType Directory -Path $script:ProfileDataDir -Force | Out-Null
}
$script:ErrorLogFile = Join-Path $script:ProfileDataDir "error.log"
# Global error logging for profile loading issues.
trap {
$errorMessage = "PROFILE LOAD ERROR: $($_.Exception.Message) at $($_.InvocationInfo.PositionMessage)"
Add-Content -Path $script:ErrorLogFile -Value $errorMessage
continue # Don't block the shell from starting.
}
# --- 2. ESSENTIAL MODULES & PROMPT ---
# These are critical for the interactive experience and are loaded upfront.
# Others will be lazy-loaded.
Import-Module PSReadLine -ErrorAction SilentlyContinue
Import-Module posh-git -ErrorAction SilentlyContinue
Import-Module Terminal-Icons -ErrorAction SilentlyContinue
# High-performance, custom prompt function. No external dependencies.
function prompt {
# --- Execution Time ---
$history = Get-History -Count 1
$execTime = if ($history) {
$duration = $history.EndExecutionTime - $history.StartExecutionTime
if ($duration.TotalMilliseconds > 100) { " [$([math]::Round($duration.TotalMilliseconds))ms]" }
}
# --- Path ---
$fullPath = $ExecutionContext.SessionState.Path.CurrentLocation.Path
$homePath = $fullPath.Replace($HOME, "~")
$promptPath = Split-Path -Path $homePath -Parent | ForEach-Object { "$($_ | Split-Path -Leaf)\" }
$promptPath = "$($promptPath)$($homePath | Split-Path -Leaf)"
# --- Git Status ---
$gitStatus = if ($GitPromptSettings.EnableFileStatus) {
$status = $GitPromptSettings.AnsiFileStatus
$promptGit = " ($($status.Branch$($status.FileStatus)))"
}
# --- Admin Indicator ---
$adminMark = if (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
" [ADMIN]"
}
# --- Assemble Prompt ---
"PS $($promptPath)$($promptGit)$($adminMark)$($execTime)`n❯ "
}
# --- 3. PSREADLINE CONFIGURATION (KEYBOARD-FIRST) ---
Set-PSReadLineOption -EditMode Windows `
-HistorySavePath (Join-Path $script:ProfileDataDir "history.txt") `
-MaximumHistoryCount 10000 `
-HistoryNoDuplicates `
-PredictionSource History `
-PredictionViewStyle ListView
# --- 3a. FZF INTEGRATION (KEYBOARD-FIRST) ---
# Check for fzf before setting up integrations.
if (Get-Command fzf -ErrorAction SilentlyContinue) {
# Custom keybindings for fzf integration and efficiency.
Set-PSReadLineKeyHandler -Key 'Ctrl+r' -Function HistorySearchBackward
Set-PSReadLineKeyHandler -Key 'Ctrl+f' -ScriptBlock {
# Fuzzy find file and insert into command line
$file = (Get-ChildItem -Recurse -File -ErrorAction SilentlyContinue | fzf)
if ($null -ne $file) {
[Microsoft.PowerShell.PSConsoleReadLine]::Insert($file.FullName)
}
}
Set-PSReadLineKeyHandler -Key 'Alt+c' -ScriptBlock {
# Fuzzy find directory and cd into it
$dir = (Get-ChildItem -Recurse -Directory -ErrorAction SilentlyContinue | fzf)
if ($null -ne $dir) {
Set-Location $dir.FullName
}
}
} else {
Write-Warning "fzf not found. Advanced file search and Git keybindings (Ctrl+f, Alt+c) are disabled."
}
# --- 4. CORE ALIASES & UTILITIES ---
Set-Alias ll Get-ChildItem -Option AllScope
Set-Alias la 'Get-ChildItem -Force' -Option AllScope
Set-Alias .. 'Set-Location ..'
Set-Alias ... 'Set-Location ..\..'
# Edit profile with preferred editor.
$script:EDITOR = "code" # Default to VS Code
function ep { & $script:EDITOR $PROFILE } # Edit Profile
function rp { . $PROFILE } # Reload Profile
# Quick file operations
function mkcd($d) { mkdir $d -Force; Set-Location $d }
function cpy($t) { Set-Clipboard $t; Write-Host "Copied to clipboard." }
# --- 5. ADVANCED GIT & DOCKER TOOLING (FZF INTEGRATION) ---
if (Get-Command fzf -ErrorAction SilentlyContinue) {
function fig { # Fuzzy Interactive Git Log
git log --graph --color=always --format="%C(auto)%h%d %s %C(green)(%cr) %C(bold blue)<%an>%Creset" |
fzf --ansi --no-sort --reverse --tiebreak=index --bind=ctrl-d:preview-page-down,ctrl-u:preview-page-up --preview="echo {} | grep -o '[a-f0-9]\{7\}' | head -1 | xargs -I@ git show --color=always @" |
grep -o '[a-f0-9]\{7\}' | head -1 |
xargs -I@ git show --color=always @
}
function fib { # Fuzzy Interactive Branch
git branch -a --color=always | grep -v '/HEAD\s' |
fzf --ansi --no-sort --reverse --tiebreak=index --preview="echo {} | sed 's/..//' | cut -d' ' -f2 | xargs -I@ git log --graph --color=always --format='%C(auto)%h%d %s %C(green)(%cr) %C(bold blue)<%an>%Creset' @" |
sed 's/..//' | cut -d' ' -f2 |
xargs -I@ git checkout @
}
function fic { # Fuzzy Interactive Checkout (File)
git ls-files | fzf --preview="git diff --color=always {}" | xargs -I@ git checkout @
}
if (Get-Command docker -ErrorAction SilentlyContinue) {
function dexec { # Docker Exec Interactive
$container = docker ps | fzf | awk '{print $1}'
if ($container) {
docker exec -it $container /bin/bash
}
}
} else {
Write-Warning "Docker not found. The 'dexec' function is disabled."
}
}
# --- 6. DYNAMIC PROJECT ENVIRONMENT ---
# Looks for a .env file and loads it into the session.
function Set-ProjectEnv {
$envFile = Join-Path (Get-Location) ".env"
if (Test-Path $envFile) {
Get-Content $envFile | ForEach-Object {
$line = $_.Trim()
if ($line -and !$line.StartsWith("#")) {
$key, $value = $line -split '=', 2
if ($key -and $value) {
Write-Verbose "Setting env var: $($key.Trim())"
[Environment]::SetEnvironmentVariable($key.Trim(), $value.Trim(), "Process")
}
}
}
Write-Host "Loaded environment variables from .env" -ForegroundColor Cyan
}
}
# --- 7. HIGH-EFFICIENCY SYSTEM & NETWORK DIAGNOSTICS ---
function Get-TopProcesses {
param([ValidateSet("CPU", "Memory")][string]$SortBy = "CPU")
if ($SortBy -eq "CPU") {
Get-Process | Sort-Object -Property CPU -Descending | Select-Object -First 10
} else {
Get-Process | Sort-Object -Property WorkingSet -Descending | Select-Object -First 10
}
}
function Find-PortUser {
param([Parameter(Mandatory=$true)][int]$Port)
$procId = (netstat -ano | findstr ":$Port" | findstr "LISTENING" | Select-Object -First 1).Trim().Split()[-1]
if ($procId) {
Get-Process -Id $procId
} else {
Write-Host "No process found listening on port $Port." -ForegroundColor Yellow
}
}
# --- 8. LAZY-LOADED MODULES & FUNCTIONS ---
# These functions will import their required modules on first use.
function Update-AllPackages {
Write-Host "Running package manager updates..." -ForegroundColor Cyan
if (Get-Command winget -ErrorAction SilentlyContinue) {
Write-Host "Updating Winget packages..."
winget upgrade --all --accept-source-agreements --accept-package-agreements
}
if (Get-Command choco -ErrorAction SilentlyContinue) {
Write-Host "Updating Chocolatey packages..."
choco upgrade all -y
}
if (Get-Command scoop -ErrorAction SilentlyContinue) {
Write-Host "Updating Scoop packages..."
scoop update *
}
Write-Host "Updating PowerShell modules..."
Update-Module -Force -AcceptLicense -ErrorAction SilentlyContinue
}
function Get-SystemHealth {
Write-Host "`n=== System Health Snapshot ===" -ForegroundColor Yellow
$jobs = @{
Uptime = Start-Job { (Get-CimInstance Win32_OperatingSystem).LastBootUpTime }
CPU = Start-Job { (Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples.CookedValue }
Memory = Start-Job { (Get-CimInstance Win32_OperatingSystem).FreePhysicalMemory }
Disk = Start-Job { (Get-PSDrive C).Free }
}
$results = @{}
foreach ($key in $jobs.Keys) {
$results[$key] = Wait-Job $jobs[$key] -Timeout 2 | Receive-Job
Remove-Job $jobs[$key] -Force
}
$boot = $results.Uptime
if ($boot) { $uptime = (Get-Date) - $boot; Write-Host "Uptime : $($uptime.Days)d $($uptime.Hours)h $($uptime.Minutes)m" }
Write-Host "CPU Load : $([math]::Round($results.CPU, 1))%"
Write-Host "Memory : $([math]::Round($results.Memory/1GB, 1)) GB free"
Write-Host "Disk C : $([math]::Round($results.Disk/1GB, 1)) GB free"
Write-Host "===============================`n"
}
# --- 9. FINALIZATION ---
# Clean up variables to avoid polluting the session.
Remove-Variable -Name ProfileLoadStart -Scope script -ErrorAction SilentlyContinue
# Display load time.
$ProfileLoadDuration = (Get-Date) - $script:ProfileLoadStart
Write-Host "Profile loaded in $([math]::Round($ProfileLoadDuration.TotalMilliseconds))ms." -ForegroundColor DarkGray