Public/Install-TerminalColorsProfile.ps1
|
$script:TcProfileBeginMarker = '# >>> TerminalColors >>>' $script:TcProfileEndMarker = '# <<< TerminalColors <<<' function Get-TcProfileBlock { param([string] $EnableArguments) $call = 'Enable-TerminalColors' if ($EnableArguments) { $call = "Enable-TerminalColors $EnableArguments" } return @( $script:TcProfileBeginMarker '# Automatic terminal colouring based on the current directory.' '# Block managed by TerminalColors: Install-TerminalColorsProfile replaces it,' '# Uninstall-TerminalColorsProfile removes it. You can also edit it by hand' '# (to change -Tint, for instance).' '# The WT_SESSION test avoids any startup cost outside Windows Terminal;' '# remove it to colour other compatible terminals as well.' 'if ($env:WT_SESSION) {' ' Import-Module TerminalColors -ErrorAction SilentlyContinue' " if (Get-Module TerminalColors) { $call }" '}' $script:TcProfileEndMarker ) -join [Environment]::NewLine } function Install-TerminalColorsProfile { <# .SYNOPSIS Adds (or updates) the TerminalColors activation in your PowerShell profile, so the colouring is active every time you open a terminal. .DESCRIPTION The inserted block is delimited by markers, which makes it possible to update or remove it cleanly without touching the rest of your profile. A backup of the profile is taken before it is modified. .PARAMETER ProfilePath Profile to modify. Defaults to the current user's [all hosts] profile ($PROFILE.CurrentUserAllHosts). .PARAMETER EnableArguments Arguments to pass to Enable-TerminalColors in the profile. Example: '-Tint 0.45 -NoWindowBorder' .PARAMETER NoBackup Does not write a backup copy. .EXAMPLE Install-TerminalColorsProfile .EXAMPLE Install-TerminalColorsProfile -EnableArguments '-Tint 0.45' #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')] [OutputType([pscustomobject])] param( [string] $ProfilePath, [string] $EnableArguments, [switch] $NoBackup ) if (-not $ProfilePath) { $ProfilePath = $PROFILE.CurrentUserAllHosts } $block = Get-TcProfileBlock -EnableArguments $EnableArguments $existing = '' if ([System.IO.File]::Exists($ProfilePath)) { $existing = [System.IO.File]::ReadAllText($ProfilePath) } $pattern = '(?s)' + [regex]::Escape($script:TcProfileBeginMarker) + '.*?' + [regex]::Escape($script:TcProfileEndMarker) $action = 'Add' if ([regex]::IsMatch($existing, $pattern)) { $newContent = [regex]::Replace($existing, $pattern, [System.Text.RegularExpressions.MatchEvaluator] { param($m) $block }) $action = 'Update' } elseif ([string]::IsNullOrWhiteSpace($existing)) { $newContent = $block + [Environment]::NewLine } else { $separator = [Environment]::NewLine if (-not $existing.EndsWith([Environment]::NewLine)) { $separator = [Environment]::NewLine + [Environment]::NewLine } $newContent = $existing + $separator + $block + [Environment]::NewLine } if ($newContent -eq $existing) { return [pscustomobject]@{ ProfilePath = $ProfilePath; Changed = $false; Action = 'No change'; Backup = $null } } $backupPath = $null if ($PSCmdlet.ShouldProcess($ProfilePath, "$action the TerminalColors block")) { $directory = Split-Path $ProfilePath -Parent if ($directory -and -not (Test-Path -LiteralPath $directory)) { New-Item -ItemType Directory -Path $directory -Force | Out-Null } if (-not $NoBackup -and [System.IO.File]::Exists($ProfilePath)) { $backupPath = '{0}.terminalcolors-backup-{1}' -f $ProfilePath, (Get-Date -Format 'yyyyMMdd-HHmmss') [System.IO.File]::Copy($ProfilePath, $backupPath, $true) } # UTF-8 with BOM: without one, Windows PowerShell 5.1 reads profiles in the # ANSI code page, which would corrupt any non-ASCII text the user has put # in there. $encoding = New-Object System.Text.UTF8Encoding($true) [System.IO.File]::WriteAllText($ProfilePath, $newContent, $encoding) } return [pscustomobject]@{ ProfilePath = $ProfilePath; Changed = $true; Action = $action; Backup = $backupPath } } function Uninstall-TerminalColorsProfile { <# .SYNOPSIS Removes the TerminalColors block from your PowerShell profile. .PARAMETER ProfilePath Profile to modify. Defaults to $PROFILE.CurrentUserAllHosts. .EXAMPLE Uninstall-TerminalColorsProfile #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')] param([string] $ProfilePath) if (-not $ProfilePath) { $ProfilePath = $PROFILE.CurrentUserAllHosts } if (-not [System.IO.File]::Exists($ProfilePath)) { Write-Warning "TerminalColors: profile not found [$ProfilePath]." return } $existing = [System.IO.File]::ReadAllText($ProfilePath) $pattern = '(?s)\s*' + [regex]::Escape($script:TcProfileBeginMarker) + '.*?' + [regex]::Escape($script:TcProfileEndMarker) if (-not [regex]::IsMatch($existing, $pattern)) { Write-Warning 'TerminalColors: no TerminalColors block in this profile.' return } $newContent = [regex]::Replace($existing, $pattern, '') if ($PSCmdlet.ShouldProcess($ProfilePath, 'Remove the TerminalColors block')) { $encoding = New-Object System.Text.UTF8Encoding($true) [System.IO.File]::WriteAllText($ProfilePath, $newContent, $encoding) } } function Test-TerminalColorsProfile { <# .SYNOPSIS Indicates whether the TerminalColors block is present in a PowerShell profile. .PARAMETER ProfilePath Profile to inspect. Defaults to $PROFILE.CurrentUserAllHosts. #> [CmdletBinding()] [OutputType([bool])] param([string] $ProfilePath) if (-not $ProfilePath) { $ProfilePath = $PROFILE.CurrentUserAllHosts } if (-not [System.IO.File]::Exists($ProfilePath)) { return $false } $existing = [System.IO.File]::ReadAllText($ProfilePath) return $existing.Contains($script:TcProfileBeginMarker) } |