Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use ANSI color codes if SupportsVirtualTerminal #304

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 121 additions & 0 deletions ConsoleMode.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Hack! https://gist.github.com/lzybkr/f2059cb2ee8d0c13c65ab933b75e998c

Add-Type @"
using System;
using System.Runtime.InteropServices;

public class NativeConsoleMethods
{
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr GetStdHandle(int handleId);

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool GetConsoleMode(IntPtr hConsoleOutput, out uint dwMode);

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool SetConsoleMode(IntPtr hConsoleOutput, uint dwMode);

public static uint GetConsoleMode(bool input = false)
{
var handle = GetStdHandle(input ? -10 : -11);
uint mode;
if (GetConsoleMode(handle, out mode))
{
return mode;
}
return 0xffffffff;
}

public static uint SetConsoleMode(bool input, uint mode)
{
var handle = GetStdHandle(input ? -10 : -11);
if (SetConsoleMode(handle, mode))
{
return GetConsoleMode(input);
}
return 0xffffffff;
}
}
"@

[Flags()]
enum ConsoleModeInputFlags
{
ENABLE_PROCESSED_INPUT = 0x0001
ENABLE_LINE_INPUT = 0x0002
ENABLE_ECHO_INPUT = 0x0004
ENABLE_WINDOW_INPUT = 0x0008
ENABLE_MOUSE_INPUT = 0x0010
ENABLE_INSERT_MODE = 0x0020
ENABLE_QUICK_EDIT_MODE = 0x0040
ENABLE_EXTENDED_FLAGS = 0x0080
ENABLE_AUTO_POSITION = 0x0100
ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0200
}

[Flags()]
enum ConsoleModeOutputFlags
{
ENABLE_PROCESSED_OUTPUT = 0x0001
ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002
ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004
}

function Get-ConsoleMode
{
[CmdletBinding()]
param(
[switch]
$StandardInput
)

$mode = [NativeConsoleMethods]::GetConsoleMode($StandardInput)
if ($StandardInput)
{
[ConsoleModeInputFlags]$mode
}
else
{
[ConsoleModeOutputFlags]$mode
}
}

function Set-ConsoleMode
{
param(
[Parameter(ParameterSetName = "ANSI")]
[switch]
$ANSI,

[Parameter(ParameterSetName = "Mode")]
[uint32]
$Mode,

[switch]
$StandardInput
)

if ($ANSI)
{
$outputMode = [NativeConsoleMethods]::GetConsoleMode($false)
$null = [NativeConsoleMethods]::SetConsoleMode($false, $outputMode -bor [ConsoleModeOutputFlags]::ENABLE_VIRTUAL_TERMINAL_PROCESSING)

if ($StandardInput)
{
$inputMode = [NativeConsoleMethods]::GetConsoleMode($true)
$null = [NativeConsoleMethods]::SetConsoleMode($true, $inputMode -bor [ConsoleModeInputFlags]::ENABLE_VIRTUAL_TERMINAL_PROCESSING)
}
}
else
{
[NativeConsoleMethods]::SetConsoleMode($StandardInput, $Mode)
}
}

function Reset-Colors
{
$mode = [NativeConsoleMethods]::GetConsoleMode()
Set-ConsoleMode -ANSI
"$([char]0x1b)[0m"
[NativeConsoleMethods]::SetConsoleMode($false, $mode)
}
54 changes: 35 additions & 19 deletions GitPrompt.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ $global:GitPromptSettings = New-Object PSObject -Property @{

EnableWindowTitle = 'posh~git ~ '

AnsiConsole = $Host.UI.SupportsVirtualTerminal -or ($Env:ConEmuANSI -eq "ON")

Debug = $false

BranchNameLimit = 0
Expand All @@ -106,11 +108,18 @@ if (Get-Module NuGet) {
}

function Write-Prompt($Object, $ForegroundColor, $BackgroundColor = -1) {
if ($GitPromptSettings.AnsiConsole) {
$e = [char]27 + "["
$f = Get-ForegroundVirtualTerminalSequence $ForegroundColor
$b = Get-BackgroundVirtualTerminalSequence $BackgroundColor
return "${f}${b}${Object}${e}0m"
}
if ($BackgroundColor -lt 0) {
Write-Host $Object -NoNewLine -ForegroundColor $ForegroundColor
} else {
Write-Host $Object -NoNewLine -ForegroundColor $ForegroundColor -BackgroundColor $BackgroundColor
}
return ""
}

function Format-BranchName($branchName){
Expand All @@ -126,8 +135,9 @@ function Format-BranchName($branchName){

function Write-GitStatus($status) {
$s = $global:GitPromptSettings
$p = ''
if ($status -and $s) {
Write-Prompt $s.BeforeText -BackgroundColor $s.BeforeBackgroundColor -ForegroundColor $s.BeforeForegroundColor
$p += Write-Prompt $s.BeforeText -BackgroundColor $s.BeforeBackgroundColor -ForegroundColor $s.BeforeForegroundColor

$branchStatusSymbol = $null
$branchStatusBackgroundColor = $s.BranchBackgroundColor
Expand Down Expand Up @@ -160,47 +170,47 @@ function Write-GitStatus($status) {
$branchStatusSymbol = "?"
}

Write-Prompt (Format-BranchName($status.Branch)) -BackgroundColor $branchStatusBackgroundColor -ForegroundColor $branchStatusForegroundColor
$p += Write-Prompt (Format-BranchName($status.Branch)) -BackgroundColor $branchStatusBackgroundColor -ForegroundColor $branchStatusForegroundColor

if ($branchStatusSymbol) {
Write-Prompt (" {0}" -f $branchStatusSymbol) -BackgroundColor $branchStatusBackgroundColor -ForegroundColor $branchStatusForegroundColor
$p += Write-Prompt (" {0}" -f $branchStatusSymbol) -BackgroundColor $branchStatusBackgroundColor -ForegroundColor $branchStatusForegroundColor
}

if($s.EnableFileStatus -and $status.HasIndex) {
Write-Prompt $s.BeforeIndexText -BackgroundColor $s.BeforeIndexBackgroundColor -ForegroundColor $s.BeforeIndexForegroundColor
$p += Write-Prompt $s.BeforeIndexText -BackgroundColor $s.BeforeIndexBackgroundColor -ForegroundColor $s.BeforeIndexForegroundColor

if($s.ShowStatusWhenZero -or $status.Index.Added) {
Write-Prompt (" $($s.FileAddedText)$($status.Index.Added.Count)") -BackgroundColor $s.IndexBackgroundColor -ForegroundColor $s.IndexForegroundColor
$p += Write-Prompt (" $($s.FileAddedText)$($status.Index.Added.Count)") -BackgroundColor $s.IndexBackgroundColor -ForegroundColor $s.IndexForegroundColor
}
if($s.ShowStatusWhenZero -or $status.Index.Modified) {
Write-Prompt (" $($s.FileModifiedText)$($status.Index.Modified.Count)") -BackgroundColor $s.IndexBackgroundColor -ForegroundColor $s.IndexForegroundColor
$p += Write-Prompt (" $($s.FileModifiedText)$($status.Index.Modified.Count)") -BackgroundColor $s.IndexBackgroundColor -ForegroundColor $s.IndexForegroundColor
}
if($s.ShowStatusWhenZero -or $status.Index.Deleted) {
Write-Prompt (" $($s.FileRemovedText)$($status.Index.Deleted.Count)") -BackgroundColor $s.IndexBackgroundColor -ForegroundColor $s.IndexForegroundColor
$p += Write-Prompt (" $($s.FileRemovedText)$($status.Index.Deleted.Count)") -BackgroundColor $s.IndexBackgroundColor -ForegroundColor $s.IndexForegroundColor
}

if ($status.Index.Unmerged) {
Write-Prompt (" $($s.FileConflictedText)$($status.Index.Unmerged.Count)") -BackgroundColor $s.IndexBackgroundColor -ForegroundColor $s.IndexForegroundColor
$p += Write-Prompt (" $($s.FileConflictedText)$($status.Index.Unmerged.Count)") -BackgroundColor $s.IndexBackgroundColor -ForegroundColor $s.IndexForegroundColor
}

if($status.HasWorking) {
Write-Prompt $s.DelimText -BackgroundColor $s.DelimBackgroundColor -ForegroundColor $s.DelimForegroundColor
$p += Write-Prompt $s.DelimText -BackgroundColor $s.DelimBackgroundColor -ForegroundColor $s.DelimForegroundColor
}
}

if($s.EnableFileStatus -and $status.HasWorking) {
if($s.ShowStatusWhenZero -or $status.Working.Added) {
Write-Prompt (" $($s.FileAddedText)$($status.Working.Added.Count)") -BackgroundColor $s.WorkingBackgroundColor -ForegroundColor $s.WorkingForegroundColor
$p += Write-Prompt (" $($s.FileAddedText)$($status.Working.Added.Count)") -BackgroundColor $s.WorkingBackgroundColor -ForegroundColor $s.WorkingForegroundColor
}
if($s.ShowStatusWhenZero -or $status.Working.Modified) {
Write-Prompt (" $($s.FileModifiedText)$($status.Working.Modified.Count)") -BackgroundColor $s.WorkingBackgroundColor -ForegroundColor $s.WorkingForegroundColor
$p += Write-Prompt (" $($s.FileModifiedText)$($status.Working.Modified.Count)") -BackgroundColor $s.WorkingBackgroundColor -ForegroundColor $s.WorkingForegroundColor
}
if($s.ShowStatusWhenZero -or $status.Working.Deleted) {
Write-Prompt (" $($s.FileRemovedText)$($status.Working.Deleted.Count)") -BackgroundColor $s.WorkingBackgroundColor -ForegroundColor $s.WorkingForegroundColor
$p += Write-Prompt (" $($s.FileRemovedText)$($status.Working.Deleted.Count)") -BackgroundColor $s.WorkingBackgroundColor -ForegroundColor $s.WorkingForegroundColor
}

if ($status.Working.Unmerged) {
Write-Prompt (" $($s.FileConflictedText)$($status.Working.Unmerged.Count)") -BackgroundColor $s.WorkingBackgroundColor -ForegroundColor $s.WorkingForegroundColor
$p += Write-Prompt (" $($s.FileConflictedText)$($status.Working.Unmerged.Count)") -BackgroundColor $s.WorkingBackgroundColor -ForegroundColor $s.WorkingForegroundColor
}
}

Expand All @@ -222,16 +232,16 @@ function Write-GitStatus($status) {
}

if ($localStatusSymbol) {
Write-Prompt (" {0}" -f $localStatusSymbol) -BackgroundColor $localStatusBackgroundColor -ForegroundColor $localStatusForegroundColor
$p += Write-Prompt (" {0}" -f $localStatusSymbol) -BackgroundColor $localStatusBackgroundColor -ForegroundColor $localStatusForegroundColor
}

if ($s.EnableStashStatus -and ($status.StashCount -gt 0)) {
Write-Prompt $s.BeforeStashText -BackgroundColor $s.BeforeStashBackgroundColor -ForegroundColor $s.BeforeStashForegroundColor
Write-Prompt $status.StashCount -BackgroundColor $s.StashBackgroundColor -ForegroundColor $s.StashForegroundColor
Write-Prompt $s.AfterStashText -BackgroundColor $s.AfterStashBackgroundColor -ForegroundColor $s.AfterStashForegroundColor
$p += Write-Prompt $s.BeforeStashText -BackgroundColor $s.BeforeStashBackgroundColor -ForegroundColor $s.BeforeStashForegroundColor
$p += Write-Prompt $status.StashCount -BackgroundColor $s.StashBackgroundColor -ForegroundColor $s.StashForegroundColor
$p += Write-Prompt $s.AfterStashText -BackgroundColor $s.AfterStashBackgroundColor -ForegroundColor $s.AfterStashForegroundColor
}

Write-Prompt $s.AfterText -BackgroundColor $s.AfterBackgroundColor -ForegroundColor $s.AfterForegroundColor
$p += Write-Prompt $s.AfterText -BackgroundColor $s.AfterBackgroundColor -ForegroundColor $s.AfterForegroundColor

if ($WindowTitleSupported -and $s.EnableWindowTitle) {
if( -not $Global:PreviousWindowTitle ) {
Expand All @@ -241,8 +251,11 @@ function Write-GitStatus($status) {
$prefix = if ($s.EnableWindowTitle -is [string]) { $s.EnableWindowTitle } else { '' }
$Host.UI.RawUI.WindowTitle = "$script:adminHeader$prefix$repoName [$($status.Branch)]"
}

return $p
} elseif ( $Global:PreviousWindowTitle ) {
$Host.UI.RawUI.WindowTitle = $Global:PreviousWindowTitle
return ""
}
}

Expand All @@ -262,7 +275,10 @@ if ($Host.UI.RawUI.BackgroundColor -eq [ConsoleColor]::DarkMagenta) {
$s.WorkingForegroundColor = $s.WorkingForegroundBrightColor
}

function Global:Write-VcsStatus { $Global:VcsPromptStatuses | foreach { & $_ } }
function Global:Write-VcsStatus {
Set-ConsoleMode -ANSI
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works! 🎉

$Global:VcsPromptStatuses | foreach { & $_ }
}

# Add scriptblock that will execute for Write-VcsStatus
$PoshGitVcsPrompt = {
Expand Down
37 changes: 37 additions & 0 deletions Utils.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,43 @@ function Get-LocalOrParentPath($path) {
return $null
}

# Color codes from https://msdn.microsoft.com/en-us/library/windows/desktop/mt638032(v=vs.85).aspx
$ConsoleColorToAnsi = @(
30 # Black
34 # DarkBlue
32 # DarkGreen
36 # DarkCyan
31 # DarkRed
35 # DarkMagenta
33 # DarkYellow
37 # Gray
90 # DarkGray
94 # Blue
92 # Green
96 # Cyan
91 # Red
95 # Magenta
93 # Yellow
97 # White
)
$AnsiDefaultColor = 39
$AnsiEscape = [char]27 + "["

function Get-VirtualTerminalSequence ([ConsoleColor]$color, [int]$offset = 0) {
if (($color -lt 0) -or ($color -gt 15)) {
return "${AnsiEscape}$($AnsiDefaultColor + $offset)m"
}
return "${AnsiEscape}$($ConsoleColorToAnsi[$color] + $offset)m"
}

function Get-ForegroundVirtualTerminalSequence($Color) {
return Get-VirtualTerminalSequence $Color
}

function Get-BackgroundVirtualTerminalSequence($Color) {
return Get-VirtualTerminalSequence $Color 10
}

function dbg ($Message, [Diagnostics.Stopwatch]$Stopwatch) {
if($Stopwatch) {
Write-Verbose ('{0:00000}:{1}' -f $Stopwatch.ElapsedMilliseconds,$Message) -Verbose # -ForegroundColor Yellow
Expand Down
1 change: 1 addition & 0 deletions posh-git.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ if ($psv.Major -lt 3 -and !$NoVersionWarn) {
Push-Location $psScriptRoot
.\CheckVersion.ps1 > $null

. .\ConsoleMode.ps1
. .\Utils.ps1
. .\GitUtils.ps1
. .\GitPrompt.ps1
Expand Down
4 changes: 2 additions & 2 deletions profile.example.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ function global:prompt {

Write-Host($pwd.ProviderPath) -nonewline

Write-VcsStatus
$p = Write-VcsStatus

$global:LASTEXITCODE = $realLASTEXITCODE
return "> "
return $p + "> "
}

Pop-Location
Expand Down