src/Settings.ps1
|
#requires -Version 5.1 # Settings.ps1 - Configuration system for power-git # Provides typed settings, theme support, and per-repo overrides class PowerGitColor { [string]$Ansi # ANSI escape sequence (e.g. "$([char]27)[32m") [System.ConsoleColor]$Legacy # Legacy console color PowerGitColor([string]$ansi, [System.ConsoleColor]$legacy) { $this.Ansi = $ansi $this.Legacy = $legacy } static [PowerGitColor] FromRgb([byte]$r, [byte]$g, [byte]$b, [System.ConsoleColor]$legacy) { return [PowerGitColor]::new("$([char]27)[38;2;${r};${g};${b}m", $legacy) } static [PowerGitColor] FromAnsi256([byte]$n, [System.ConsoleColor]$legacy) { return [PowerGitColor]::new("$([char]27)[38;5;${n}m", $legacy) } static [PowerGitColor] Reset() { return [PowerGitColor]::new("$([char]27)[0m", [System.ConsoleColor]::Gray) } } class PowerGitSymbols { [string]$Branch = [char]0xE0A0 # Powerline branch (overridden by theme) [string]$Detached = [char]0x27A6 # ➦ [string]$Ahead = [char]0x2191 # ↑ [string]$Behind = [char]0x2193 # ↓ [string]$Diverged = [char]0x21C5 # ⇅ [string]$UpToDate = [char]0x2714 # ✔ [string]$Gone = [char]0x2717 # ✗ [string]$Staged = [char]0x2022 # • (indexed changes) [string]$Unstaged = [char]0x00B1 # ± (working dir changes) [string]$Untracked = [char]0x2026 # … (untracked files) [string]$Conflict = [char]0x25C6 # ◆ [string]$Stash = [char]0x2261 # ≡ [string]$Merging = 'MERGING' [string]$Rebasing = 'REBASING' [string]$CherryPicking = 'CHERRY-PICKING' [string]$Reverting = 'REVERTING' [string]$Bisecting = 'BISECTING' } class PowerGitSettings { # Rendering mode: 'Ansi' (ANSI escape sequences) or 'Legacy' (Write-Host ConsoleColor) [string]$WriterMode = 'Ansi' # Show git status in prompt [bool]$EnablePrompt = $true # Show file-level status counts (index/working). Disable for large repos. [bool]$ShowFileStatus = $true # Show stash count [bool]$ShowStashCount = $true # Show tag distance (e.g. v1.2-3-gabcdef) [bool]$ShowTagDistance = $false # Truncate long branch names to this length (0 = no truncation) [int]$BranchMaxLength = 0 # Cache git status for this many milliseconds (0 = no cache) [int]$StatusCacheMs = 500 # Repos to skip file status (large monorepos) [System.Collections.Generic.HashSet[string]]$DisableFileStatusRepos = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) # Colors [PowerGitColor]$BranchColor = [PowerGitColor]::new("$([char]27)[32m", [System.ConsoleColor]::Green) [PowerGitColor]$BranchAheadColor = [PowerGitColor]::new("$([char]27)[36m", [System.ConsoleColor]::Cyan) [PowerGitColor]$BranchBehindColor = [PowerGitColor]::new("$([char]27)[33m", [System.ConsoleColor]::Yellow) [PowerGitColor]$BranchDivergedColor = [PowerGitColor]::new("$([char]27)[31m", [System.ConsoleColor]::Red) [PowerGitColor]$BranchGoneColor = [PowerGitColor]::new("$([char]27)[90m", [System.ConsoleColor]::DarkGray) [PowerGitColor]$StagedColor = [PowerGitColor]::new("$([char]27)[32m", [System.ConsoleColor]::Green) [PowerGitColor]$UnstagedColor = [PowerGitColor]::new("$([char]27)[33m", [System.ConsoleColor]::Yellow) [PowerGitColor]$ConflictColor = [PowerGitColor]::new("$([char]27)[31;1m",[System.ConsoleColor]::Red) [PowerGitColor]$UntrackedColor = [PowerGitColor]::new("$([char]27)[90m", [System.ConsoleColor]::DarkGray) [PowerGitColor]$StateColor = [PowerGitColor]::new("$([char]27)[35m", [System.ConsoleColor]::Magenta) [PowerGitColor]$StashColor = [PowerGitColor]::new("$([char]27)[36m", [System.ConsoleColor]::Cyan) [PowerGitColor]$DelimiterColor = [PowerGitColor]::new("$([char]27)[37m", [System.ConsoleColor]::Gray) [PowerGitColor]$ResetColor = [PowerGitColor]::Reset() # Symbols [PowerGitSymbols]$Symbols = [PowerGitSymbols]::new() # Prompt delimiters [string]$BeforeText = ' [' [string]$AfterText = ']' # Apply a named theme [void] ApplyTheme([string]$name) { switch ($name) { 'Default' { & $script:Themes['Default'] $this; break } 'Minimal' { & $script:Themes['Minimal'] $this; break } 'Powerline' { & $script:Themes['Powerline'] $this; break } 'ASCII' { & $script:Themes['ASCII'] $this; break } default { Write-Warning "power-git: Unknown theme '$name'. Available: Default, Minimal, Powerline, ASCII" } } } } # Theme registry $script:Themes = @{} # Default theme - sensible defaults with Unicode symbols $script:Themes['Default'] = { param($s) $s.Symbols.Branch = '' $s.Symbols.Ahead = [char]0x2191 $s.Symbols.Behind = [char]0x2193 $s.Symbols.Diverged = [char]0x21C5 $s.Symbols.UpToDate = [char]0x2714 $s.Symbols.Gone = [char]0x2717 $s.Symbols.Staged = '+' $s.Symbols.Unstaged = '~' $s.Symbols.Untracked = '?' $s.Symbols.Conflict = '!' $s.Symbols.Stash = [char]0x2261 $s.BeforeText = ' [' $s.AfterText = ']' } # Minimal theme - plain ASCII, no colors on branch name $script:Themes['Minimal'] = { param($s) & $script:Themes['Default'] $s $s.Symbols.Branch = '' $s.Symbols.Ahead = '^' $s.Symbols.Behind = 'v' $s.Symbols.Diverged = '<>' $s.Symbols.UpToDate = '=' $s.Symbols.Gone = 'x' $s.Symbols.Stash = '$' $s.ShowStashCount = $false $s.ShowTagDistance = $false } # ASCII theme - pure ASCII, maximum compatibility $script:Themes['ASCII'] = { param($s) & $script:Themes['Minimal'] $s $s.Symbols.Staged = '+' $s.Symbols.Unstaged = '*' $s.Symbols.Untracked = '?' $s.Symbols.Conflict = '!' } # Powerline theme - nerd fonts glyphs $script:Themes['Powerline'] = { param($s) & $script:Themes['Default'] $s $s.Symbols.Branch = [char]0xE0A0 # $s.Symbols.Detached = [char]0xE0A3 # $s.Symbols.Staged = [char]0xF067 # (plus) $s.Symbols.Unstaged = [char]0xF069 # (asterisk-like) $s.Symbols.Conflict = [char]0xF06A # (exclamation) $s.Symbols.Untracked = [char]0xF128 # (question) $s.Symbols.Stash = [char]0xF01C # (inbox) $s.BeforeText = " $([char]0xE0B0) " $s.AfterText = " $([char]0xE0B1)" } # Factory function - creates fresh settings with auto-detected writer mode function New-PowerGitSettings { [OutputType([PowerGitSettings])] param( [string]$Theme = 'Default' ) $settings = [PowerGitSettings]::new() # Auto-detect ANSI support if (-not $env:TERM_PROGRAM -and -not $env:WT_SESSION -and -not $env:TERM -and $Host.Name -eq 'ConsoleHost' -and [System.Environment]::OSVersion.Version.Major -lt 10) { $settings.WriterMode = 'Legacy' } $settings.ApplyTheme($Theme) return $settings } |