mirror of
https://github.com/acedanger/shell.git
synced 2025-12-05 22:50:18 -08:00
Enhance PowerShell profile with comprehensive features and error handling
- Added automatic installation and import of essential PowerShell modules (Terminal-Icons, PSReadLine, PSScriptAnalyzer, PSFzf). - Improved error handling during module installation and import. - Integrated oh-my-posh for prompt theming with a specified theme. - Configured PSReadLine options for better user experience. - Added fzf to PATH if not already present and checked for its installation. - Implemented functions for network utilities (Get-Ip-Address, Invoke-WslReboot) and application management (Update-Budget, Update-Winget). - Enhanced file system utilities with functions like ff (file finder), touch (create/update file), and Unix-like commands (grep, which, head, tail). - Added clipboard utilities (cpy, pst) for easier text management. - Included Fabric AI integration for dynamic pattern functions and YouTube transcript retrieval. - Created a sync function for VS Code profile to maintain consistency with the main PowerShell profile. - Improved overall structure and documentation for better maintainability and usability.
This commit is contained in:
@@ -1,52 +1,215 @@
|
||||
# =============================================================================
|
||||
# POWERSHELL PROFILE CONFIGURATION
|
||||
# =============================================================================
|
||||
# Author: Peter Wood <peter@peterwood.dev>
|
||||
# Last Updated: June 17, 2025
|
||||
# Description: Comprehensive PowerShell profile with enhanced functionality
|
||||
#
|
||||
$canConnectToGitHub = Test-Connection github.com -Count 1 -Quiet -TimeoutSeconds 1
|
||||
# Features:
|
||||
# - Automatic module installation and import with error handling
|
||||
# - oh-my-posh prompt theming
|
||||
# - PSFzf fuzzy search integration
|
||||
# - Unix-like command aliases (grep, which, head, tail, etc.)
|
||||
# - Fabric AI pattern integration for text processing
|
||||
# - Network and system utilities
|
||||
# - File system helpers
|
||||
# - PowerShell and package management tools
|
||||
# - VS Code profile synchronization
|
||||
#
|
||||
# Usage:
|
||||
# - This profile loads automatically when starting PowerShell
|
||||
# - Use 'syncvscode' to sync with VS Code terminal
|
||||
# - Use 'Update-Profile' to reload after making changes
|
||||
# - All functions include help documentation accessible via Get-Help
|
||||
# =============================================================================
|
||||
|
||||
function Install-CustomModules {
|
||||
param (
|
||||
[string]$ModuleName = ''
|
||||
)
|
||||
# check if module is installed
|
||||
$moduleInfo = Get-Module -ListAvailable -Name $ModuleName -ErrorAction SilentlyContinue
|
||||
if ($moduleInfo) { return }
|
||||
# Install missing modules
|
||||
Write-Host "🔍 Checking for required PowerShell modules..." -ForegroundColor Cyan
|
||||
|
||||
Write-Host "${ModuleName} module not found." -ForegroundColor Red
|
||||
Install-Module -Name $ModuleName -Scope CurrentUser
|
||||
|
||||
Import-Module -Name $ModuleName
|
||||
}
|
||||
|
||||
Install-CustomModules -ModuleName 'tiPS'
|
||||
Install-CustomModules -ModuleName 'PSScriptAnalyzer'
|
||||
Install-CustomModules -ModuleName 'Terminal-Icons'
|
||||
Install-CustomModules -ModuleName 'PSReadLine'
|
||||
Install-CustomModules -ModuleName 'PSWindowsUpdate'
|
||||
|
||||
# kali.omp.json
|
||||
oh-my-posh --init --shell pwsh --config "$env:OneDrive\Documents\PowerShell\prompt\themes\stelbent-compact.minimal.omp.json" | Invoke-Expression
|
||||
|
||||
Set-PSReadLineOption -PredictionSource History
|
||||
Set-PSReadLineOption -PredictionViewStyle ListView
|
||||
Set-PSReadLineOption -EditMode Windows
|
||||
Set-PSReadLineKeyHandler -Key Tab -Function Complete
|
||||
|
||||
Register-ArgumentCompleter -Native -CommandName winget -ScriptBlock {
|
||||
param($wordToComplete, $commandAst, $cursorPosition)
|
||||
[Console]::InputEncoding = [Console]::OutputEncoding = $OutputEncoding = [System.Text.Utf8Encoding]::new()
|
||||
$Local:word = $wordToComplete.Replace('"', '""')
|
||||
$Local:ast = $commandAst.ToString().Replace('"', '""')
|
||||
winget complete --word="$Local:word" --commandline "$Local:ast" --position $cursorPosition | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
||||
if (-not (Get-Module -ListAvailable -Name Terminal-Icons)) {
|
||||
Write-Host "📦 Installing Terminal-Icons module..." -ForegroundColor Yellow
|
||||
try {
|
||||
Install-Module -Name Terminal-Icons -Scope CurrentUser -Force
|
||||
Write-Host "✅ Terminal-Icons installed successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Error "❌ Failed to install Terminal-Icons: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
if (-not (Get-Module -ListAvailable -Name PSReadLine)) {
|
||||
Write-Host "📦 Installing PSReadLine module..." -ForegroundColor Yellow
|
||||
try {
|
||||
Install-Module -Name PSReadLine -Scope CurrentUser -Force
|
||||
Write-Host "✅ PSReadLine installed successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Error "❌ Failed to install PSReadLine: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
if (-not (Get-Module -ListAvailable -Name PSScriptAnalyzer)) {
|
||||
Write-Host "📦 Installing PSScriptAnalyzer module..." -ForegroundColor Yellow
|
||||
try {
|
||||
Install-Module -Name PSScriptAnalyzer -Force -Scope CurrentUser
|
||||
Write-Host "✅ PSScriptAnalyzer installed successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Error "❌ Failed to install PSScriptAnalyzer: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
if (-not (Get-Module -ListAvailable -Name PSFzf)) {
|
||||
Write-Host "📦 Installing PSFzf module..." -ForegroundColor Yellow
|
||||
try {
|
||||
Install-Module -Name PSFzf -Scope CurrentUser -Force
|
||||
Write-Host "✅ PSFzf installed successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Error "❌ Failed to install PSFzf: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
# Import modules
|
||||
Write-Host "📂 Importing PowerShell modules..." -ForegroundColor Cyan
|
||||
|
||||
try {
|
||||
Import-Module -Name Terminal-Icons -ErrorAction Stop
|
||||
Write-Host "✅ Terminal-Icons imported successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning "⚠️ Failed to import Terminal-Icons: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
# Import PSReadLine with better version conflict handling
|
||||
if (Get-Module -Name PSReadLine) {
|
||||
# PSReadLine is already loaded, don't try to reimport
|
||||
Write-Host "✅ PSReadLine already loaded" -ForegroundColor Green
|
||||
}
|
||||
else {
|
||||
try {
|
||||
# Try to import the latest available version without forcing
|
||||
Import-Module -Name PSReadLine -ErrorAction Stop
|
||||
Write-Host "✅ PSReadLine imported successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning "PSReadLine import failed: $($_.Exception.Message)"
|
||||
Write-Host "ℹ️ Using built-in PSReadLine features" -ForegroundColor Cyan
|
||||
}
|
||||
}
|
||||
|
||||
# Add fzf to PATH if not already there
|
||||
Write-Host "🔍 Checking fzf installation..." -ForegroundColor Cyan
|
||||
$fzfPath = "$env:LOCALAPPDATA\Microsoft\WinGet\Packages\junegunn.fzf_Microsoft.Winget.Source_8wekyb3d8bbwe"
|
||||
if ((Test-Path "$fzfPath\fzf.exe") -and ($env:PATH -notlike "*$fzfPath*")) {
|
||||
$env:PATH += ";$fzfPath"
|
||||
Write-Host "✅ Added fzf to PATH: $fzfPath" -ForegroundColor Green
|
||||
}
|
||||
|
||||
# Also check the WinGet Links directory
|
||||
$wingetLinks = "$env:LOCALAPPDATA\Microsoft\WinGet\Links"
|
||||
if ((Test-Path "$wingetLinks\fzf.exe") -and ($env:PATH -notlike "*$wingetLinks*")) {
|
||||
$env:PATH += ";$wingetLinks"
|
||||
Write-Host "✅ Added WinGet Links to PATH: $wingetLinks" -ForegroundColor Green
|
||||
}
|
||||
|
||||
# Initialize oh-my-posh prompt
|
||||
Write-Host "🎨 Initializing oh-my-posh prompt..." -ForegroundColor Cyan
|
||||
$promptTheme = "$env:OneDrive\Documents\PowerShell\prompt\themes\easy-term.omp.json"
|
||||
if (Test-Path $promptTheme) {
|
||||
try {
|
||||
oh-my-posh --init --shell pwsh --config $promptTheme | Invoke-Expression
|
||||
Write-Host "✅ oh-my-posh prompt loaded successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Error "❌ Failed to load oh-my-posh prompt: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Warning "⚠️ oh-my-posh theme not found at: $promptTheme"
|
||||
}
|
||||
|
||||
Write-Host "⚙️ Configuring PSReadLine options..." -ForegroundColor Cyan
|
||||
try {
|
||||
Set-PSReadLineOption -PredictionSource History
|
||||
Set-PSReadLineOption -PredictionViewStyle ListView
|
||||
Set-PSReadLineOption -EditMode Windows
|
||||
Set-PSReadLineKeyHandler -Key Tab -Function Complete
|
||||
Write-Host "✅ PSReadLine configured successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning "⚠️ Failed to configure PSReadLine: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
# Configure PSFzf if available and fzf is installed
|
||||
if (Get-Command fzf -ErrorAction SilentlyContinue) {
|
||||
try {
|
||||
Import-Module -Name PSFzf -ErrorAction Stop
|
||||
Set-PsFzfOption -PSReadlineChordProvider 'Ctrl+f' -PSReadlineChordReverseHistory 'Ctrl+r'
|
||||
Write-Host "✅ PSFzf configured successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Failed to configure PSFzf: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Host "⚠️ fzf binary not found in PATH. PSFzf features will be unavailable." -ForegroundColor Yellow
|
||||
Write-Host " Install fzf with: winget install fzf" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
Write-Host "🔧 Setting up command completers and additional modules..." -ForegroundColor Cyan
|
||||
|
||||
# Register winget completion
|
||||
try {
|
||||
Register-ArgumentCompleter -Native -CommandName winget -ScriptBlock {
|
||||
param($wordToComplete, $commandAst, $cursorPosition)
|
||||
[Console]::InputEncoding = [Console]::OutputEncoding = $OutputEncoding = [System.Text.Utf8Encoding]::new()
|
||||
$Local:word = $wordToComplete.Replace('"', '""')
|
||||
$Local:ast = $commandAst.ToString().Replace('"', '""')
|
||||
winget complete --word="$Local:word" --commandline "$Local:ast" --position $cursorPosition | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
||||
}
|
||||
}
|
||||
Write-Host "✅ winget tab completion configured" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning "⚠️ Failed to configure winget completion: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# NETWORK AND SYSTEM UTILITIES
|
||||
# =============================================================================
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get your public IP address
|
||||
.DESCRIPTION
|
||||
Retrieves your external/public IP address by querying ifconfig.me
|
||||
.EXAMPLE
|
||||
Get-Ip-Address
|
||||
getIp
|
||||
#>
|
||||
function Get-Ip-Address {
|
||||
(Invoke-WebRequest -Uri ifconfig.me/ip).Content
|
||||
}
|
||||
|
||||
Set-Alias getIp Get-Ip-Address
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Restart WSL (Windows Subsystem for Linux) distributions
|
||||
.DESCRIPTION
|
||||
Shuts down WSL completely, which effectively restarts all running distributions
|
||||
.PARAMETER Distro
|
||||
The name of the WSL distribution to restart (defaults to 'Ubuntu')
|
||||
.EXAMPLE
|
||||
Invoke-WslReboot
|
||||
wslreboot
|
||||
wslreboot "Debian"
|
||||
#>
|
||||
function Invoke-WslReboot() {
|
||||
param (
|
||||
[string]$Distro = 'Debian'
|
||||
[string]$Distro = 'Ubuntu'
|
||||
)
|
||||
Write-Host "Rebooting $Distro"
|
||||
wsl --shutdown
|
||||
@@ -54,6 +217,20 @@ function Invoke-WslReboot() {
|
||||
|
||||
Set-Alias wslreboot Invoke-WslReboot
|
||||
|
||||
# =============================================================================
|
||||
# APPLICATION AND PACKAGE MANAGEMENT
|
||||
# =============================================================================
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Update family budget database from Excel file
|
||||
.DESCRIPTION
|
||||
Runs a Python script to export budget data from an Excel spreadsheet
|
||||
Specific to the user's budget management workflow
|
||||
.EXAMPLE
|
||||
Update-Budget
|
||||
updbudget
|
||||
#>
|
||||
function Update-Budget() {
|
||||
Write-Host "Updating budget database"
|
||||
py D:\dev\export-budget-csv\export.py -s "$env:OneDrive\Documents\Financial\Wood Family Financials.xlsx"
|
||||
@@ -62,52 +239,245 @@ function Update-Budget() {
|
||||
|
||||
Set-Alias updbudget Update-Budget
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Update all packages using winget
|
||||
.DESCRIPTION
|
||||
Runs 'winget upgrade' to update all installed packages
|
||||
.EXAMPLE
|
||||
Update-Winget
|
||||
wgu
|
||||
#>
|
||||
function Update-Winget() {
|
||||
winget upgrade
|
||||
}
|
||||
|
||||
Set-Alias wgu Update-Winget
|
||||
#f45873b3-b655-43a6-b217-97c00aa0db58 PowerToys CommandNotFound module
|
||||
|
||||
Import-Module -Name Microsoft.WinGet.CommandNotFound
|
||||
try {
|
||||
Import-Module -Name Microsoft.WinGet.CommandNotFound -ErrorAction Stop
|
||||
Write-Host "✅ PowerToys CommandNotFound module loaded" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning "⚠️ PowerToys CommandNotFound module not available: $($_.Exception.Message)"
|
||||
}
|
||||
#f45873b3-b655-43a6-b217-97c00aa0db58
|
||||
|
||||
Write-Host "🗂️ Initializing zoxide (smart directory navigation)..." -ForegroundColor Cyan
|
||||
if (Get-Command zoxide -ErrorAction SilentlyContinue) {
|
||||
Invoke-Expression (& { (zoxide init powershell | Out-String) })
|
||||
try {
|
||||
Invoke-Expression (& { (zoxide init powershell | Out-String) })
|
||||
Write-Host "✅ zoxide initialized successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning "⚠️ Failed to initialize zoxide: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Host "zoxide command not found. Attempting to install via winget..."
|
||||
Write-Host "📦 zoxide not found. Attempting to install via winget..." -ForegroundColor Yellow
|
||||
try {
|
||||
winget install -e --id ajeetdsouza.zoxide
|
||||
Write-Host "zoxide installed successfully. Initializing..."
|
||||
Write-Host "✅ zoxide installed successfully. Initializing..." -ForegroundColor Green
|
||||
Invoke-Expression (& { (zoxide init powershell | Out-String) })
|
||||
}
|
||||
catch {
|
||||
Write-Error "Failed to install zoxide. Error: $_"
|
||||
Write-Error "❌ Failed to install zoxide: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
Set-TiPSConfiguration -AutomaticallyWritePowerShellTip EverySession
|
||||
# Fabric patterns integration (with error handling)
|
||||
Write-Host "🧩 Loading Fabric AI patterns..." -ForegroundColor Cyan
|
||||
try {
|
||||
# Path to the patterns directory
|
||||
$patternsPath = Join-Path $HOME ".config/fabric/patterns"
|
||||
if (Test-Path $patternsPath) {
|
||||
$patternCount = 0
|
||||
foreach ($patternDir in Get-ChildItem -Path $patternsPath -Directory -ErrorAction SilentlyContinue) {
|
||||
$patternName = $patternDir.Name
|
||||
|
||||
# Finds files recursively matching a pattern.
|
||||
function ff($name) {
|
||||
Get-ChildItem -Recurse -Filter "*${name}*" -ErrorAction SilentlyContinue | ForEach-Object { Write-Output "${$_.directory}\$(%_)" }
|
||||
# Dynamically define a function for each pattern
|
||||
$functionDefinition = @"
|
||||
function $patternName {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(ValueFromPipeline = `$true)]
|
||||
[string] `$InputObject,
|
||||
|
||||
[Parameter(ValueFromRemainingArguments = `$true)]
|
||||
[String[]] `$patternArgs
|
||||
)
|
||||
|
||||
begin {
|
||||
# Initialize an array to collect pipeline input
|
||||
`$collector = @()
|
||||
}
|
||||
|
||||
process {
|
||||
# Collect pipeline input objects
|
||||
if (`$InputObject) {
|
||||
`$collector += `$InputObject
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
# Join all pipeline input into a single string, separated by newlines
|
||||
`$pipelineContent = `$collector -join "`n"
|
||||
|
||||
# If there's pipeline input, include it in the call to fabric
|
||||
if (`$pipelineContent) {
|
||||
`$pipelineContent | fabric --pattern $patternName `$patternArgs
|
||||
} else {
|
||||
# No pipeline input; just call fabric with the additional args
|
||||
fabric --pattern $patternName `$patternArgs
|
||||
}
|
||||
}
|
||||
}
|
||||
"@
|
||||
# Add the function to the current session
|
||||
Invoke-Expression $functionDefinition
|
||||
$patternCount++
|
||||
}
|
||||
Write-Host "✅ Loaded $patternCount Fabric patterns successfully" -ForegroundColor Green
|
||||
}
|
||||
else {
|
||||
Write-Host "ℹ️ Fabric patterns directory not found at: $patternsPath" -ForegroundColor Cyan
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Warning "⚠️ Failed to load fabric patterns: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
# Creates an empty file (similar to the touch command in Linux).
|
||||
# =============================================================================
|
||||
# FABRIC AI INTEGRATION FUNCTIONS
|
||||
# =============================================================================
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get YouTube video transcript using Fabric AI
|
||||
.DESCRIPTION
|
||||
Downloads and processes YouTube video transcripts using the Fabric AI tool
|
||||
Can optionally include timestamps in the transcript
|
||||
.PARAMETER t
|
||||
Switch to include timestamps in the transcript
|
||||
.PARAMETER videoLink
|
||||
The YouTube video URL to process
|
||||
.EXAMPLE
|
||||
yt "https://youtube.com/watch?v=example"
|
||||
yt -t "https://youtube.com/watch?v=example" # With timestamps
|
||||
#>
|
||||
function yt {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter()]
|
||||
[Alias("timestamps")]
|
||||
[switch]$t,
|
||||
|
||||
[Parameter(Position = 0, ValueFromPipeline = $true)]
|
||||
[string]$videoLink
|
||||
)
|
||||
|
||||
begin {
|
||||
$transcriptFlag = "--transcript"
|
||||
if ($t) {
|
||||
$transcriptFlag = "--transcript-with-timestamps"
|
||||
}
|
||||
}
|
||||
|
||||
process {
|
||||
if (-not $videoLink) {
|
||||
Write-Error "Usage: yt [-t | --timestamps] youtube-link"
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
if ($videoLink) {
|
||||
# Execute and allow output to flow through the pipeline
|
||||
fabric -y $videoLink $transcriptFlag
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# FILE SYSTEM UTILITIES
|
||||
# =============================================================================
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Fast file finder - search for files by name pattern
|
||||
.DESCRIPTION
|
||||
Recursively searches for files matching a name pattern from current directory
|
||||
Similar to Unix 'find' command but simpler syntax
|
||||
.PARAMETER name
|
||||
The search pattern to match against filenames (supports wildcards)
|
||||
.EXAMPLE
|
||||
ff "*.txt"
|
||||
ff "config"
|
||||
ff "package.json"
|
||||
#>
|
||||
function ff($name) {
|
||||
Get-ChildItem -Recurse -Filter "*${name}*" -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
Write-Output "$($_.Directory)\$($_.Name)"
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Create an empty file (Unix-style touch command)
|
||||
.DESCRIPTION
|
||||
Creates a new empty file or updates the timestamp of an existing file
|
||||
Mimics the behavior of the Unix 'touch' command
|
||||
.PARAMETER file
|
||||
The path and name of the file to create or touch
|
||||
.EXAMPLE
|
||||
touch "newfile.txt"
|
||||
touch "C:\temp\example.log"
|
||||
#>
|
||||
function touch($file) {
|
||||
"" | Out-File -File $file -Encoding ascii
|
||||
}
|
||||
|
||||
# Reloads the current profile.
|
||||
# =============================================================================
|
||||
# PROFILE MANAGEMENT FUNCTIONS
|
||||
# =============================================================================
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Reload the current PowerShell profile
|
||||
.DESCRIPTION
|
||||
Reloads the PowerShell profile to apply any changes made to the profile file
|
||||
Useful for testing profile modifications without restarting the terminal
|
||||
.EXAMPLE
|
||||
Update-Profile
|
||||
reload-profile
|
||||
#>
|
||||
function Update-Profile {
|
||||
& $PROFILE
|
||||
}
|
||||
|
||||
# Checks for and updates PowerShell to the latest version.
|
||||
# Alias for backward compatibility
|
||||
Set-Alias reload-profile Update-Profile
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Check for and install PowerShell updates
|
||||
.DESCRIPTION
|
||||
Checks GitHub for the latest PowerShell release and updates via winget if needed
|
||||
Includes network connectivity check to avoid unnecessary delays
|
||||
.EXAMPLE
|
||||
Update-PowerShell
|
||||
#>
|
||||
function Update-PowerShell {
|
||||
if (-not $global:canConnectToGitHub) {
|
||||
Write-Host "Skipping PowerShell update check due to GitHub.com not responding within 1 second." -ForegroundColor Yellow
|
||||
# Check if we can connect to GitHub with a faster, quieter method
|
||||
try {
|
||||
$response = Test-Connection -ComputerName "8.8.8.8" -Count 1 -Quiet -TimeoutSeconds 2
|
||||
if (-not $response) {
|
||||
Write-Host "Skipping PowerShell update check - no internet connection." -ForegroundColor Yellow
|
||||
return
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host "Skipping PowerShell update check - network unavailable." -ForegroundColor Yellow
|
||||
return
|
||||
}
|
||||
|
||||
@@ -135,54 +505,216 @@ function Update-PowerShell {
|
||||
Write-Error "Failed to update PowerShell. Error: $_"
|
||||
}
|
||||
}
|
||||
Update-PowerShell
|
||||
# Commented out automatic PowerShell update check to prevent slow profile loading
|
||||
# Run 'Update-PowerShell' manually when you want to check for updates
|
||||
# Update-PowerShell
|
||||
|
||||
# Searches for a regular expression in files (similar to the grep command in Linux).
|
||||
# =============================================================================
|
||||
# UNIX-LIKE UTILITY FUNCTIONS
|
||||
# =============================================================================
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Search for text patterns in files (Unix grep equivalent)
|
||||
.DESCRIPTION
|
||||
Searches for regex patterns in files or pipeline input
|
||||
Mimics the behavior of the Unix 'grep' command
|
||||
.PARAMETER regex
|
||||
The regular expression pattern to search for
|
||||
.PARAMETER dir
|
||||
Optional directory to search in (searches current dir if not specified)
|
||||
.EXAMPLE
|
||||
grep "error" *.log
|
||||
Get-Content file.txt | grep "pattern"
|
||||
grep "TODO" C:\Projects
|
||||
#>
|
||||
function grep($regex, $dir) {
|
||||
if ( $dir ) {
|
||||
Get-ChildItem $dir | select-string $regex
|
||||
if ($dir) {
|
||||
Get-ChildItem $dir | Select-String $regex
|
||||
return
|
||||
}
|
||||
$input | select-string $regex
|
||||
$input | Select-String $regex
|
||||
}
|
||||
|
||||
# Displays disk volume information.
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Find the location of a command (Unix which equivalent)
|
||||
.DESCRIPTION
|
||||
Locates the executable file for a given command name
|
||||
Mimics the behavior of the Unix 'which' command
|
||||
.PARAMETER command
|
||||
The name of the command to locate
|
||||
.EXAMPLE
|
||||
which "git"
|
||||
which "notepad"
|
||||
#>
|
||||
function which ($command) {
|
||||
Get-Command -Name $command -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Display disk usage information (Unix df equivalent)
|
||||
.DESCRIPTION
|
||||
Shows disk space usage for all mounted volumes
|
||||
Mimics the behavior of the Unix 'df' command
|
||||
.EXAMPLE
|
||||
df
|
||||
#>
|
||||
function df {
|
||||
get-volume
|
||||
}
|
||||
|
||||
# Displays the first n lines of a file8587
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Display the first lines of a file (Unix head equivalent)
|
||||
.DESCRIPTION
|
||||
Shows the first N lines of a text file (default: 10 lines)
|
||||
Mimics the behavior of the Unix 'head' command
|
||||
.PARAMETER Path
|
||||
The path to the file to read
|
||||
.PARAMETER n
|
||||
Number of lines to display (default: 10)
|
||||
.EXAMPLE
|
||||
head "file.txt"
|
||||
head "file.txt" 5
|
||||
#>
|
||||
function head {
|
||||
param($Path, $n = 10)
|
||||
Get-Content $Path -Head $n
|
||||
}
|
||||
|
||||
# Displays the last n lines of a file
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Display the last lines of a file (Unix tail equivalent)
|
||||
.DESCRIPTION
|
||||
Shows the last N lines of a text file (default: 10 lines)
|
||||
Mimics the behavior of the Unix 'tail' command
|
||||
.PARAMETER Path
|
||||
The path to the file to read
|
||||
.PARAMETER n
|
||||
Number of lines to display (default: 10)
|
||||
.EXAMPLE
|
||||
tail "file.txt"
|
||||
tail "logfile.log" 20
|
||||
#>
|
||||
function tail {
|
||||
param($Path, $n = 10)
|
||||
Get-Content $Path -Tail $n
|
||||
}
|
||||
|
||||
# Navigates to the Documents directory.
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Quick navigation to Documents folder
|
||||
.DESCRIPTION
|
||||
Changes the current directory to the user's Documents folder
|
||||
.EXAMPLE
|
||||
docs
|
||||
#>
|
||||
function docs { Set-Location -Path $HOME\Documents }
|
||||
|
||||
# Navigates to the Downloads directory.
|
||||
function dl { Set-Location -Path $HOME\Downloads }
|
||||
# =============================================================================
|
||||
# NETWORKING UTILITIES
|
||||
# =============================================================================
|
||||
|
||||
# Clears the DNS client cache.
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Flush DNS cache
|
||||
.DESCRIPTION
|
||||
Clears the DNS resolver cache to force fresh DNS lookups
|
||||
Useful for troubleshooting DNS issues
|
||||
.EXAMPLE
|
||||
flushdns
|
||||
#>
|
||||
function flushdns { Clear-DnsClientCache }
|
||||
|
||||
# Copies text to the clipboard.
|
||||
# =============================================================================
|
||||
# CLIPBOARD UTILITIES
|
||||
# =============================================================================
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Copy text to clipboard
|
||||
.DESCRIPTION
|
||||
Copies the specified text to the Windows clipboard
|
||||
.PARAMETER args
|
||||
The text to copy to clipboard
|
||||
.EXAMPLE
|
||||
cpy "Hello World"
|
||||
#>
|
||||
function cpy { Set-Clipboard $args[0] }
|
||||
|
||||
# Gets the text from the clipboard.
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Paste text from clipboard
|
||||
.DESCRIPTION
|
||||
Retrieves text from the Windows clipboard and displays it
|
||||
.EXAMPLE
|
||||
pst
|
||||
#>
|
||||
function pst { Get-Clipboard }
|
||||
|
||||
# Enhanced PowerShell Experience
|
||||
Set-PSReadLineOption -Colors @{
|
||||
Command = 'Yellow'
|
||||
Parameter = 'Green'
|
||||
String = 'DarkCyan'
|
||||
Write-Host "🎨 Configuring PowerShell color scheme..." -ForegroundColor Cyan
|
||||
try {
|
||||
Set-PSReadLineOption -Colors @{
|
||||
Command = 'Yellow'
|
||||
Parameter = 'Green'
|
||||
String = 'DarkCyan'
|
||||
}
|
||||
Write-Host "✅ Color scheme applied successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning "⚠️ Failed to apply color scheme: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
# http://bin.christitus.com/unakijolon
|
||||
$env:GITHUB_PERSONAL_ACCESS_TOKEN = [Environment]::GetEnvironmentVariable("GITHUB_PERSONAL_ACCESS_TOKEN", "User")
|
||||
|
||||
# http://bin.christitus.com/unakijolon
|
||||
|
||||
function Sync-VSCodeProfile {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Syncs the current PowerShell profile to VS Code
|
||||
|
||||
.DESCRIPTION
|
||||
Creates or updates the VS Code PowerShell profile to source this main profile,
|
||||
keeping all your customizations in sync between regular PowerShell and VS Code.
|
||||
#>
|
||||
$mainProfile = $PROFILE.CurrentUserCurrentHost
|
||||
$vscodeProfile = $mainProfile -replace "Microsoft\.PowerShell", "Microsoft.VSCode"
|
||||
|
||||
if (Test-Path $mainProfile) {
|
||||
$vscodeContent = @"
|
||||
# VS Code PowerShell Profile
|
||||
# This profile sources the main PowerShell profile to keep them in sync
|
||||
# Last synced: $(Get-Date)
|
||||
|
||||
# Source the main PowerShell profile
|
||||
`$mainProfile = "$mainProfile"
|
||||
if (Test-Path `$mainProfile) {
|
||||
. `$mainProfile
|
||||
Write-Host "✅ Loaded main PowerShell profile in VS Code" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Warning "Main PowerShell profile not found at: `$mainProfile"
|
||||
}
|
||||
|
||||
# VS Code specific customizations can go here if needed
|
||||
"@
|
||||
|
||||
Set-Content -Path $vscodeProfile -Value $vscodeContent -Encoding UTF8
|
||||
Write-Host "✅ VS Code profile synced successfully!" -ForegroundColor Green
|
||||
Write-Host "Location: $vscodeProfile" -ForegroundColor Cyan
|
||||
}
|
||||
else {
|
||||
Write-Error "Main PowerShell profile not found at: $mainProfile"
|
||||
}
|
||||
}
|
||||
|
||||
Set-Alias syncvscode Sync-VSCodeProfile
|
||||
|
||||
# Profile loading complete
|
||||
Write-Host "" # Empty line for spacing
|
||||
Write-Host "🎉 PowerShell profile loaded successfully!" -ForegroundColor Green
|
||||
Write-Host " Type 'Get-Help about_profiles' for more information" -ForegroundColor Gray
|
||||
Write-Host " Use 'syncvscode' to sync this profile with VS Code" -ForegroundColor Gray
|
||||
|
||||
@@ -1,52 +1,215 @@
|
||||
# =============================================================================
|
||||
# POWERSHELL PROFILE CONFIGURATION
|
||||
# =============================================================================
|
||||
# Author: Peter Wood <peter@peterwood.dev>
|
||||
# Last Updated: June 17, 2025
|
||||
# Description: Comprehensive PowerShell profile with enhanced functionality
|
||||
#
|
||||
$canConnectToGitHub = Test-Connection github.com -Count 1 -Quiet -TimeoutSeconds 1
|
||||
# Features:
|
||||
# - Automatic module installation and import with error handling
|
||||
# - oh-my-posh prompt theming
|
||||
# - PSFzf fuzzy search integration
|
||||
# - Unix-like command aliases (grep, which, head, tail, etc.)
|
||||
# - Fabric AI pattern integration for text processing
|
||||
# - Network and system utilities
|
||||
# - File system helpers
|
||||
# - PowerShell and package management tools
|
||||
# - VS Code profile synchronization
|
||||
#
|
||||
# Usage:
|
||||
# - This profile loads automatically when starting PowerShell
|
||||
# - Use 'syncvscode' to sync with VS Code terminal
|
||||
# - Use 'Update-Profile' to reload after making changes
|
||||
# - All functions include help documentation accessible via Get-Help
|
||||
# =============================================================================
|
||||
|
||||
function Install-CustomModules {
|
||||
param (
|
||||
[string]$ModuleName = ''
|
||||
)
|
||||
# check if module is installed
|
||||
$moduleInfo = Get-Module -ListAvailable -Name $ModuleName -ErrorAction SilentlyContinue
|
||||
if ($moduleInfo) { return }
|
||||
# Install missing modules
|
||||
Write-Host "🔍 Checking for required PowerShell modules..." -ForegroundColor Cyan
|
||||
|
||||
Write-Host "${ModuleName} module not found." -ForegroundColor Red
|
||||
Install-Module -Name $ModuleName -Scope CurrentUser
|
||||
|
||||
Import-Module -Name $ModuleName
|
||||
}
|
||||
|
||||
Install-CustomModules -ModuleName 'tiPS'
|
||||
Install-CustomModules -ModuleName 'PSScriptAnalyzer'
|
||||
Install-CustomModules -ModuleName 'Terminal-Icons'
|
||||
Install-CustomModules -ModuleName 'PSReadLine'
|
||||
Install-CustomModules -ModuleName 'PSWindowsUpdate'
|
||||
|
||||
# kali.omp.json
|
||||
oh-my-posh --init --shell pwsh --config "$env:OneDrive\Documents\PowerShell\prompt\themes\stelbent-compact.minimal.omp.json" | Invoke-Expression
|
||||
|
||||
Set-PSReadLineOption -PredictionSource History
|
||||
Set-PSReadLineOption -PredictionViewStyle ListView
|
||||
Set-PSReadLineOption -EditMode Windows
|
||||
Set-PSReadLineKeyHandler -Key Tab -Function Complete
|
||||
|
||||
Register-ArgumentCompleter -Native -CommandName winget -ScriptBlock {
|
||||
param($wordToComplete, $commandAst, $cursorPosition)
|
||||
[Console]::InputEncoding = [Console]::OutputEncoding = $OutputEncoding = [System.Text.Utf8Encoding]::new()
|
||||
$Local:word = $wordToComplete.Replace('"', '""')
|
||||
$Local:ast = $commandAst.ToString().Replace('"', '""')
|
||||
winget complete --word="$Local:word" --commandline "$Local:ast" --position $cursorPosition | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
||||
if (-not (Get-Module -ListAvailable -Name Terminal-Icons)) {
|
||||
Write-Host "📦 Installing Terminal-Icons module..." -ForegroundColor Yellow
|
||||
try {
|
||||
Install-Module -Name Terminal-Icons -Scope CurrentUser -Force
|
||||
Write-Host "✅ Terminal-Icons installed successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Error "❌ Failed to install Terminal-Icons: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
if (-not (Get-Module -ListAvailable -Name PSReadLine)) {
|
||||
Write-Host "📦 Installing PSReadLine module..." -ForegroundColor Yellow
|
||||
try {
|
||||
Install-Module -Name PSReadLine -Scope CurrentUser -Force
|
||||
Write-Host "✅ PSReadLine installed successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Error "❌ Failed to install PSReadLine: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
if (-not (Get-Module -ListAvailable -Name PSScriptAnalyzer)) {
|
||||
Write-Host "📦 Installing PSScriptAnalyzer module..." -ForegroundColor Yellow
|
||||
try {
|
||||
Install-Module -Name PSScriptAnalyzer -Force -Scope CurrentUser
|
||||
Write-Host "✅ PSScriptAnalyzer installed successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Error "❌ Failed to install PSScriptAnalyzer: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
if (-not (Get-Module -ListAvailable -Name PSFzf)) {
|
||||
Write-Host "📦 Installing PSFzf module..." -ForegroundColor Yellow
|
||||
try {
|
||||
Install-Module -Name PSFzf -Scope CurrentUser -Force
|
||||
Write-Host "✅ PSFzf installed successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Error "❌ Failed to install PSFzf: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
# Import modules
|
||||
Write-Host "📂 Importing PowerShell modules..." -ForegroundColor Cyan
|
||||
|
||||
try {
|
||||
Import-Module -Name Terminal-Icons -ErrorAction Stop
|
||||
Write-Host "✅ Terminal-Icons imported successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning "⚠️ Failed to import Terminal-Icons: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
# Import PSReadLine with better version conflict handling
|
||||
if (Get-Module -Name PSReadLine) {
|
||||
# PSReadLine is already loaded, don't try to reimport
|
||||
Write-Host "✅ PSReadLine already loaded" -ForegroundColor Green
|
||||
}
|
||||
else {
|
||||
try {
|
||||
# Try to import the latest available version without forcing
|
||||
Import-Module -Name PSReadLine -ErrorAction Stop
|
||||
Write-Host "✅ PSReadLine imported successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning "PSReadLine import failed: $($_.Exception.Message)"
|
||||
Write-Host "ℹ️ Using built-in PSReadLine features" -ForegroundColor Cyan
|
||||
}
|
||||
}
|
||||
|
||||
# Add fzf to PATH if not already there
|
||||
Write-Host "🔍 Checking fzf installation..." -ForegroundColor Cyan
|
||||
$fzfPath = "$env:LOCALAPPDATA\Microsoft\WinGet\Packages\junegunn.fzf_Microsoft.Winget.Source_8wekyb3d8bbwe"
|
||||
if ((Test-Path "$fzfPath\fzf.exe") -and ($env:PATH -notlike "*$fzfPath*")) {
|
||||
$env:PATH += ";$fzfPath"
|
||||
Write-Host "✅ Added fzf to PATH: $fzfPath" -ForegroundColor Green
|
||||
}
|
||||
|
||||
# Also check the WinGet Links directory
|
||||
$wingetLinks = "$env:LOCALAPPDATA\Microsoft\WinGet\Links"
|
||||
if ((Test-Path "$wingetLinks\fzf.exe") -and ($env:PATH -notlike "*$wingetLinks*")) {
|
||||
$env:PATH += ";$wingetLinks"
|
||||
Write-Host "✅ Added WinGet Links to PATH: $wingetLinks" -ForegroundColor Green
|
||||
}
|
||||
|
||||
# Initialize oh-my-posh prompt
|
||||
Write-Host "🎨 Initializing oh-my-posh prompt..." -ForegroundColor Cyan
|
||||
$promptTheme = "$env:OneDrive\Documents\PowerShell\prompt\themes\easy-term.omp.json"
|
||||
if (Test-Path $promptTheme) {
|
||||
try {
|
||||
oh-my-posh --init --shell pwsh --config $promptTheme | Invoke-Expression
|
||||
Write-Host "✅ oh-my-posh prompt loaded successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Error "❌ Failed to load oh-my-posh prompt: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Warning "⚠️ oh-my-posh theme not found at: $promptTheme"
|
||||
}
|
||||
|
||||
Write-Host "⚙️ Configuring PSReadLine options..." -ForegroundColor Cyan
|
||||
try {
|
||||
Set-PSReadLineOption -PredictionSource History
|
||||
Set-PSReadLineOption -PredictionViewStyle ListView
|
||||
Set-PSReadLineOption -EditMode Windows
|
||||
Set-PSReadLineKeyHandler -Key Tab -Function Complete
|
||||
Write-Host "✅ PSReadLine configured successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning "⚠️ Failed to configure PSReadLine: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
# Configure PSFzf if available and fzf is installed
|
||||
if (Get-Command fzf -ErrorAction SilentlyContinue) {
|
||||
try {
|
||||
Import-Module -Name PSFzf -ErrorAction Stop
|
||||
Set-PsFzfOption -PSReadlineChordProvider 'Ctrl+f' -PSReadlineChordReverseHistory 'Ctrl+r'
|
||||
Write-Host "✅ PSFzf configured successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Failed to configure PSFzf: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Host "⚠️ fzf binary not found in PATH. PSFzf features will be unavailable." -ForegroundColor Yellow
|
||||
Write-Host " Install fzf with: winget install fzf" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
Write-Host "🔧 Setting up command completers and additional modules..." -ForegroundColor Cyan
|
||||
|
||||
# Register winget completion
|
||||
try {
|
||||
Register-ArgumentCompleter -Native -CommandName winget -ScriptBlock {
|
||||
param($wordToComplete, $commandAst, $cursorPosition)
|
||||
[Console]::InputEncoding = [Console]::OutputEncoding = $OutputEncoding = [System.Text.Utf8Encoding]::new()
|
||||
$Local:word = $wordToComplete.Replace('"', '""')
|
||||
$Local:ast = $commandAst.ToString().Replace('"', '""')
|
||||
winget complete --word="$Local:word" --commandline "$Local:ast" --position $cursorPosition | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
||||
}
|
||||
}
|
||||
Write-Host "✅ winget tab completion configured" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning "⚠️ Failed to configure winget completion: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# NETWORK AND SYSTEM UTILITIES
|
||||
# =============================================================================
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get your public IP address
|
||||
.DESCRIPTION
|
||||
Retrieves your external/public IP address by querying ifconfig.me
|
||||
.EXAMPLE
|
||||
Get-Ip-Address
|
||||
getIp
|
||||
#>
|
||||
function Get-Ip-Address {
|
||||
(Invoke-WebRequest -Uri ifconfig.me/ip).Content
|
||||
}
|
||||
|
||||
Set-Alias getIp Get-Ip-Address
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Restart WSL (Windows Subsystem for Linux) distributions
|
||||
.DESCRIPTION
|
||||
Shuts down WSL completely, which effectively restarts all running distributions
|
||||
.PARAMETER Distro
|
||||
The name of the WSL distribution to restart (defaults to 'Ubuntu')
|
||||
.EXAMPLE
|
||||
Invoke-WslReboot
|
||||
wslreboot
|
||||
wslreboot "Debian"
|
||||
#>
|
||||
function Invoke-WslReboot() {
|
||||
param (
|
||||
[string]$Distro = 'Debian'
|
||||
[string]$Distro = 'Ubuntu'
|
||||
)
|
||||
Write-Host "Rebooting $Distro"
|
||||
wsl --shutdown
|
||||
@@ -54,6 +217,20 @@ function Invoke-WslReboot() {
|
||||
|
||||
Set-Alias wslreboot Invoke-WslReboot
|
||||
|
||||
# =============================================================================
|
||||
# APPLICATION AND PACKAGE MANAGEMENT
|
||||
# =============================================================================
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Update family budget database from Excel file
|
||||
.DESCRIPTION
|
||||
Runs a Python script to export budget data from an Excel spreadsheet
|
||||
Specific to the user's budget management workflow
|
||||
.EXAMPLE
|
||||
Update-Budget
|
||||
updbudget
|
||||
#>
|
||||
function Update-Budget() {
|
||||
Write-Host "Updating budget database"
|
||||
py D:\dev\export-budget-csv\export.py -s "$env:OneDrive\Documents\Financial\Wood Family Financials.xlsx"
|
||||
@@ -62,52 +239,245 @@ function Update-Budget() {
|
||||
|
||||
Set-Alias updbudget Update-Budget
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Update all packages using winget
|
||||
.DESCRIPTION
|
||||
Runs 'winget upgrade' to update all installed packages
|
||||
.EXAMPLE
|
||||
Update-Winget
|
||||
wgu
|
||||
#>
|
||||
function Update-Winget() {
|
||||
winget upgrade
|
||||
}
|
||||
|
||||
Set-Alias wgu Update-Winget
|
||||
#f45873b3-b655-43a6-b217-97c00aa0db58 PowerToys CommandNotFound module
|
||||
|
||||
Import-Module -Name Microsoft.WinGet.CommandNotFound
|
||||
try {
|
||||
Import-Module -Name Microsoft.WinGet.CommandNotFound -ErrorAction Stop
|
||||
Write-Host "✅ PowerToys CommandNotFound module loaded" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning "⚠️ PowerToys CommandNotFound module not available: $($_.Exception.Message)"
|
||||
}
|
||||
#f45873b3-b655-43a6-b217-97c00aa0db58
|
||||
|
||||
Write-Host "🗂️ Initializing zoxide (smart directory navigation)..." -ForegroundColor Cyan
|
||||
if (Get-Command zoxide -ErrorAction SilentlyContinue) {
|
||||
Invoke-Expression (& { (zoxide init powershell | Out-String) })
|
||||
try {
|
||||
Invoke-Expression (& { (zoxide init powershell | Out-String) })
|
||||
Write-Host "✅ zoxide initialized successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning "⚠️ Failed to initialize zoxide: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Host "zoxide command not found. Attempting to install via winget..."
|
||||
Write-Host "📦 zoxide not found. Attempting to install via winget..." -ForegroundColor Yellow
|
||||
try {
|
||||
winget install -e --id ajeetdsouza.zoxide
|
||||
Write-Host "zoxide installed successfully. Initializing..."
|
||||
Write-Host "✅ zoxide installed successfully. Initializing..." -ForegroundColor Green
|
||||
Invoke-Expression (& { (zoxide init powershell | Out-String) })
|
||||
}
|
||||
catch {
|
||||
Write-Error "Failed to install zoxide. Error: $_"
|
||||
Write-Error "❌ Failed to install zoxide: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
Set-TiPSConfiguration -AutomaticallyWritePowerShellTip EverySession
|
||||
# Fabric patterns integration (with error handling)
|
||||
Write-Host "🧩 Loading Fabric AI patterns..." -ForegroundColor Cyan
|
||||
try {
|
||||
# Path to the patterns directory
|
||||
$patternsPath = Join-Path $HOME ".config/fabric/patterns"
|
||||
if (Test-Path $patternsPath) {
|
||||
$patternCount = 0
|
||||
foreach ($patternDir in Get-ChildItem -Path $patternsPath -Directory -ErrorAction SilentlyContinue) {
|
||||
$patternName = $patternDir.Name
|
||||
|
||||
# Finds files recursively matching a pattern.
|
||||
function ff($name) {
|
||||
Get-ChildItem -Recurse -Filter "*${name}*" -ErrorAction SilentlyContinue | ForEach-Object { Write-Output "${$_.directory}\$(%_)" }
|
||||
# Dynamically define a function for each pattern
|
||||
$functionDefinition = @"
|
||||
function $patternName {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(ValueFromPipeline = `$true)]
|
||||
[string] `$InputObject,
|
||||
|
||||
[Parameter(ValueFromRemainingArguments = `$true)]
|
||||
[String[]] `$patternArgs
|
||||
)
|
||||
|
||||
begin {
|
||||
# Initialize an array to collect pipeline input
|
||||
`$collector = @()
|
||||
}
|
||||
|
||||
process {
|
||||
# Collect pipeline input objects
|
||||
if (`$InputObject) {
|
||||
`$collector += `$InputObject
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
# Join all pipeline input into a single string, separated by newlines
|
||||
`$pipelineContent = `$collector -join "`n"
|
||||
|
||||
# If there's pipeline input, include it in the call to fabric
|
||||
if (`$pipelineContent) {
|
||||
`$pipelineContent | fabric --pattern $patternName `$patternArgs
|
||||
} else {
|
||||
# No pipeline input; just call fabric with the additional args
|
||||
fabric --pattern $patternName `$patternArgs
|
||||
}
|
||||
}
|
||||
}
|
||||
"@
|
||||
# Add the function to the current session
|
||||
Invoke-Expression $functionDefinition
|
||||
$patternCount++
|
||||
}
|
||||
Write-Host "✅ Loaded $patternCount Fabric patterns successfully" -ForegroundColor Green
|
||||
}
|
||||
else {
|
||||
Write-Host "ℹ️ Fabric patterns directory not found at: $patternsPath" -ForegroundColor Cyan
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Warning "⚠️ Failed to load fabric patterns: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
# Creates an empty file (similar to the touch command in Linux).
|
||||
# =============================================================================
|
||||
# FABRIC AI INTEGRATION FUNCTIONS
|
||||
# =============================================================================
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get YouTube video transcript using Fabric AI
|
||||
.DESCRIPTION
|
||||
Downloads and processes YouTube video transcripts using the Fabric AI tool
|
||||
Can optionally include timestamps in the transcript
|
||||
.PARAMETER t
|
||||
Switch to include timestamps in the transcript
|
||||
.PARAMETER videoLink
|
||||
The YouTube video URL to process
|
||||
.EXAMPLE
|
||||
yt "https://youtube.com/watch?v=example"
|
||||
yt -t "https://youtube.com/watch?v=example" # With timestamps
|
||||
#>
|
||||
function yt {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter()]
|
||||
[Alias("timestamps")]
|
||||
[switch]$t,
|
||||
|
||||
[Parameter(Position = 0, ValueFromPipeline = $true)]
|
||||
[string]$videoLink
|
||||
)
|
||||
|
||||
begin {
|
||||
$transcriptFlag = "--transcript"
|
||||
if ($t) {
|
||||
$transcriptFlag = "--transcript-with-timestamps"
|
||||
}
|
||||
}
|
||||
|
||||
process {
|
||||
if (-not $videoLink) {
|
||||
Write-Error "Usage: yt [-t | --timestamps] youtube-link"
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
if ($videoLink) {
|
||||
# Execute and allow output to flow through the pipeline
|
||||
fabric -y $videoLink $transcriptFlag
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# FILE SYSTEM UTILITIES
|
||||
# =============================================================================
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Fast file finder - search for files by name pattern
|
||||
.DESCRIPTION
|
||||
Recursively searches for files matching a name pattern from current directory
|
||||
Similar to Unix 'find' command but simpler syntax
|
||||
.PARAMETER name
|
||||
The search pattern to match against filenames (supports wildcards)
|
||||
.EXAMPLE
|
||||
ff "*.txt"
|
||||
ff "config"
|
||||
ff "package.json"
|
||||
#>
|
||||
function ff($name) {
|
||||
Get-ChildItem -Recurse -Filter "*${name}*" -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
Write-Output "$($_.Directory)\$($_.Name)"
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Create an empty file (Unix-style touch command)
|
||||
.DESCRIPTION
|
||||
Creates a new empty file or updates the timestamp of an existing file
|
||||
Mimics the behavior of the Unix 'touch' command
|
||||
.PARAMETER file
|
||||
The path and name of the file to create or touch
|
||||
.EXAMPLE
|
||||
touch "newfile.txt"
|
||||
touch "C:\temp\example.log"
|
||||
#>
|
||||
function touch($file) {
|
||||
"" | Out-File -File $file -Encoding ascii
|
||||
}
|
||||
|
||||
# Reloads the current profile.
|
||||
# =============================================================================
|
||||
# PROFILE MANAGEMENT FUNCTIONS
|
||||
# =============================================================================
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Reload the current PowerShell profile
|
||||
.DESCRIPTION
|
||||
Reloads the PowerShell profile to apply any changes made to the profile file
|
||||
Useful for testing profile modifications without restarting the terminal
|
||||
.EXAMPLE
|
||||
Update-Profile
|
||||
reload-profile
|
||||
#>
|
||||
function Update-Profile {
|
||||
& $PROFILE
|
||||
}
|
||||
|
||||
# Checks for and updates PowerShell to the latest version.
|
||||
# Alias for backward compatibility
|
||||
Set-Alias reload-profile Update-Profile
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Check for and install PowerShell updates
|
||||
.DESCRIPTION
|
||||
Checks GitHub for the latest PowerShell release and updates via winget if needed
|
||||
Includes network connectivity check to avoid unnecessary delays
|
||||
.EXAMPLE
|
||||
Update-PowerShell
|
||||
#>
|
||||
function Update-PowerShell {
|
||||
if (-not $global:canConnectToGitHub) {
|
||||
Write-Host "Skipping PowerShell update check due to GitHub.com not responding within 1 second." -ForegroundColor Yellow
|
||||
# Check if we can connect to GitHub with a faster, quieter method
|
||||
try {
|
||||
$response = Test-Connection -ComputerName "8.8.8.8" -Count 1 -Quiet -TimeoutSeconds 2
|
||||
if (-not $response) {
|
||||
Write-Host "Skipping PowerShell update check - no internet connection." -ForegroundColor Yellow
|
||||
return
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host "Skipping PowerShell update check - network unavailable." -ForegroundColor Yellow
|
||||
return
|
||||
}
|
||||
|
||||
@@ -135,54 +505,216 @@ function Update-PowerShell {
|
||||
Write-Error "Failed to update PowerShell. Error: $_"
|
||||
}
|
||||
}
|
||||
Update-PowerShell
|
||||
# Commented out automatic PowerShell update check to prevent slow profile loading
|
||||
# Run 'Update-PowerShell' manually when you want to check for updates
|
||||
# Update-PowerShell
|
||||
|
||||
# Searches for a regular expression in files (similar to the grep command in Linux).
|
||||
# =============================================================================
|
||||
# UNIX-LIKE UTILITY FUNCTIONS
|
||||
# =============================================================================
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Search for text patterns in files (Unix grep equivalent)
|
||||
.DESCRIPTION
|
||||
Searches for regex patterns in files or pipeline input
|
||||
Mimics the behavior of the Unix 'grep' command
|
||||
.PARAMETER regex
|
||||
The regular expression pattern to search for
|
||||
.PARAMETER dir
|
||||
Optional directory to search in (searches current dir if not specified)
|
||||
.EXAMPLE
|
||||
grep "error" *.log
|
||||
Get-Content file.txt | grep "pattern"
|
||||
grep "TODO" C:\Projects
|
||||
#>
|
||||
function grep($regex, $dir) {
|
||||
if ( $dir ) {
|
||||
Get-ChildItem $dir | select-string $regex
|
||||
if ($dir) {
|
||||
Get-ChildItem $dir | Select-String $regex
|
||||
return
|
||||
}
|
||||
$input | select-string $regex
|
||||
$input | Select-String $regex
|
||||
}
|
||||
|
||||
# Displays disk volume information.
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Find the location of a command (Unix which equivalent)
|
||||
.DESCRIPTION
|
||||
Locates the executable file for a given command name
|
||||
Mimics the behavior of the Unix 'which' command
|
||||
.PARAMETER command
|
||||
The name of the command to locate
|
||||
.EXAMPLE
|
||||
which "git"
|
||||
which "notepad"
|
||||
#>
|
||||
function which ($command) {
|
||||
Get-Command -Name $command -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Display disk usage information (Unix df equivalent)
|
||||
.DESCRIPTION
|
||||
Shows disk space usage for all mounted volumes
|
||||
Mimics the behavior of the Unix 'df' command
|
||||
.EXAMPLE
|
||||
df
|
||||
#>
|
||||
function df {
|
||||
get-volume
|
||||
}
|
||||
|
||||
# Displays the first n lines of a file8587
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Display the first lines of a file (Unix head equivalent)
|
||||
.DESCRIPTION
|
||||
Shows the first N lines of a text file (default: 10 lines)
|
||||
Mimics the behavior of the Unix 'head' command
|
||||
.PARAMETER Path
|
||||
The path to the file to read
|
||||
.PARAMETER n
|
||||
Number of lines to display (default: 10)
|
||||
.EXAMPLE
|
||||
head "file.txt"
|
||||
head "file.txt" 5
|
||||
#>
|
||||
function head {
|
||||
param($Path, $n = 10)
|
||||
Get-Content $Path -Head $n
|
||||
}
|
||||
|
||||
# Displays the last n lines of a file
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Display the last lines of a file (Unix tail equivalent)
|
||||
.DESCRIPTION
|
||||
Shows the last N lines of a text file (default: 10 lines)
|
||||
Mimics the behavior of the Unix 'tail' command
|
||||
.PARAMETER Path
|
||||
The path to the file to read
|
||||
.PARAMETER n
|
||||
Number of lines to display (default: 10)
|
||||
.EXAMPLE
|
||||
tail "file.txt"
|
||||
tail "logfile.log" 20
|
||||
#>
|
||||
function tail {
|
||||
param($Path, $n = 10)
|
||||
Get-Content $Path -Tail $n
|
||||
}
|
||||
|
||||
# Navigates to the Documents directory.
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Quick navigation to Documents folder
|
||||
.DESCRIPTION
|
||||
Changes the current directory to the user's Documents folder
|
||||
.EXAMPLE
|
||||
docs
|
||||
#>
|
||||
function docs { Set-Location -Path $HOME\Documents }
|
||||
|
||||
# Navigates to the Downloads directory.
|
||||
function dl { Set-Location -Path $HOME\Downloads }
|
||||
# =============================================================================
|
||||
# NETWORKING UTILITIES
|
||||
# =============================================================================
|
||||
|
||||
# Clears the DNS client cache.
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Flush DNS cache
|
||||
.DESCRIPTION
|
||||
Clears the DNS resolver cache to force fresh DNS lookups
|
||||
Useful for troubleshooting DNS issues
|
||||
.EXAMPLE
|
||||
flushdns
|
||||
#>
|
||||
function flushdns { Clear-DnsClientCache }
|
||||
|
||||
# Copies text to the clipboard.
|
||||
# =============================================================================
|
||||
# CLIPBOARD UTILITIES
|
||||
# =============================================================================
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Copy text to clipboard
|
||||
.DESCRIPTION
|
||||
Copies the specified text to the Windows clipboard
|
||||
.PARAMETER args
|
||||
The text to copy to clipboard
|
||||
.EXAMPLE
|
||||
cpy "Hello World"
|
||||
#>
|
||||
function cpy { Set-Clipboard $args[0] }
|
||||
|
||||
# Gets the text from the clipboard.
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Paste text from clipboard
|
||||
.DESCRIPTION
|
||||
Retrieves text from the Windows clipboard and displays it
|
||||
.EXAMPLE
|
||||
pst
|
||||
#>
|
||||
function pst { Get-Clipboard }
|
||||
|
||||
# Enhanced PowerShell Experience
|
||||
Set-PSReadLineOption -Colors @{
|
||||
Command = 'Yellow'
|
||||
Parameter = 'Green'
|
||||
String = 'DarkCyan'
|
||||
Write-Host "🎨 Configuring PowerShell color scheme..." -ForegroundColor Cyan
|
||||
try {
|
||||
Set-PSReadLineOption -Colors @{
|
||||
Command = 'Yellow'
|
||||
Parameter = 'Green'
|
||||
String = 'DarkCyan'
|
||||
}
|
||||
Write-Host "✅ Color scheme applied successfully" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Warning "⚠️ Failed to apply color scheme: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
# http://bin.christitus.com/unakijolon
|
||||
$env:GITHUB_PERSONAL_ACCESS_TOKEN = [Environment]::GetEnvironmentVariable("GITHUB_PERSONAL_ACCESS_TOKEN", "User")
|
||||
|
||||
# http://bin.christitus.com/unakijolon
|
||||
|
||||
function Sync-VSCodeProfile {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Syncs the current PowerShell profile to VS Code
|
||||
|
||||
.DESCRIPTION
|
||||
Creates or updates the VS Code PowerShell profile to source this main profile,
|
||||
keeping all your customizations in sync between regular PowerShell and VS Code.
|
||||
#>
|
||||
$mainProfile = $PROFILE.CurrentUserCurrentHost
|
||||
$vscodeProfile = $mainProfile -replace "Microsoft\.PowerShell", "Microsoft.VSCode"
|
||||
|
||||
if (Test-Path $mainProfile) {
|
||||
$vscodeContent = @"
|
||||
# VS Code PowerShell Profile
|
||||
# This profile sources the main PowerShell profile to keep them in sync
|
||||
# Last synced: $(Get-Date)
|
||||
|
||||
# Source the main PowerShell profile
|
||||
`$mainProfile = "$mainProfile"
|
||||
if (Test-Path `$mainProfile) {
|
||||
. `$mainProfile
|
||||
Write-Host "✅ Loaded main PowerShell profile in VS Code" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Warning "Main PowerShell profile not found at: `$mainProfile"
|
||||
}
|
||||
|
||||
# VS Code specific customizations can go here if needed
|
||||
"@
|
||||
|
||||
Set-Content -Path $vscodeProfile -Value $vscodeContent -Encoding UTF8
|
||||
Write-Host "✅ VS Code profile synced successfully!" -ForegroundColor Green
|
||||
Write-Host "Location: $vscodeProfile" -ForegroundColor Cyan
|
||||
}
|
||||
else {
|
||||
Write-Error "Main PowerShell profile not found at: $mainProfile"
|
||||
}
|
||||
}
|
||||
|
||||
Set-Alias syncvscode Sync-VSCodeProfile
|
||||
|
||||
# Profile loading complete
|
||||
Write-Host "" # Empty line for spacing
|
||||
Write-Host "🎉 PowerShell profile loaded successfully!" -ForegroundColor Green
|
||||
Write-Host " Type 'Get-Help about_profiles' for more information" -ForegroundColor Gray
|
||||
Write-Host " Use 'syncvscode' to sync this profile with VS Code" -ForegroundColor Gray
|
||||
|
||||
Reference in New Issue
Block a user