-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathPSColors.psm1
294 lines (232 loc) · 9.23 KB
/
PSColors.psm1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# Function to check wheter current Console support ANSI codes
function Test-Ansi {
# Powershell ISE don't support ANSI, and this test will print ugly chars there
if($host.PrivateData.ToString() -eq 'Microsoft.PowerShell.Host.ISE.ISEOptions') {
return $false;
}
# To test is console supports ANSI, we will print an ANSI code
# and check if cursor postion has changed. If it has, ANSI is not
# supported
$oldPos = $host.UI.RawUI.CursorPosition.X
Write-Host -NoNewline "$([char](27))[0m" -ForegroundColor ($host.UI.RawUI.BackgroundColor);
$pos = $host.UI.RawUI.CursorPosition.X
if($pos -eq $oldPos) {
return $true;
}
else {
# If ANSI is not supported, let's clean up ugly ANSI escapes
Write-Host -NoNewLine ("`b" * 4)
return $false
}
}
$Script:HasAnsi = Test-Ansi
if($Script:HasAnsi) {
# If ANSI is supported, save current console mode, so we can restore it latter.
# Some programs, like cygwin's git disables ANSI support in windows Console.
# This it will bad side effetcts from GIT.
$sig = '';
$sig = $sig + '[DllImport("kernel32.dll", SetLastError = true)] public static extern bool SetConsoleMode(IntPtr hConsoleHandle, int dwMode);';
$sig = $sig + '[DllImport("kernel32.dll", SetLastError = true)] public static extern bool GetConsoleMode(IntPtr hConsoleHandle, ref int nCmdShow);';
$sig = $sig + '[DllImport("kernel32.dll", SetLastError = true)] public static extern IntPtr GetStdHandle(int nStdHandle);';
Add-Type -MemberDefinition $sig -name PSColorsNativeMethods -namespace Win32;
$Script:ConsoleHandle = [Win32.PSColorsNativeMethods]::GetStdHandle(-11);
$Script:ConsoleMode = 0;
[Win32.PSColorsNativeMethods]::GetConsoleMode($Script:ConsoleHandle, [ref] $Script:ConsoleMode);
}
function Test-Git {
param([IO.DirectoryInfo] $dir)
# Function to check wheter directory is in a git repository
# If have .git dir, it's a git repo
if(Test-Path (Join-Path $dir.FullName '.git')) {
return $true;
}
# If reached root dir, we are not in a git repository
if(($dir.Parent -eq $null) -or ($dir -eq $dir.Parent)) {
return $false;
}
# Check parent dir. Let's hope PowerShell supports tail recursion
return Test-Git ($dir.Parent.FullName)
}
# Overriding PowerShell's default prompt function!
function prompt {
if($Script:HasAnsi) {
# Making sure we are restoing original Console Mode in case someone (e.g. GIT) has changed it
[Win32.PSColorsNativeMethods]::SetConsoleMode($Script:ConsoleHandle, $Script:ConsoleMode) | Out-Null
}
if($global:FSFormatDefaultColor) {
[Console]::ForegroundColor = $global:FSFormatDefaultColor
}
$isFS = (Get-Item .).PSProvider.Name -eq 'FileSystem';
if($isFS) {
# PowerShell don't change CurrentDirectory when you navigate throught File Sytem
# which causes problem when executing external programs providing relative paths
# This will fix the issue, syncing PowerShell current localtion to Windows Environment
[system.Environment]::CurrentDirectory = (Convert-Path ".");
}
#Check if current user has admin privilges so we can use a different color
$user = [Security.Principal.WindowsIdentity]::GetCurrent();
$admin = (New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
$branch = $null;
# Legancy functionality to display git branch. Recommend to use posh-git, as it has better info
# PSColors will not use its own branching displaying if it dectects posh-git is present
if(-not(Get-Command Write-VcsStatus -ErrorAction SilentlyContinue)) {
if( $isFS -and (Test-Git (Convert-Path .)) -and (Get-Command git)) {
$branch = (git branch 2>$null) | %{ ([regex] '\* (.*)').match($_) } | ? { $_.Success } | %{ $_.Groups[1].Value } | Select-Object -First 1
}
}
$drive = (Get-Location).Drive
if($drive.Root -eq "$($drive.Name):\") {
$title = $executionContext.SessionState.Path.CurrentLocation
if($branch) {
$title = "[$branch] $title";
}
}
else {
$title = $drive.Name
if($branch) {
$title = "$title@$branch";
}
}
$host.UI.RawUI.WindowTitle = $title
# Choosing color based on admin's privileges
if($admin) {
$color = 'Yellow';
}
else {
$color = 'Green';
}
Write-Host ([System.Char](10)) -NoNewLine;
# Print git branch, if posh-git is not present
if($branch) {
Write-Host "[" -NoNewLine -ForegroundColor Yellow
Write-Host "$branch" -NoNewLine -ForegroundColor Cyan
Write-Host "] " -NoNewLine -ForegroundColor Yellow
}
# If we have posh-git, use it
if(Get-Command Write-VcsStatus -ErrorAction SilentlyContinue) {
Write-VcsStatus;
}
# Write prompt info
Write-Host $executionContext.SessionState.Path.CurrentLocation -NoNewLine -ForegroundColor $color;
Write-Host ('>' * ($nestedPromptLevel + 1)) -NoNewLine -ForegroundColor $color;
# Prevents PowerShell default prompt printing
if($host.Name -like 'StudioShell*') {
return " ";
}
else {
return " `b";
}
}
# Wrapper for Get-ChildItem, that will aid PSColors.format.ps1xml detect if it's outputing to console,
# and hence use ANSI code for coloring different file types
function Get-ChildItem {
<#
.ForwardHelpTargetName Get-ChildItem
.ForwardHelpCategory Cmdlet
#>
[CmdletBinding(DefaultParameterSetName='Items', SupportsTransactions=$true, HelpUri='https://go.microsoft.com/fwlink/?LinkID=113308')]
param(
[Parameter(ParameterSetName='Items', Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[string[]]
${Path},
[Parameter(ParameterSetName='LiteralItems', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
[Alias('PSPath')]
[string[]]
${LiteralPath},
[Parameter(Position=1)]
[string]
${Filter},
[string[]]
${Include},
[string[]]
${Exclude},
[Alias('s')]
[switch]
${Recurse},
[uint32]
${Depth},
[switch]
${Force},
[System.IO.FileAttributes]
${Attributes},
[switch]
${Directory},
[switch]
${File},
[switch]
${Hidden},
[switch]
${ReadOnly},
[switch]
${System},
[switch]
${Name})
dynamicparam
{
try {
# Set global variable to indicates PSColors.format.ps1xml should output ANSI colors
$global:PSColorsUseAnsi = $Script:HasAnsi -and ($MyInvocation.PipelineLength -eq $MyInvocation.PipelinePosition);
$targetCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Management\Get-ChildItem', [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters)
$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object { $_.Value.IsDynamic })
if ($dynamicParams.Length -gt 0)
{
$paramDictionary = [Management.Automation.RuntimeDefinedParameterDictionary]::new()
foreach ($param in $dynamicParams)
{
$param = $param.Value
if(-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name))
{
$dynParam = [Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes)
$paramDictionary.Add($param.Name, $dynParam)
}
}
return $paramDictionary
}
} catch {
throw
}
}
begin
{
try {
$outBuffer = $null
if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
{
$PSBoundParameters['OutBuffer'] = 1
}
$showDotFiles = -not $env:PSCOLORS_HIDE_DOTFILE -or $env:PSCOLORS_HIDE_DOTFILE.ToLower() -ne 'true'
$wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Management\Get-ChildItem', [System.Management.Automation.CommandTypes]::Cmdlet)
$scriptCmd = {
& $wrappedCmd @PSBoundParameters `
| ? { $Force -or $showDotFiles -or ($_.Name -eq $null) -or -not $_.Name.StartsWith('.') }
}
$steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
$steppablePipeline.Begin($PSCmdlet)
} catch {
throw
}
}
process
{
try {
$steppablePipeline.Process($_)
} catch {
throw
}
}
end
{
try {
# Get-ChildItem has ended. PSColors.format.ps1xml will not longer append ANSI codes
$global:PSColorsUseAnsi = $false;
$steppablePipeline.End()
} catch {
throw
}
}
}
if($Script:HasAnsi) {
# If ANSI is active, use custom PSColors.format.ps1xml for output coloring
Update-FormatData -Prepend (Join-Path $PSScriptRoot PSColors.format.ps1xml)
}