From df4d3b03338556bc7a1b7f5ad1361acde3171e42 Mon Sep 17 00:00:00 2001 From: juancwu <46619361+juancwu@users.noreply.github.com> Date: Thu, 31 Jul 2025 15:05:52 -0400 Subject: [PATCH] add powershell profile --- powershell/Microsoft.PowerShell_profile.ps1 | 142 ++++++++++++++++++++ powershell/README.md | 78 +++++++++++ powershell/setup.ps1 | 45 +++++++ 3 files changed, 265 insertions(+) create mode 100644 powershell/Microsoft.PowerShell_profile.ps1 create mode 100644 powershell/README.md create mode 100644 powershell/setup.ps1 diff --git a/powershell/Microsoft.PowerShell_profile.ps1 b/powershell/Microsoft.PowerShell_profile.ps1 new file mode 100644 index 0000000..3356259 --- /dev/null +++ b/powershell/Microsoft.PowerShell_profile.ps1 @@ -0,0 +1,142 @@ +# PowerShell equivalents of bash functions from .bashrc.arch + +# Fuzzy cd into specific folders +function fcd { + param( + [string]$Filter = "" + ) + + $dirs = @() + + # Add .config directories + $dirs += Get-ChildItem "$env:HOME/.config" -Directory -Force | Select-Object -ExpandProperty FullName + $dirs += Get-ChildItem "$env:HOME/.config" -Force | Where-Object { $_.Attributes -band [System.IO.FileAttributes]::ReparsePoint } | Select-Object -ExpandProperty FullName + + # Add .cache directories + $dirs += Get-ChildItem "$env:HOME/.cache" -Directory -Force | Select-Object -ExpandProperty FullName + + # Add ghq directories (depth 2) + if (Test-Path "$env:HOME/ghq") { + $dirs += Get-ChildItem "$env:HOME/ghq" -Directory | ForEach-Object { + Get-ChildItem $_.FullName -Directory | Select-Object -ExpandProperty FullName + } + } + + # Add home directories (excluding .git) + $dirs += Get-ChildItem "$env:HOME" -Directory | Where-Object { $_.Name -notmatch '^\.git$' } | Select-Object -ExpandProperty FullName + + if ($Filter) { + $selected = $dirs | fzf --filter="$Filter" --select-1 --exit-0 | Select-Object -First 1 + } else { + $selected = $dirs | fzf + } + + if ($selected) { + Set-Location $selected + + # Check for .nvmrc and switch Node version if needed + if (Test-Path ".nvmrc") { + $nvmrcVersion = Get-Content ".nvmrc" + $currentVersion = nvm current + if ($nvmrcVersion -ne $currentVersion) { + nvm use + } + } + } else { + Write-Host "ERROR: No selection made." -ForegroundColor Red + } +} + +# Clone repository function +function cl { + param( + [Parameter(Position=0)] + [string]$Arg1, + [Parameter(Position=1)] + [string]$Arg2, + [Parameter(Position=2)] + [string]$Arg3 + ) + + if (-not $Arg1) { + # Show help text + Write-Host "Usage: cl REPOSITORY_NAME" + Write-Host "Usage: cl REPOSITORY_URL" + Write-Host "Usage: cl (hub|lab) REPOSITORY_NAME" + Write-Host "Usage: cl (hub|lab) NAMESPACE REPOSITORY_NAME" + return + } + + $url = $Arg1 + $ghqDir = "$env:HOME/ghq" + $namespace = "" + $repositoryName = "" + + # Check if it's a full Git URL + if ($url -match 'git@git(lab|hub)\.com:([^/]+)/([^/]+)\.git') { + $namespace = $Matches[2] + $repositoryName = $Matches[3] + } + elseif ($url -match 'https://git(lab|hub)\.com/([^/]+)/([^/]+)(\.git)?') { + $namespace = $Matches[2] + $repositoryName = $Matches[3] + } + else { + # Handle shorthand formats + $repositoryName = $Arg1 + $namespace = "juancwu" + $domain = "hub" # Default to GitHub + + # Check if domain was provided + if ($Arg2) { + if ($Arg1 -eq "hub" -or $Arg1 -eq "lab") { + $domain = $Arg1 + $repositoryName = $Arg2 + } else { + $repositoryName = $Arg1 + } + } + + # Check if namespace was also provided + if ($Arg3) { + $domain = $Arg1 + $namespace = $Arg2 + $repositoryName = $Arg3 + } + + $url = "git@git$domain.com:$namespace/$repositoryName.git" + } + + # Create directory if it doesn't exist + $repositoryDir = Join-Path $ghqDir $namespace $repositoryName + if (-not (Test-Path $repositoryDir)) { + New-Item -ItemType Directory -Path $repositoryDir -Force | Out-Null + } + + # Clone the repository + git clone $url $repositoryDir +} + +# Additional helper function: fuzzy find all directories from current directory +function cdf { + param( + [string]$Filter = "" + ) + + if ($Filter) { + $selected = Get-ChildItem . -Recurse -Directory | Select-Object -ExpandProperty FullName | fzf --filter="$Filter" --select-1 --exit-0 | Select-Object -First 1 + } else { + $selected = Get-ChildItem . -Recurse -Directory | Select-Object -ExpandProperty FullName | fzf + } + + if ($selected) { + Set-Location $selected + } +} + +# Set aliases similar to bash +Set-Alias -Name gs -Value "git status" + +# Note: For Windows, you'll need to install fzf separately: +# Install-Module -Name PSFzf -Scope CurrentUser -Force +# Or use scoop: scoop install fzf \ No newline at end of file diff --git a/powershell/README.md b/powershell/README.md new file mode 100644 index 0000000..97fc090 --- /dev/null +++ b/powershell/README.md @@ -0,0 +1,78 @@ +# PowerShell Configuration + +This directory contains PowerShell equivalents of the bash functions from `.bashrc.arch`. + +## Functions + +### `fcd` - Fuzzy Change Directory +Searches through predefined directories and allows fuzzy selection: +- `~/.config` directories +- `~/.cache` directories +- `~/ghq` repositories (2 levels deep) +- Home directories (excluding .git) + +Usage: +```powershell +fcd # Interactive fuzzy search +fcd dotfiles # Quick filter and select best match +``` + +### `cl` - Clone Repository +Smart git clone that organizes repositories in `~/ghq` structure. + +Usage: +```powershell +cl repo-name # Clones from github.com/juancwu/repo-name +cl hub repo-name # Clones from github.com/juancwu/repo-name +cl lab repo-name # Clones from gitlab.com/juancwu/repo-name +cl hub namespace repo-name # Clones from github.com/namespace/repo-name +cl git@github.com:user/repo.git # Clones using full URL +``` + +### `cdf` - Change Directory Fuzzy +Searches all subdirectories from current location. + +Usage: +```powershell +cdf # Interactive fuzzy search +cdf src # Quick filter for directories containing "src" +``` + +## Installation + +### Automatic Setup +```powershell +cd ~/ghq/juancwu/dotfiles/powershell +./setup.ps1 +``` + +### Manual Setup +1. Copy profile to PowerShell profile location: + ```powershell + cp Microsoft.PowerShell_profile.ps1 $PROFILE + ``` + +2. Install dependencies: + - **fzf** (required for fuzzy search): + ```powershell + # Using Scoop + scoop install fzf + + # Using Chocolatey + choco install fzf + + # Using PowerShell Gallery + Install-Module -Name PSFzf -Scope CurrentUser + ``` + +3. Reload profile: + ```powershell + . $PROFILE + ``` + +## Notes + +- The functions maintain compatibility with the bash versions +- Node version switching with nvm is supported in `fcd` +- Git aliases like `gs` for `git status` are included +- All paths use PowerShell's cross-platform `$env:HOME` variable \ No newline at end of file diff --git a/powershell/setup.ps1 b/powershell/setup.ps1 new file mode 100644 index 0000000..971713f --- /dev/null +++ b/powershell/setup.ps1 @@ -0,0 +1,45 @@ +# PowerShell Profile Setup Script + +# Determine the PowerShell profile directory +$profileDir = Split-Path $PROFILE -Parent + +# Create profile directory if it doesn't exist +if (-not (Test-Path $profileDir)) { + New-Item -ItemType Directory -Path $profileDir -Force | Out-Null + Write-Host "Created PowerShell profile directory: $profileDir" -ForegroundColor Green +} + +# Copy the profile file +$sourceProfile = Join-Path $PSScriptRoot "Microsoft.PowerShell_profile.ps1" +$targetProfile = $PROFILE + +if (Test-Path $sourceProfile) { + Copy-Item $sourceProfile $targetProfile -Force + Write-Host "PowerShell profile installed to: $targetProfile" -ForegroundColor Green +} else { + Write-Host "ERROR: Source profile not found at $sourceProfile" -ForegroundColor Red + exit 1 +} + +# Check if fzf is installed +try { + $null = Get-Command fzf -ErrorAction Stop + Write-Host "fzf is already installed" -ForegroundColor Green +} catch { + Write-Host "WARNING: fzf is not installed. The fcd and cdf functions require fzf." -ForegroundColor Yellow + Write-Host "Install fzf using one of these methods:" -ForegroundColor Yellow + Write-Host " - Windows: scoop install fzf" -ForegroundColor Cyan + Write-Host " - Windows: choco install fzf" -ForegroundColor Cyan + Write-Host " - Cross-platform: Install-Module -Name PSFzf -Scope CurrentUser" -ForegroundColor Cyan +} + +# Check if git is installed +try { + $null = Get-Command git -ErrorAction Stop + Write-Host "git is already installed" -ForegroundColor Green +} catch { + Write-Host "WARNING: git is not installed. The cl function requires git." -ForegroundColor Yellow +} + +Write-Host "`nSetup complete! Reload your PowerShell profile with:" -ForegroundColor Green +Write-Host " . `$PROFILE" -ForegroundColor Cyan \ No newline at end of file