From d066f32b1081ad3411d190b3730298c0ec19da53 Mon Sep 17 00:00:00 2001 From: Peter Wood Date: Wed, 18 Jun 2025 04:23:28 -0400 Subject: [PATCH] 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. --- dotfiles/Microsoft.PowerShell_profile.ps1 | 672 +++++++++++++++++++--- dotfiles/Microsoft.VSCode_profile.ps1 | 672 +++++++++++++++++++--- 2 files changed, 1204 insertions(+), 140 deletions(-) diff --git a/dotfiles/Microsoft.PowerShell_profile.ps1 b/dotfiles/Microsoft.PowerShell_profile.ps1 index a80787d..4ac6f91 100644 --- a/dotfiles/Microsoft.PowerShell_profile.ps1 +++ b/dotfiles/Microsoft.PowerShell_profile.ps1 @@ -1,52 +1,215 @@ +# ============================================================================= +# POWERSHELL PROFILE CONFIGURATION +# ============================================================================= +# Author: Peter Wood +# 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 \ No newline at end of file +$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 diff --git a/dotfiles/Microsoft.VSCode_profile.ps1 b/dotfiles/Microsoft.VSCode_profile.ps1 index a80787d..4ac6f91 100644 --- a/dotfiles/Microsoft.VSCode_profile.ps1 +++ b/dotfiles/Microsoft.VSCode_profile.ps1 @@ -1,52 +1,215 @@ +# ============================================================================= +# POWERSHELL PROFILE CONFIGURATION +# ============================================================================= +# Author: Peter Wood +# 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 \ No newline at end of file +$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