ColoredText.psm1
#requires -Version 5.0 using namespace System.Management.Automation.Host using namespace System.Management.Automation using namespace System.Collections.Generic using module .\Src\PublicMethods.psm1 class ColoredText { [PSHost]$host = $global:host [String]$__text static [ConsoleColor]$DEFAULT_BACKGROUND = [ConsoleColor]::Black static [ConsoleColor]$DEFAULT_FOREGROUND = [ConsoleColor]::White static [ConsoleColor]$LAST_BACKGROUND = [ColoredText]::DEFAULT_BACKGROUND static [ConsoleColor]$LAST_FOREGROUND = [ColoredText]::DEFAULT_FOREGROUND [ConsoleColor]$background = [ColoredText]::DEFAULT_BACKGROUND [ConsoleColor]$foreground = [ColoredText]::DEFAULT_FOREGROUND [Boolean]$backgroundMode = $false [Boolean]$persistent = $false [Int]$leftPadding = 0 [Int]$rightPadding = 0 [Char]$paddingCharacter = 0x020 [ColoredText]newInstance() { return New-Object ColoredText } ColoredText() { } ColoredText([String]$text) { $this.__text = $text } hidden [Void]setBackground([ConsoleColor]$color) { [ColoredText]::LAST_BACKGROUND = $this.background = $color } hidden [Void]setForeground([ConsoleColor]$color) { [ColoredText]::LAST_FOREGROUND = $this.foreground = $color } hidden [String]prepareText() { return '{0}{1}{2}' -f "".PadLeft($this.leftPadding, $this.paddingCharacter), $this.__text, "".PadRight($this.rightPadding, $this.paddingCharacter) } [ColoredText]text([String]$text) { $this.__text = $text return $this } [ColoredText]color([ConsoleColor]$color) { if ($this.backgroundMode) { $this.setBackground($color) $this.backgroundMode = $false } else { $this.setForeground($color) } return $this } [ColoredText]on() { $this.backgroundMode = $true return $this } [ColoredText]print() { $this.host.UI.Write($this.foreground, $this.background, $this.prepareText()) return $this } [ColoredText]cr() { $this.host.UI.WriteLine() return $this } [ColoredText]reset() { $this.setBackground([ColoredText]::DEFAULT_BACKGROUND) $this.setForeground([ColoredText]::DEFAULT_FOREGROUND) return $this } [ColoredText]nopad() { $this.leftPadding = $this.rightPadding = 0 return $this } [ColoredText]lpad() { $this.leftPadding++ return $this } [ColoredText]rpad() { $this.rightPadding++ return $this } [ColoredText]black() { return $this.color([ConsoleColor]::black) } [ColoredText]blue() { return $this.color([ConsoleColor]::blue) } [ColoredText]cyan() { return $this.color([ConsoleColor]::cyan) } [ColoredText]gray() { return $this.color([ConsoleColor]::gray) } [ColoredText]green() { return $this.color([ConsoleColor]::green) } [ColoredText]magenta() { return $this.color([ConsoleColor]::magenta) } [ColoredText]red() { return $this.color([ConsoleColor]::red) } [ColoredText]white() { return $this.color([ConsoleColor]::white) } [ColoredText]yellow() { return $this.color([ConsoleColor]::yellow) } [ColoredText]darkblue() { return $this.color([ConsoleColor]::darkblue) } [ColoredText]darkcyan() { return $this.color([ConsoleColor]::darkcyan) } [ColoredText]darkgray() { return $this.color([ConsoleColor]::darkgray) } [ColoredText]darkgreen() { return $this.color([ConsoleColor]::darkgreen) } [ColoredText]darkmagenta() { return $this.color([ConsoleColor]::darkmagenta) } [ColoredText]darkred() { return $this.color([ConsoleColor]::darkred) } [ColoredText]darkyellow() { return $this.color([ConsoleColor]::darkyellow) } [ColoredText]persist() { $this.setBackground([ColoredText]::LAST_BACKGROUND) $this.setForeground([ColoredText]::LAST_FOREGROUND) $this.persistent = $true return $this } [ColoredText]next() { [Int]$index = $true [Boolean]$bgMode = $this.backgroundMode [ConsoleColor]$bg, [ConsoleColor]$fg = $this.background, $this.foreground if ($this.persistent) { [int]$bg = ([ColoredText]::LAST_BACKGROUND) [int]$fg = ([ColoredText]::LAST_FOREGROUND) } [int]$index += switch ($bgMode) { True { $bg } False { $fg } } $isLastColor = { $index -eq [Enum]::GetNames([ConsoleColor]).Count } $color = switch (& $isLastColor) { True { [ConsoleColor]::black } False { [Enum]::GetNames([ConsoleColor])[$index] } } # Set the current color. $this.color($color) # The previous call resets the "backgroundMode" # so we restore it, in case there is a color collision # and we'll need to skip one more color. $this.backgroundMode = $bgMode # Needs more tests to ensure there is no infinite loop possibility! if ($this.foreground -eq $this.background) { $this.next() } return $this } [ColoredText]rainbow() { $this.persist() return $this.next() } } function Format-Color { param ( [switch]$Debug, [switch]$PassThru ) process { [List[String]]$commands = $args [ColoredText]$text = [String]::Empty if ([Boolean]$_) { $commands.Insert(0, $_) } $isNotExposed = { [Enum]::GetNames([PublicMethods]) -notcontains $command } foreach ($command in $commands) { if (& $isNotExposed) { [Void]$text.text($command) continue } Invoke-Expression('$text.{0}()' -f $command) > $null if ($debug) { Write-Host $command } } if ($passThru) { return $text } } } New-Alias -Name cprint -Value Format-Color Register-ArgumentCompleter -CommandName cprint -ScriptBlock { param ( $wordToComplete, $commandAst, $cursorPosition ) $methods = [Enum]::GetValues([PublicMethods]) $matches = $methods | Where-Object { $_ -like "*$wordToComplete*" } $matches = switch ([Boolean]$matches.Count) { True { $matches } False { $methods } } $matches | Sort-Object | ForEach-Object { [CompletionResult]::new($_) } } |