From 08f63fa9e52bc5b4b9ab792d774ac70b803251c4 Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sat, 26 Aug 2023 13:46:16 -0700 Subject: [PATCH 01/41] Adding VersionControl (Fixes #230) --- Formatting/VersionControl.format.ps1 | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 Formatting/VersionControl.format.ps1 diff --git a/Formatting/VersionControl.format.ps1 b/Formatting/VersionControl.format.ps1 new file mode 100644 index 0000000..d9905c1 --- /dev/null +++ b/Formatting/VersionControl.format.ps1 @@ -0,0 +1,21 @@ +Write-FormatView -TypeName n/a -Name VersionControl -Action { + Write-FormatViewExpression -ScriptBlock { + if ($PSStyle) { + @(foreach ($versionPart in $_.ToString() -split "\.") { + @( + $PSStyle.Foreground.Cyan + $PSStyle.Bold + $versionPart + $PSStyle.Reset + ) -join '' + }) -join "$( + @( + $PSStyle.Foreground.Yellow + '.' + ) -join '' + )" + } else { + $_.ToString() + } + } +} -AsControl \ No newline at end of file From 83a3a9962a0ad228483fbb4e141bdb6f06cf3653 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sat, 26 Aug 2023 20:47:13 +0000 Subject: [PATCH 02/41] Adding VersionControl (Fixes #230) --- Posh.format.ps1xml | 1314 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 1042 insertions(+), 272 deletions(-) diff --git a/Posh.format.ps1xml b/Posh.format.ps1xml index a2496f0..dfbaf62 100644 --- a/Posh.format.ps1xml +++ b/Posh.format.ps1xml @@ -1,5 +1,5 @@ - + @@ -189,12 +189,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Foreground.Cyan','Bold') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -232,12 +248,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Formatting.Warning') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -292,12 +324,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Foreground.Cyan','Bold') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -315,12 +363,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Formatting.Warning') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -410,12 +474,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Foreground.Cyan','Bold') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -442,12 +522,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Foreground.Cyan','Bold') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -474,12 +570,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Formatting.Warning') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -538,12 +650,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Formatting.Verbose') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -561,12 +689,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Formatting.Warning') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -640,12 +784,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Foreground.Cyan','Bold') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -663,12 +823,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Formatting.Warning') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -716,12 +892,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Foreground.BrightBlack') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -747,12 +939,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Foreground.BrightBlue','Bold') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -790,12 +998,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Foreground.BrightBlack') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -827,12 +1051,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Foreground.Green') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -858,12 +1098,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Foreground.BrightGreen') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -899,12 +1155,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Foreground.BrightBlack') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -927,12 +1199,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Foreground.BrightBlue','Bold') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -951,12 +1239,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Foreground.BrightBlack') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -995,12 +1299,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Foreground.BrightCyan') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -1019,12 +1339,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Foreground.BrightBlack') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -1046,12 +1382,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Foreground.Magenta') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -1070,12 +1422,28 @@ $script:TreeDepth++; if ($psStyle) { @(foreach ($styleProp in 'Foreground.BrightBlack') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -1146,6 +1514,38 @@ $script:TreeDepth++; + + VersionControl + + + + + + + if ($PSStyle) { + @(foreach ($versionPart in $_.ToString() -split "\.") { + @( + $PSStyle.Foreground.Cyan + $PSStyle.Bold + $versionPart + $PSStyle.Reset + ) -join '' + }) -join "$( + @( + $PSStyle.Foreground.Yellow + '.' + ) -join '' + )" + } else { + $_.ToString() + } + + + + + + + ${Posh_Indent} @@ -2544,12 +2944,28 @@ if ($Request -or $Host.UI.SupportsHTML) { if ($psStyle) { @(foreach ($styleProp in 'Foreground.Blue','Bold') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -2566,12 +2982,28 @@ if ($Request -or $Host.UI.SupportsHTML) { if ($psStyle) { @(foreach ($styleProp in 'Foreground.Cyan') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -2586,12 +3018,28 @@ if ($Request -or $Host.UI.SupportsHTML) { if ($psStyle) { @(foreach ($styleProp in 'Foreground.Cyan','Bold') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -2610,12 +3058,28 @@ if ($Request -or $Host.UI.SupportsHTML) { if ($psStyle) { @(foreach ($styleProp in 'Foreground.Blue','Italic') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -2635,12 +3099,28 @@ if ($Request -or $Host.UI.SupportsHTML) { if ($psStyle) { @(foreach ($styleProp in 'Foreground.Green') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -2661,12 +3141,28 @@ if ($Request -or $Host.UI.SupportsHTML) { if ($psStyle) { @(foreach ($styleProp in 'Foreground.Magenta') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -2690,12 +3186,28 @@ if ($Request -or $Host.UI.SupportsHTML) { if ($psStyle) { @(foreach ($styleProp in 'Foreground.Cyan') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -2774,12 +3286,28 @@ To see everything Posh can do: `$posh | Get-Member if ($psStyle) { @(foreach ($styleProp in 'Foreground.Cyan') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -2805,12 +3333,28 @@ To see everything Posh can do: `$posh | Get-Member if ($psStyle) { @(foreach ($styleProp in 'Foreground.Yellow','Italic') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -3075,12 +3619,28 @@ To see everything Posh can do: `$posh | Get-Member if ($psStyle) { @(foreach ($styleProp in 'Foreground.Cyan') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -3180,12 +3740,28 @@ To see everything Posh can do: `$posh | Get-Member if ($psStyle) { @(foreach ($styleProp in 'Italic') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -3204,12 +3780,28 @@ To see everything Posh can do: `$posh | Get-Member if ($psStyle) { @(foreach ($styleProp in 'Foreground.Cyan') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -3229,12 +3821,28 @@ To see everything Posh can do: `$posh | Get-Member if ($psStyle) { @(foreach ($styleProp in 'Foreground.Cyan') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -3267,12 +3875,28 @@ To see everything Posh can do: `$posh | Get-Member if ($psStyle) { @(foreach ($styleProp in 'Foreground.Green','Bold') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -3292,12 +3916,28 @@ To see everything Posh can do: `$posh | Get-Member if ($psStyle) { @(foreach ($styleProp in 'Foreground.Cyan') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -3323,12 +3963,28 @@ To see everything Posh can do: `$posh | Get-Member if ($psStyle) { @(foreach ($styleProp in 'Foreground.Yellow','Italic') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -3538,12 +4194,28 @@ To see everything Posh can do: `$posh | Get-Member if ($psStyle) { @(foreach ($styleProp in 'Foreground.Cyan') { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { - $psStyle.$styleProp - } + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + }) -ne '' -join '' } @@ -4176,7 +4848,7 @@ To see everything Posh can do: `$posh | Get-Member - System.Management.Automation.CommandInfoSystem.Management.Automation.AliasInfoSystem.Management.Automation.ApplicationInfoSystem.Management.Automation.CmdletInfoSystem.Management.Automation.ExternalScriptInfoSystem.Management.Automation.FilterInfoSystem.Management.Automation.FunctionInfo + System.Management.Automation.CommandInfo System.Management.Automation.CommandInfo System.Management.Automation.AliasInfo @@ -4257,10 +4929,24 @@ To see everything Posh can do: `$posh | Get-Member $CellColorValue = if ($psStyle) { @(foreach ($styleProp in $CellColorValue) { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { $psStyle.$styleProp } }) -join '' @@ -4322,10 +5008,24 @@ To see everything Posh can do: `$posh | Get-Member $CellColorValue = if ($psStyle) { @(foreach ($styleProp in $CellColorValue) { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { $psStyle.$styleProp } }) -join '' @@ -4356,10 +5056,24 @@ To see everything Posh can do: `$posh | Get-Member $CellColorValue = if ($psStyle) { @(foreach ($styleProp in $CellColorValue) { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { $psStyle.$styleProp } }) -join '' @@ -4511,10 +5225,24 @@ To see everything Posh can do: `$posh | Get-Member $CellColorValue = if ($psStyle) { @(foreach ($styleProp in $CellColorValue) { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { $psStyle.$styleProp } }) -join '' @@ -4678,7 +5406,7 @@ To see everything Posh can do: `$posh | Get-Member - System.Management.Automation.PSModuleInfoPosh.RichModuleInfo + System.Management.Automation.PSModuleInfo System.Management.Automation.PSModuleInfo Posh.RichModuleInfo @@ -4716,7 +5444,7 @@ To see everything Posh can do: `$posh | Get-Member - System.Management.Automation.PSModuleInfoPosh.RichModuleInfo + System.Management.Automation.PSModuleInfo System.Management.Automation.PSModuleInfo Posh.RichModuleInfo @@ -5055,10 +5783,24 @@ $module = $_ $CellColorValue = if ($psStyle) { @(foreach ($styleProp in $CellColorValue) { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { $psStyle.$styleProp } }) -join '' @@ -5074,10 +5816,24 @@ $module = $_ $CellColorValue = if ($psStyle) { @(foreach ($styleProp in $CellColorValue) { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { $psStyle.$styleProp } }) -join '' @@ -5095,10 +5851,24 @@ $module = $_ $CellColorValue = if ($psStyle) { @(foreach ($styleProp in $CellColorValue) { - if ($styleProp -match '\.') { - $styleGroup, $styleProp = $styleProp -split '\.' - $psStyle.$styleGroup.$styleProp - } else { + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { $psStyle.$styleProp } }) -join '' From 22d28dd9dca5d3cb94e34775e3dc318a6047b0a0 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sat, 26 Aug 2023 20:47:13 +0000 Subject: [PATCH 03/41] Adding VersionControl (Fixes #230) --- Posh.types.ps1xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Posh.types.ps1xml b/Posh.types.ps1xml index b81c732..0a3eb88 100644 --- a/Posh.types.ps1xml +++ b/Posh.types.ps1xml @@ -1,5 +1,5 @@ - + Posh From 4a78fd984a86a97b8e9969be96bb9d1933d498b0 Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sat, 26 Aug 2023 13:47:51 -0700 Subject: [PATCH 04/41] Adding Formatting for System.Version (Fixes #231) --- Formatting/System.Version.format.ps1 | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Formatting/System.Version.format.ps1 diff --git a/Formatting/System.Version.format.ps1 b/Formatting/System.Version.format.ps1 new file mode 100644 index 0000000..d5e0b3c --- /dev/null +++ b/Formatting/System.Version.format.ps1 @@ -0,0 +1,3 @@ +Write-FormatView -TypeName System.Version -Action { + Write-FormatViewExpression -ScriptBlock { $_ } -ControlName VersionControl +} \ No newline at end of file From 234d1cc7476964bb6dabc09014802d0dd9e8ff56 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sat, 26 Aug 2023 20:48:50 +0000 Subject: [PATCH 05/41] Adding Formatting for System.Version (Fixes #231) --- Posh.format.ps1xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Posh.format.ps1xml b/Posh.format.ps1xml index dfbaf62..580ddc0 100644 --- a/Posh.format.ps1xml +++ b/Posh.format.ps1xml @@ -5690,6 +5690,24 @@ $module = $_ + + System.Version + + System.Version + + + + + + + $_ + VersionControl + + + + + + Default From 9d99910a258e9d719c449a310c5733ffba329f4d Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sat, 26 Aug 2023 13:50:36 -0700 Subject: [PATCH 06/41] Using Posh format - Using VersionControl (Fixes #232) --- Formatting/Posh/Posh.format.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Formatting/Posh/Posh.format.ps1 b/Formatting/Posh/Posh.format.ps1 index 1ab7322..59de77b 100644 --- a/Formatting/Posh/Posh.format.ps1 +++ b/Formatting/Posh/Posh.format.ps1 @@ -2,7 +2,7 @@ Write-FormatView -TypeName Posh -Action { Write-FormatViewExpression -Style "Foreground.Blue", "Bold" -Property Name Write-FormatViewExpression -Style "Foreground.Cyan" -Text ' @ ' - Write-FormatViewExpression -Style "Foreground.Cyan", "Bold" -Property Version + Write-FormatViewExpression -Property Version -ControlName VersionControl Write-FormatViewExpression -Newline Write-FormatViewExpression -Newline From 3f067fc7b406ec17f40a6090365e731193636d59 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sat, 26 Aug 2023 20:51:33 +0000 Subject: [PATCH 07/41] Using Posh format - Using VersionControl (Fixes #232) --- Posh.format.ps1xml | 36 +----------------------------------- 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/Posh.format.ps1xml b/Posh.format.ps1xml index 580ddc0..b276d50 100644 --- a/Posh.format.ps1xml +++ b/Posh.format.ps1xml @@ -3015,43 +3015,9 @@ if ($Request -or $Host.UI.SupportsHTML) { } - - if ($psStyle) { - @(foreach ($styleProp in 'Foreground.Cyan','Bold') { - - if ($styleProp -match '^\$') { - $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) - } - elseif ($styleProp -match '\.') { - $targetObject = $psStyle - foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { - if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or - $targetObject -is [Collections.IDictionary]) { - $targetObject = $targetObject[$dotProperty] - } else { - $targetObject = $targetObject.$dotProperty - } - } - if ($targetObject) { - $targetObject - } - } - else { - $psStyle.$styleProp - } - - }) -ne '' -join '' -} - Version - - - - if ($PSStyle) { - $PSStyle.Reset - } - + VersionControl From 6296c9cfd214f964161b3958976193f807db429c Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sat, 26 Aug 2023 13:54:18 -0700 Subject: [PATCH 08/41] Updating Version Control (switching dots to blue) (re #230) --- Formatting/VersionControl.format.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Formatting/VersionControl.format.ps1 b/Formatting/VersionControl.format.ps1 index d9905c1..1f05162 100644 --- a/Formatting/VersionControl.format.ps1 +++ b/Formatting/VersionControl.format.ps1 @@ -10,8 +10,8 @@ Write-FormatView -TypeName n/a -Name VersionControl -Action { ) -join '' }) -join "$( @( - $PSStyle.Foreground.Yellow - '.' + $PSStyle.Foreground.Blue + '.' ) -join '' )" } else { From 1841a0d2f1610958bf02771f28d379f3e08e2e9a Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sat, 26 Aug 2023 20:55:18 +0000 Subject: [PATCH 09/41] Updating Version Control (switching dots to blue) (re #230) --- Posh.format.ps1xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Posh.format.ps1xml b/Posh.format.ps1xml index b276d50..9e70b1e 100644 --- a/Posh.format.ps1xml +++ b/Posh.format.ps1xml @@ -1532,8 +1532,8 @@ $script:TreeDepth++; ) -join '' }) -join "$( @( - $PSStyle.Foreground.Yellow - '.' + $PSStyle.Foreground.Blue + '.' ) -join '' )" } else { From af09155176fbeba7a58e6f4e8f8f4a1a802e3c7e Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sat, 26 Aug 2023 14:44:22 -0700 Subject: [PATCH 10/41] Adding TypeInterfaceControl (Fixes #220) --- Formatting/Reflection/TypeInterfaceControl.format.ps1 | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 Formatting/Reflection/TypeInterfaceControl.format.ps1 diff --git a/Formatting/Reflection/TypeInterfaceControl.format.ps1 b/Formatting/Reflection/TypeInterfaceControl.format.ps1 new file mode 100644 index 0000000..5c2120e --- /dev/null +++ b/Formatting/Reflection/TypeInterfaceControl.format.ps1 @@ -0,0 +1,5 @@ +Write-FormatView -Action { + Write-FormatViewExpression -Newline + Write-FormatViewExpression -ScriptBlock { ' *' } + Write-FormatViewExpression -ControlName TypeNameControl -ScriptBlock {$_ } -Style 'Foreground.Cyan', 'Bold' +} -TypeName n/a -Name TypeInterfaceControl -AsControl From 882950e1f2284a6eeff71b308a8a5df89f578462 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sat, 26 Aug 2023 21:45:17 +0000 Subject: [PATCH 11/41] Adding TypeInterfaceControl (Fixes #220) --- Posh.format.ps1xml | 54 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/Posh.format.ps1xml b/Posh.format.ps1xml index 9e70b1e..ba360e1 100644 --- a/Posh.format.ps1xml +++ b/Posh.format.ps1xml @@ -403,6 +403,60 @@ $script:TreeDepth++; + + TypeInterfaceControl + + + + + + + ' *' + + + if ($psStyle) { + @(foreach ($styleProp in 'Foreground.Cyan','Bold') { + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + + }) -ne '' -join '' +} + + + $_ + TypeNameControl + + + + if ($PSStyle) { + $PSStyle.Reset + } + + + + + + + TypeMemberControl From 253a30c1a0f24236834d095e3b5bf3874d782fde Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sat, 26 Aug 2023 14:45:44 -0700 Subject: [PATCH 12/41] Adding TypeConstructorsControl (Fixes #222) --- .../Reflection/TypeConstructorsControl.format.ps1 | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Formatting/Reflection/TypeConstructorsControl.format.ps1 diff --git a/Formatting/Reflection/TypeConstructorsControl.format.ps1 b/Formatting/Reflection/TypeConstructorsControl.format.ps1 new file mode 100644 index 0000000..4699d2b --- /dev/null +++ b/Formatting/Reflection/TypeConstructorsControl.format.ps1 @@ -0,0 +1,13 @@ +$getConstructors = { + if ($_ -is [Type]) { + $_.GetConstructors('Instance,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetConstructors($_.BindingFlags) + } +} +Write-FormatControl -Name TypeConstructorsControl -Action { + Write-FormatViewExpression -If $getConstructors -ScriptBlock { + [Environment]::NewLine + ('#' * 3) + ' Constructors:' + } + Write-FormatViewExpression -If $getConstructors -ScriptBlock $getConstructors -Enumerate -ControlName TypeMethodControl +} \ No newline at end of file From 877d67e83fcfa785feef427d8b3a015f63dc53cc Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sat, 26 Aug 2023 21:46:33 +0000 Subject: [PATCH 13/41] Adding TypeConstructorsControl (Fixes #222) --- Posh.format.ps1xml | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/Posh.format.ps1xml b/Posh.format.ps1xml index ba360e1..4024e35 100644 --- a/Posh.format.ps1xml +++ b/Posh.format.ps1xml @@ -230,6 +230,51 @@ $script:TreeDepth++; + + TypeConstructorsControl + + + + + + + + if ($_ -is [Type]) { + $_.GetConstructors('Instance,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetConstructors($_.BindingFlags) + } + + + + [Environment]::NewLine + ('#' * 3) + ' Constructors:' + + + + + + if ($_ -is [Type]) { + $_.GetConstructors('Instance,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetConstructors($_.BindingFlags) + } + + + + if ($_ -is [Type]) { + $_.GetConstructors('Instance,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetConstructors($_.BindingFlags) + } + + + TypeMethodControl + + + + + + TypeEventControl From 7101c7d6a25c780003a2e03b000121d28b8dd800 Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sat, 26 Aug 2023 14:48:21 -0700 Subject: [PATCH 14/41] TypeMethodParameterControl - Improving Empty Methods (Fixes #234) --- Formatting/Reflection/TypeMethodParameterControl.format.ps1 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Formatting/Reflection/TypeMethodParameterControl.format.ps1 b/Formatting/Reflection/TypeMethodParameterControl.format.ps1 index 0930a99..e700f18 100644 --- a/Formatting/Reflection/TypeMethodParameterControl.format.ps1 +++ b/Formatting/Reflection/TypeMethodParameterControl.format.ps1 @@ -1,6 +1,5 @@ Write-FormatView -Action { Write-FormatViewExpression -If { $_.N -gt 0} -ScriptBlock { ', ' } - Write-FormatViewExpression -Property ParameterType -ControlName TypeNameControl -Style 'Formatting.Verbose' - Write-FormatViewExpression -ScriptBlock { '$' + $_.Name } -Style 'Formatting.Warning' - Write-FormatViewExpression -ScriptBlock { ' ' } + Write-FormatViewExpression -Property ParameterType -ControlName TypeNameControl -Style 'Foreground.Cyan','Bold' + Write-FormatViewExpression -ScriptBlock { '$' + $_.Name + ' ' } -Style 'Formatting.Warning' -If {$_.Name } } -TypeName TypeMethodParameterControl -Name TypeMethodParameterControl -AsControl From e25225a12f44ba58f572402724cef89bc317ccc5 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sat, 26 Aug 2023 21:49:09 +0000 Subject: [PATCH 15/41] TypeMethodParameterControl - Improving Empty Methods (Fixes #234) --- Posh.format.ps1xml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Posh.format.ps1xml b/Posh.format.ps1xml index 4024e35..ad96c44 100644 --- a/Posh.format.ps1xml +++ b/Posh.format.ps1xml @@ -748,7 +748,7 @@ $script:TreeDepth++; if ($psStyle) { - @(foreach ($styleProp in 'Formatting.Verbose') { + @(foreach ($styleProp in 'Foreground.Cyan','Bold') { if ($styleProp -match '^\$') { $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) @@ -786,6 +786,9 @@ $script:TreeDepth++; + + $_.Name + if ($psStyle) { @(foreach ($styleProp in 'Formatting.Warning') { @@ -814,18 +817,21 @@ $script:TreeDepth++; } - '$' + $_.Name + + $_.Name + + '$' + $_.Name + ' ' + + $_.Name + if ($PSStyle) { $PSStyle.Reset } - - ' ' - From 6281e799ec85d353aa4da89c8af81cac4899efda Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sat, 26 Aug 2023 14:49:59 -0700 Subject: [PATCH 16/41] Adding TypeEvents Control (Fixes #225) --- Formatting/Reflection/TypeEventsControl.format.ps1 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 Formatting/Reflection/TypeEventsControl.format.ps1 diff --git a/Formatting/Reflection/TypeEventsControl.format.ps1 b/Formatting/Reflection/TypeEventsControl.format.ps1 new file mode 100644 index 0000000..1d721c1 --- /dev/null +++ b/Formatting/Reflection/TypeEventsControl.format.ps1 @@ -0,0 +1,14 @@ +$getEvents = { + if ($_ -is [Type]) { + $_.GetEvents('Instance,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetEvents($_.BindingFlags) + } +} + +Write-FormatControl -Name TypeEventsControl -Action { + Write-FormatViewExpression -If $getEvents -ScriptBlock { + [Environment]::NewLine + ('#' * 3) + ' Events:' + } + Write-FormatViewExpression -If $getEvents -ScriptBlock $getEvents -Enumerate -ControlName TypeEventControl +} \ No newline at end of file From 15a584b1fd847f28c58b1eebc039c6da0e016412 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sat, 26 Aug 2023 21:50:56 +0000 Subject: [PATCH 17/41] Adding TypeEvents Control (Fixes #225) --- Posh.format.ps1xml | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/Posh.format.ps1xml b/Posh.format.ps1xml index ad96c44..e31d5a8 100644 --- a/Posh.format.ps1xml +++ b/Posh.format.ps1xml @@ -351,6 +351,51 @@ $script:TreeDepth++; + + TypeEventsControl + + + + + + + + if ($_ -is [Type]) { + $_.GetEvents('Instance,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetEvents($_.BindingFlags) + } + + + + [Environment]::NewLine + ('#' * 3) + ' Events:' + + + + + + if ($_ -is [Type]) { + $_.GetEvents('Instance,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetEvents($_.BindingFlags) + } + + + + if ($_ -is [Type]) { + $_.GetEvents('Instance,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetEvents($_.BindingFlags) + } + + + TypeEventControl + + + + + + TypeFieldControl From 59787e9548699816408f37c2860c8ee6e947d035 Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sat, 26 Aug 2023 14:52:05 -0700 Subject: [PATCH 18/41] Adding TypeProperties Control (Fixes #224) --- .../TypePropertiesControl.format.ps1 | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Formatting/Reflection/TypePropertiesControl.format.ps1 diff --git a/Formatting/Reflection/TypePropertiesControl.format.ps1 b/Formatting/Reflection/TypePropertiesControl.format.ps1 new file mode 100644 index 0000000..3d1731e --- /dev/null +++ b/Formatting/Reflection/TypePropertiesControl.format.ps1 @@ -0,0 +1,26 @@ +$getStaticProperties = { + if ($_ -is [Type]) { + $_.GetProperties('Static,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetProperties("Static,$($_.BindingFlags)") + } +} + +$getInstanceProperties = { + if ($_ -is [Type]) { + $_.GetProperties('Instance,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetProperties("Instance,$($_.BindingFlags)") + } +} + +Write-FormatControl -Name TypePropertiesControl -Action { + Write-FormatViewExpression -If $getStaticProperties -ScriptBlock { + [Environment]::NewLine + ('#' * 3) + ' Static Properties:' + } + Write-FormatViewExpression -If $getStaticProperties -ScriptBlock $getStaticProperties -Enumerate -ControlName TypePropertyControl + Write-FormatViewExpression -If $getInstanceProperties -ScriptBlock { + [Environment]::NewLine + ('#' * 3) + ' Properties:' + } + Write-FormatViewExpression -If $getInstanceProperties -ScriptBlock $getInstanceProperties -Enumerate -ControlName TypePropertyControl +} \ No newline at end of file From c16c4797b1748945fef276f56eb02ad673f6e5c9 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sat, 26 Aug 2023 21:53:06 +0000 Subject: [PATCH 19/41] Adding TypeProperties Control (Fixes #224) --- Posh.format.ps1xml | 79 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/Posh.format.ps1xml b/Posh.format.ps1xml index e31d5a8..51a1d4e 100644 --- a/Posh.format.ps1xml +++ b/Posh.format.ps1xml @@ -916,6 +916,85 @@ $script:TreeDepth++; + + TypePropertiesControl + + + + + + + + if ($_ -is [Type]) { + $_.GetProperties('Static,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetProperties("Static,$($_.BindingFlags)") + } + + + + [Environment]::NewLine + ('#' * 3) + ' Static Properties:' + + + + + + if ($_ -is [Type]) { + $_.GetProperties('Static,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetProperties("Static,$($_.BindingFlags)") + } + + + + if ($_ -is [Type]) { + $_.GetProperties('Static,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetProperties("Static,$($_.BindingFlags)") + } + + + TypePropertyControl + + + + + if ($_ -is [Type]) { + $_.GetProperties('Instance,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetProperties("Instance,$($_.BindingFlags)") + } + + + + [Environment]::NewLine + ('#' * 3) + ' Properties:' + + + + + + if ($_ -is [Type]) { + $_.GetProperties('Instance,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetProperties("Instance,$($_.BindingFlags)") + } + + + + if ($_ -is [Type]) { + $_.GetProperties('Instance,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetProperties("Instance,$($_.BindingFlags)") + } + + + TypePropertyControl + + + + + + TypePropertyControl From 934c5f747b078e36297025b8cecab7cf11a34d85 Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sat, 26 Aug 2023 14:55:02 -0700 Subject: [PATCH 20/41] TypeMethodControl - Highlighting private methods (Fixes #235) --- .../Reflection/TypeMethodControl.format.ps1 | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/Formatting/Reflection/TypeMethodControl.format.ps1 b/Formatting/Reflection/TypeMethodControl.format.ps1 index 302c5cf..cea39cc 100644 --- a/Formatting/Reflection/TypeMethodControl.format.ps1 +++ b/Formatting/Reflection/TypeMethodControl.format.ps1 @@ -1,10 +1,39 @@ Write-FormatView -Action { Write-FormatViewExpression -If { -not $script:DisplayingMember } -ScriptBlock { [Environment]::NewLine } + Write-FormatViewExpression -ScriptBlock { ' *' } + Write-FormatViewExpression -If { $_.IsStatic } -ScriptBlock { ' static ' } + Write-FormatViewExpression -If {$_.IsConstructor } -ScriptBlock { $_.DeclaringType } -ControlName TypeNameControl -Style 'Foreground.Cyan','Bold' Write-FormatViewExpression -If { -not $_.IsConstructor -and $_.ReturnType } -ScriptBlock { $_.ReturnType } -ControlName TypeNameControl -Style 'Foreground.Cyan','Bold' - Write-FormatViewExpression -If { -not $_.IsConstructor } -ScriptBlock { ' ' + $_.Name } -Style 'Formatting.Warning' + + Write-FormatViewExpression -ScriptBlock { + @(if (-not $_.IsConstructor) { + ' ' + if ($_.IsPublic) { + if ($PSStyle) { + $PSStyle.Formatting.Warning + } + } + elseif ($_.IsPrivate) { + if ($PSStyle) { + $PSStyle.Formatting.Error + } + } + else { + if ($PSStyle) { + $PSStyle.Formatting.Warning + } + } + + $_.Name + if ($PSStyle) { + $PSStyle.Reset + } + }) -join '' + } + Write-FormatViewExpression -ScriptBlock { ' (' } Write-FormatViewExpression -ScriptBlock { $MethodParameters = @($_.GetParameters()) From f33422c3427cfe7b791c630a613bd93ad3640f71 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sat, 26 Aug 2023 21:55:55 +0000 Subject: [PATCH 21/41] TypeMethodControl - Highlighting private methods (Fixes #235) --- Posh.format.ps1xml | 64 ++++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 42 deletions(-) diff --git a/Posh.format.ps1xml b/Posh.format.ps1xml index 51a1d4e..b3d037f 100644 --- a/Posh.format.ps1xml +++ b/Posh.format.ps1xml @@ -709,51 +709,31 @@ $script:TreeDepth++; - - -not $_.IsConstructor - - if ($psStyle) { - @(foreach ($styleProp in 'Formatting.Warning') { - - if ($styleProp -match '^\$') { - $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) - } - elseif ($styleProp -match '\.') { - $targetObject = $psStyle - foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { - if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or - $targetObject -is [Collections.IDictionary]) { - $targetObject = $targetObject[$dotProperty] - } else { - $targetObject = $targetObject.$dotProperty + + @(if (-not $_.IsConstructor) { + ' ' + if ($_.IsPublic) { + if ($PSStyle) { + $PSStyle.Formatting.Warning } } - if ($targetObject) { - $targetObject + elseif ($_.IsPrivate) { + if ($PSStyle) { + $PSStyle.Formatting.Error + } } - } - else { - $psStyle.$styleProp - } - - }) -ne '' -join '' -} - - - - -not $_.IsConstructor - - ' ' + $_.Name - - - - -not $_.IsConstructor - - - if ($PSStyle) { - $PSStyle.Reset - } - + else { + if ($PSStyle) { + $PSStyle.Formatting.Warning + } + } + + $_.Name + if ($PSStyle) { + $PSStyle.Reset + } + }) -join '' + ' (' From 9a47a9facd583872fa96af91ecb51d200268a71e Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sat, 26 Aug 2023 14:57:04 -0700 Subject: [PATCH 22/41] Adding TypeMethodsControl (Fixes #223) --- .../Reflection/TypeMethodsControl.format.ps1 | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Formatting/Reflection/TypeMethodsControl.format.ps1 diff --git a/Formatting/Reflection/TypeMethodsControl.format.ps1 b/Formatting/Reflection/TypeMethodsControl.format.ps1 new file mode 100644 index 0000000..aeb8e41 --- /dev/null +++ b/Formatting/Reflection/TypeMethodsControl.format.ps1 @@ -0,0 +1,26 @@ +$getStaticMethods = { + if ($_ -is [Type]) { + $_.GetMethods('Static,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetMethods("Static,$($_.BindingFlags)") + } +} + +$getInstanceMethods = { + if ($_ -is [Type]) { + $_.GetMethods('Instance,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetMethods("Instance,$($_.BindingFlags)") + } +} + +Write-FormatControl -Name TypeMethodsControl -Action { + Write-FormatViewExpression -If $getStaticMethods -ScriptBlock { + [Environment]::NewLine + ('#' * 3) + ' Static Methods:' + } + Write-FormatViewExpression -If $getStaticMethods -ScriptBlock $getStaticMethods -Enumerate -ControlName TypeMethodControl + Write-FormatViewExpression -If $getInstanceMethods -ScriptBlock { + [Environment]::NewLine + ('#' * 3) + ' Methods:' + } + Write-FormatViewExpression -If $getInstanceMethods -ScriptBlock $getInstanceMethods -Enumerate -ControlName TypeMethodControl +} \ No newline at end of file From 1605f13b17428e20a7a8c2beb188a116ef3181a8 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sat, 26 Aug 2023 21:57:58 +0000 Subject: [PATCH 23/41] Adding TypeMethodsControl (Fixes #223) --- Posh.format.ps1xml | 79 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/Posh.format.ps1xml b/Posh.format.ps1xml index b3d037f..7f138c7 100644 --- a/Posh.format.ps1xml +++ b/Posh.format.ps1xml @@ -862,6 +862,85 @@ $script:TreeDepth++; + + TypeMethodsControl + + + + + + + + if ($_ -is [Type]) { + $_.GetMethods('Static,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetMethods("Static,$($_.BindingFlags)") + } + + + + [Environment]::NewLine + ('#' * 3) + ' Static Methods:' + + + + + + if ($_ -is [Type]) { + $_.GetMethods('Static,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetMethods("Static,$($_.BindingFlags)") + } + + + + if ($_ -is [Type]) { + $_.GetMethods('Static,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetMethods("Static,$($_.BindingFlags)") + } + + + TypeMethodControl + + + + + if ($_ -is [Type]) { + $_.GetMethods('Instance,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetMethods("Instance,$($_.BindingFlags)") + } + + + + [Environment]::NewLine + ('#' * 3) + ' Methods:' + + + + + + if ($_ -is [Type]) { + $_.GetMethods('Instance,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetMethods("Instance,$($_.BindingFlags)") + } + + + + if ($_ -is [Type]) { + $_.GetMethods('Instance,Public') + } elseif ($_.Type -and $_.BindingFlags) { + $_.Type.GetMethods("Instance,$($_.BindingFlags)") + } + + + TypeMethodControl + + + + + + TypeNameControl From 0276af46bda346b71682e4a96f314eb1061bca15 Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sat, 26 Aug 2023 16:54:10 -0700 Subject: [PATCH 24/41] Updating Reflection Formatting Adding Public/Private/Interfaces, shortening view names (Fixes #217, Fixes #236) --- Formatting/Reflection/System.Type.format.ps1 | 131 ++++++++++++------- 1 file changed, 81 insertions(+), 50 deletions(-) diff --git a/Formatting/Reflection/System.Type.format.ps1 b/Formatting/Reflection/System.Type.format.ps1 index c7e3160..5c719de 100644 --- a/Formatting/Reflection/System.Type.format.ps1 +++ b/Formatting/Reflection/System.Type.format.ps1 @@ -1,64 +1,95 @@ Write-FormatView -TypeName System.Type -Property FullName, BaseType, IsPublic, IsSerializable -AutoSize -Write-FormatView -TypeName System.Type -Action { +Write-FormatView -TypeName n/a -AsControl -Name TypeInheritanceControl -Action { Write-FormatViewExpression -Newline - Write-FormatViewExpression -ScriptBlock { '-' * ($Host.UI.RawUI.BufferSize.Width - 1) } - Write-FormatViewExpression -ScriptBlock { ' ' * 1 } - Write-FormatViewExpression -ForegroundColor 'Verbose' -ScriptBlock { $_ } -ControlName TypeNameControl + Write-FormatViewExpression -ScriptBlock { ' ' * 1 } + Write-FormatViewExpression -Style 'Formatting.Verbose' -ScriptBlock { $_ } -ControlName TypeNameControl Write-FormatViewExpression -ScriptBlock { ' ' * 1 } Write-FormatViewExpression -If { $_.BaseType -and -not $_.IsValueType } -ScriptBlock { ':' } Write-FormatViewExpression -If { $_.BaseType -and -not $_.IsValueType -and $_.BaseType -ne [Object] } -Property BaseType -ControlName TypeBase - Write-FormatViewExpression -If { $_.GetInterfaces() } -ScriptBlock { $_.GetInterfaces() | Sort-Object Name} -Enumerate -ControlName TypeBase -} -GroupLabel 'Type Summary' -GroupByScript { '| Format-Custom -View System.Type.Full for more'} -Name System.Type.Summary - -Write-FormatView -TypeName System.Type -Action { Write-FormatViewExpression -Newline - Write-FormatViewExpression -ScriptBlock { '-' * ($Host.UI.RawUI.BufferSize.Width - 1) } - Write-FormatViewExpression -ScriptBlock { ' ' * 1 } - Write-FormatViewExpression -ForegroundColor 'Verbose' -ScriptBlock { $_ } -ControlName TypeNameControl - Write-FormatViewExpression -ScriptBlock { ' ' * 1 } - Write-FormatViewExpression -If { $_.BaseType -and -not $_.IsValueType -and $_.BaseType -ne [Object] } -ScriptBlock { - ':' - } - Write-FormatViewExpression -If { $_.BaseType -and -not $_.IsValueType -and $_.BaseType -ne [Object] } -Property BaseType -ControlName TypeBase - Write-FormatViewExpression -If { $_.GetInterfaces() } -ScriptBlock { $_.GetInterfaces() | Sort-Object Name} -Enumerate -ControlName TypeBase + Write-FormatViewExpression -ScriptBlock { '=' * ($Host.UI.RawUI.BufferSize.Width - 1) } +} - Write-FormatViewExpression -If { $_.GetConstructors('Instance,Public') } -ScriptBlock { - [Environment]::NewLine + ('#' * 3) + ' Constructors:' - } - Write-FormatViewExpression -If { $_.GetConstructors('Instance,Public') } -ScriptBlock { - $_.GetConstructors('Instance,Public') - } -Enumerate -ControlName TypeMethodControl - Write-FormatViewExpression -If { $_.GetEvents('Instance,Public') } -ScriptBlock { - [Environment]::NewLine + ('#' * 3) + ' Events:' - } - Write-FormatViewExpression -If { $_.GetEvents('Instance,Public') } -ScriptBlock { - $_.GetEvents('Instance,Public') | Sort-Object Name - } -Enumerate -ControlName TypeEventControl - Write-FormatViewExpression -If { $_.GetProperties('Static,Public') } -ScriptBlock { - [Environment]::NewLine + ('#' * 3) + ' Static Properties:' + +$TypeGrouping = [Ordered]@{ + GroupByScript = { + " + ... | Format-Custom -View Full # To show public and private members + ... | Format-Custom -View Public # To show public members + ... | Format-Custom -View Private # To show private members + " } - Write-FormatViewExpression -If { $_.GetProperties('Static,Public')} -ScriptBlock { - $_.GetProperties('Static,Public') | Sort-Object Name - } -Enumerate -ControlName TypePropertyControl - Write-FormatViewExpression -If { $_.GetProperties('Instance,Public') } -ScriptBlock { - [Environment]::NewLine + ('#' * 3) + ' Properties:' +} + +Write-FormatView -TypeName System.Type -Action { + Write-FormatViewExpression -ControlName TypeInheritanceControl -ScriptBlock { $_ } +} -GroupLabel 'Type Inheritance' @TypeGrouping -Name Inheritance + +Write-FormatView -TypeName System.Type -Action { + Write-FormatViewExpression -ControlName TypeInheritanceControl -ScriptBlock { $_ } + Write-FormatViewExpression -If { $_.GetInterfaces() } -ScriptBlock { $_.GetInterfaces() | Sort-Object Name} -Enumerate -ControlName TypeInterfaceControl +} -GroupLabel 'Type Inheritance' @TypeGrouping -Name Interfaces + +foreach ($viewName in 'Public','Private','Full') { + $bindingFlags = + switch ($viewName) { + Public { + 'Public' + } + Private { + 'NonPublic' + } + Full { + 'Public,NonPublic' + } + } + $assignView = [ScriptBlock]::Create(" +`$_ | + Add-Member NoteProperty '.View' '$viewName' -PassThru -Force | + Add-Member NoteProperty '.BindingFlags' ([Reflection.BindingFlags]'$bindingFlags') -Force +") + +Write-FormatView -TypeName System.Type -Action { + Write-FormatViewExpression -If $assignView -ScriptBlock { "" } + Write-FormatViewExpression -If { + $_.GetInterfaces() + } -ScriptBlock { + $_.GetInterfaces() | Sort-Object Name + } -Enumerate -ControlName TypeInterfaceControl + Write-FormatViewExpression -ControlName TypeInheritanceControl -ScriptBlock { $_ } + Write-FormatViewExpression -ControlName TypeConstructorsControl -ScriptBlock { + if ($_.'.BindingFlags') { + @{Type=$_;BindingFlags="Instance,$($_.'.BindingFlags')"} + } else { + $_ + } } - Write-FormatViewExpression -If { $_.GetProperties('Instance,Public')} -ScriptBlock { - $_.GetProperties('Instance,Public') | Sort-Object Name - } -Enumerate -ControlName TypePropertyControl - Write-FormatViewExpression -If { $_.GetMethods('Static,Public') } -ScriptBlock { - [Environment]::NewLine + ('#' * 3) + ' Static Methods:' + + Write-FormatViewExpression -ControlName TypeEventsControl -ScriptBlock { + if ($_.'.BindingFlags') { + @{Type=$_;BindingFlags="Instance,$($_.'.BindingFlags')"} + } else { + $_ + } } - Write-FormatViewExpression -If { $_.GetMethods('Static,Public') } -ScriptBlock { - $_.GetMethods('Static,Public') | Sort-Object Name | Where-Object { -not $_.IsSpecialName } - } -Enumerate -ControlName TypeMethodControl - Write-FormatViewExpression -If { $_.GetMethods('Instance,Public') } -ScriptBlock { - [Environment]::NewLine + ('#' * 3) + ' Methods:' + + Write-FormatViewExpression -ControlName TypePropertiesControl -ScriptBlock { + if ($_.'.BindingFlags') { + @{Type=$_;BindingFlags="$($_.'.BindingFlags')"} + } else { + $_ + } } - Write-FormatViewExpression -If { $_.GetMethods('Instance,Public') } -ScriptBlock { - $_.GetMethods('Instance,Public') | Sort-Object Name | Where-Object { -not $_.IsSpecialName } - } -Enumerate -ControlName TypeMethodControl -} -Name System.Type.Full \ No newline at end of file + + Write-FormatViewExpression -ControlName TypeMethodsControl -ScriptBlock { + if ($_.'.BindingFlags') { + @{Type=$_;BindingFlags="$($_.'.BindingFlags')"} + } else { + $_ + } + } +} -Name "$ViewName" -GroupLabel "Type $ViewName" @TypeGrouping +} From 2b4bcc5622148d6018ab1ddce2d9916cb0ecd7ee Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sat, 26 Aug 2023 23:55:11 +0000 Subject: [PATCH 25/41] Updating Reflection Formatting Adding Public/Private/Interfaces, shortening view names (Fixes #217, Fixes #236) --- Posh.format.ps1xml | 2090 +++++++++++++++++++++++--------------------- 1 file changed, 1110 insertions(+), 980 deletions(-) diff --git a/Posh.format.ps1xml b/Posh.format.ps1xml index 7f138c7..b6f0fc0 100644 --- a/Posh.format.ps1xml +++ b/Posh.format.ps1xml @@ -176,6 +176,82 @@ $script:TreeDepth++; + + TypeInheritanceControl + + + + + + + ' ' * 1 + + + if ($psStyle) { + @(foreach ($styleProp in 'Formatting.Verbose') { + + if ($styleProp -match '^\$') { + $ExecutionContext.SessionState.InvokeCommand.InvokeScript($styleProp) + } + elseif ($styleProp -match '\.') { + $targetObject = $psStyle + foreach ($dotProperty in $styleProp -split '(?<!\.)\.') { + if ($targetObject.Item -is [Management.Automation.PSMethodInfo] -or + $targetObject -is [Collections.IDictionary]) { + $targetObject = $targetObject[$dotProperty] + } else { + $targetObject = $targetObject.$dotProperty + } + } + if ($targetObject) { + $targetObject + } + } + else { + $psStyle.$styleProp + } + + }) -ne '' -join '' +} + + + $_ + TypeNameControl + + + + if ($PSStyle) { + $PSStyle.Reset + } + + + + ' ' * 1 + + + + $_.BaseType -and -not $_.IsValueType + + + ':' + + + + + $_.BaseType -and -not $_.IsValueType -and $_.BaseType -ne [Object] + + BaseType + TypeBase + + + + '=' * ($Host.UI.RawUI.BufferSize.Width - 1) + + + + + + TypeBase @@ -2077,7 +2153,7 @@ if ($Request -or $Host.UI.SupportsHTML) { - ${Posh_Format-RichText} + ${Posh_Format-Markdown} @@ -2085,411 +2161,418 @@ if ($Request -or $Host.UI.SupportsHTML) { <# - .Synopsis - Formats the text color of output - .Description - Formats the text color of output - - * ForegroundColor - * BackgroundColor - * Bold - * Underline - .Notes - Stylized Output works in two contexts at present: - * Rich consoles (Windows Terminal, PowerShell.exe, Pwsh.exe) (when $host.UI.SupportsVirtualTerminal) - * Web pages (Based off the presence of a $Request variable, or when $host.UI.SupportsHTML (you must add this property to $host.UI)) + .SYNOPSIS + Formats an object as Markdown + .DESCRIPTION + Formats an object as Markdown, with many options to work with + .EXAMPLE + Format-Markdown -ScriptBlock { + Get-Process + } + .EXAMPLE + 1..6 | Format-Markdown -HeadingSize { $_ } #> [Management.Automation.Cmdlet("Format","Object")] - [ValidateScript({ - $canUseANSI = $host.UI.SupportsVirtualTerminal - $canUseHTML = $Request -or $host.UI.SupportsHTML -or $OutputMode -eq 'HTML' - if (-not ($canUseANSI -or $canUseHTML)) { return $false} - return $true - })] - [OutputType([string])] - param( - # The input object - [Parameter(ValueFromPipeline)] + [ValidateScript({return $true})] + param( + [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)] [PSObject] $InputObject, - # The foreground color - [string]$ForegroundColor, + # If set, will treat the -InputObject as a paragraph. + # This is the default for strings, booleans, numbers, and other primitive types. + [Parameter(ValueFromPipelineByPropertyName)] + [switch] + $MarkdownParagraph, - # The background color - [string]$BackgroundColor, + # If set, will generate a markdown table. + [Parameter(ValueFromPipelineByPropertyName)] + [switch] + $MarkdownTable, - # If set, will render as bold - [switch]$Bold, + # If provided, will align columnns in a markdown table. + [Parameter(ValueFromPipelineByPropertyName)] + [ValidateSet("Left","Right","Center", "")] + [string[]] + $MarkdownTableAlignment, - # If set, will render as italic. - [Alias('Italics')] - [switch]$Italic, + # An array of properties. Providing this implies -MarkdownTable + [Parameter(ValueFromPipelineByPropertyName)] + [PSObject[]] + $Property, - # If set, will render as faint - [switch]$Faint, + # A heading. + # If provided without -HeadingSize, -HeadingSize will default to 2. + # If provided with -InputObject, -Heading will take priority. + [Parameter(ValueFromPipelineByPropertyName)] + [string] + $Heading, - # If set, will render as hidden text. - [switch]$Hide, + # The heading size (1-6) + # If provided without -Heading, the -InputObject will be considered to be a heading. + [Parameter(ValueFromPipelineByPropertyName)] + [ValidateRange(1,6)] + [int] + $HeadingSize, - # If set, will render as blinking (not supported in all terminals or HTML) - [switch]$Blink, + # If set, will create a link. The -InputObject will be used as the link content + [Parameter(ValueFromPipelineByPropertyName)] + [Alias('Hyperlink', 'Href')] + [string] + $Link, - # If set, will render as strikethru - [Alias('Strikethrough', 'Crossout')] - [switch]$Strikethru, + # If set, will create an image link. The -Inputobject will be used as the link content. + [Parameter(ValueFromPipelineByPropertyName)] + [string] + $ImageLink, - # If set, will underline text - [switch]$Underline, + # If set, will generate a bullet point list. + [Parameter(ValueFromPipelineByPropertyName)] + [Alias('BulletpointList')] + [switch] + $BulletPoint, + + # If set, bullet or numbered list items will have a checkbox. + # Each piped -InputObject will be an additional list item. + [Parameter(ValueFromPipelineByPropertyName)] + [switch] + $Checkbox, - # If set, will double underline text. - [switch]$DoubleUnderline, + # If set, bullet or numbered list items will be checked. + [Parameter(ValueFromPipelineByPropertyName)] + [switch] + $Checked, - # If set, will invert text - [switch]$Invert, + # If set, will generate a numbered list. + # Each piped -InputObject will be an additional list item. + [Parameter(ValueFromPipelineByPropertyName)] + [switch] + $NumberedList, - # If provided, will create a hyperlink to a given uri - [Alias('Hyperlink', 'Href')] - [uri] - $Link, + # If set, will generate a block quote. + # Each line of the -InputObject will be block quoted. + [Parameter(ValueFromPipelineByPropertyName)] + [switch] + $BlockQuote, - # If set, will not clear formatting - [switch]$NoClear, + # If set, will generate a block quote of a particular depth. + # Each line of the -InputObject will be block quoted. + [Parameter(ValueFromPipelineByPropertyName)] + [ValidateRange(1,3)] + [int] + $BlockQuoteDepth, + + # If provided, will create a markdown numbered list with this particular item as the number. + [Parameter(ValueFromPipelineByPropertyName)] + [int] + $Number, - # The alignment. Defaulting to Left. - # Setting an alignment will pad the remaining space on each line. - [ValidateSet('Left','Right','Center')] + # If set, will generate a horizontal rule. + # If other parameters are provided, the horiztonal rule will be placed after. + [Parameter(ValueFromPipelineByPropertyName)] + [switch] + $HorizontalRule, + + # If set, will output the -InputObject as a Markdown code block + [Parameter(ValueFromPipelineByPropertyName)] + [switch] + $Code, + + # If set, will output the -InputObject as a Markdown code block, with a given language + # If the -InputObject is a ScriptBlock, -CodeLanguage will be set to PowerShell. + [Parameter(ValueFromPipelineByPropertyName)] [string] - $Alignment, + $CodeLanguage, - # The length of a line. By default, the buffer width - [int]$LineLength = $($host.UI.RawUI.BufferSize.Width) - ) + # If provided, will output a script block as a Markdown code block. + [Parameter(ValueFromPipelineByPropertyName)] + [ScriptBlock] + $ScriptBlock + ) begin { - $canUseANSI = $host.UI.SupportsVirtualTerminal - $canUseHTML = $Request -or $host.UI.SupportsHTML -or $OutputMode -eq 'HTML' - $knownStreams = @{ - Output='';Error='BrightRed';Warning='BrightYellow'; - Verbose='BrightCyan';Debug='Yellow';Progress='Cyan'; - Success='BrightGreen';Failure='Red';Default=''} - - $ansiCode = [Regex]::new(@' - (?<ANSI_Code> - (?-i)\e # An Escape - \[ # Followed by a bracket - (?<ParameterBytes>[\d\:\;\<\=\>\?]{0,}) # Followed by zero or more parameter - bytes - (?<IntermediateBytes>[\s\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/]{0,}) # Followed by zero or more - intermediate bytes - (?<FinalByte>[\@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\\\]\^_\`abcdefghijklmnopqrstuvwxyz\{\|\}\~]) # Followed by a final byte - - ) -'@) - $esc = [char]0x1b - $standardColors = 'Black', 'Red', 'Green', 'Yellow', 'Blue','Magenta', 'Cyan', 'White' - $brightColors = 'BrightBlack', 'BrightRed', 'BrightGreen', 'BrightYellow', 'BrightBlue','BrightMagenta', 'BrightCyan', 'BrightWhite' + $numberedListCounter = 0 + $IsFirst = $true + filter LinkInput { + $in = $_ + if ($ImageLink) { + "![$in]($imageLink)" + } elseif ($link) { + "[$in]($link)" + } else { + "$in" + } + } - $allOutput = @() + $markdownLines = @() + } - $n =0 - $cssClasses = @() - $colorAttributes = - @(:nextColor foreach ($hc in $ForegroundColor,$BackgroundColor) { - $n++ - if (-not $hc) { continue } - if ($hc[0] -eq $esc) { - if ($canUseANSI) { - $hc; continue - } - } + process { - $ansiStartPoint = if ($n -eq 1) { 30 } else { 40 } - if ($knownStreams.ContainsKey($hc)) { - $i = $brightColors.IndexOf($knownStreams[$hc]) - if ($canUseHTML) { - $cssClasses += $hc - } else { - if ($i -ge 0 -and $canUseANSI) { - '' + $esc + "[1;$($ansiStartPoint + $i)m" - } else { - $i = $standardColors.IndexOf($knownStreams[$hc]) - if ($i -ge 0 -and $canUseANSI) { - '' + $esc + "[1;$($ansiStartPoint + $i)m" - } elseif ($i -le 0 -and $canUseANSI) { - '' + $esc + "[$($ansistartpoint + 8):5m" - } - } - } - continue nextColor - } - elseif ($standardColors -contains $hc) { - for ($i = 0; $i -lt $standardColors.Count;$i++) { - if ($standardColors[$i] -eq $hc) { - if ($canUseANSI -and -not $canUseHTML) { - '' + $esc + "[$($ansiStartPoint + $i)m" - } else { - $cssClasses += $standardColors[$i] - } - continue nextColor - } - } - } elseif ($brightColors -contains $hc) { - for ($i = 0; $i -lt $brightColors.Count;$i++) { - if ($brightColors[$i] -eq $hc) { - if ($canUseANSI -and -not $canUseHTML) { - '' + $esc + "[1;$($ansiStartPoint + $i)m" - } else { - $cssClasses += $standardColors[$i] - } - continue nextColor - } - } - } - elseif ($psStyle -and $psStyle.Formatting.$hc -and - $psStyle.Formatting.$hc -match '^\e') { - if ($canUseANSI -and -not $canUseHTML) { - $psStyle.Formatting.$hc - } else { - $cssClasses += "formatting-$hc" - } - } - elseif (-not $n -and $psStyle -and $psStyle.Foreground.$hc -and - $psStyle.Foreground.$hc -match '^\e' ) { - if ($canUseANSI -and -not $canUseHTML) { - $psStyle.Foreground.$hc - } else { - $cssClasses += "foreground-$hc" - } - } - elseif ($n -and $psStyle -and $psStyle.Background.$hc -and - $psStyle.Background.$hc -match '^\e') { - if ($canUseANSI -and -not $canUseHTML) { - $psStyle.Background.$hc - } else { - $cssClasses += "background-$hc" - } - } + if ($ScriptBlock -or $inputObject -is [scriptblock]) { # If a -ScriptBlock was provided + $CodeLanguage = 'PowerShell' # use PowerShell as a Code Language. + } - - - if ($hc -and $hc -notmatch '^[\#\e]') { - $placesToLook= - @(if ($hc.Contains('.')) { - $module, $setting = $hc -split '\.', 2 - $theModule = Get-Module $module - $theModule.PrivateData.Color, - $theModule.PrivateData.Colors, - $theModule.PrivateData.Colour, - $theModule.PrivateData.Colours, - $theModule.PrivateData.EZOut, - $global:PSColors, - $global:PSColours - } else { - $setting = $hc - $moduleColorSetting = $theModule.PrivateData.PSColors.$setting - }) - - foreach ($place in $placesToLook) { - if (-not $place) { continue } - foreach ($propName in $setting -split '\.') { - $place = $place.$propName - if (-not $place) { break } - } - if ($place -and "$place".StartsWith('#') -and 4,7 -contains "$place".Length) { - $hc = $place - continue - } - } - if (-not $hc.StartsWith -or -not $hc.StartsWith('#')) { - continue - } - } - $r,$g,$b = if ($hc.Length -eq 7) { - [int]::Parse($hc[1..2]-join'', 'HexNumber') - [int]::Parse($hc[3..4]-join '', 'HexNumber') - [int]::Parse($hc[5..6] -join'', 'HexNumber') - }elseif ($hc.Length -eq 4) { - [int]::Parse($hc[1], 'HexNumber') * 16 - [int]::Parse($hc[2], 'HexNumber') * 16 - [int]::Parse($hc[3], 'HexNumber') * 16 + # If a -HeadingSize or a -Heading were provided, render a heading. + if ($HeadingSize -or $Heading) + { + if (-not $HeadingSize) { $HeadingSize = 2} # If the -HeadingSize was not set, set it to 2. + $headingContent = "$(if ($Heading) { $Heading} else { $inputObject | LinkInput})" + $markdownLines += + if ($HeadingSize -eq 1) { + $headingContent + '=' * [Math]::Max($headingContent.Length, 3) } - - if ($canUseHTML) { - if ($n -eq 1) { "color:$hc" } - elseif ($n -eq 2) { "background-color:$hc"} + elseif ($HeadingSize -eq 2) { + $headingContent + '-' * [Math]::Max($headingContent.Length, 3) } - elseif ($canUseANSI) { - if ($n -eq 1) { $esc+"[38;2;$r;$g;${b}m" } - elseif ($n -eq 2) { $esc+"[48;2;$r;$g;${b}m" } + else { + ("#"*$HeadingSize) + " $headingContent" # Output the -Heading or the -InputObject. } - - }) - - $styleAttributes = @() + $colorAttributes - - $styleAttributes += @( - if ($Bold) { - if ($canUseHTML) {"font-weight:bold"} - elseif ($canUseANSI) { '' + $esc + "[1m" } + } + # If -Code or -CodeLanguage was provided, render a Markdown code block. + elseif ($Code -or $CodeLanguage) + { + # If the -InputObject was a [ScriptBlock] or there is a -ScriptBlock + if ($InputObject -is [scriptblock] -or $ScriptBlock) { + $CodeLanguage = 'PowerShell' # set the code language to PowerShell. } - if ($Faint) { - if ($canUseHTML) { "opacity:.5" } - elseif ($canUseANSI) { '' + $esc + "[2m" } + $markdownLines += ( + '```' + # Start the code fence, + $(if ($CodeLanguage) { $CodeLanguage}) + # add the language, + [Environment]::newline + # then a newline, + $( + $codeContent = $(if ($ScriptBlock) { "$scriptBlock" } else { $inputObject | LinkInput}) # then the -ScriptBlock or -InputObject + $codeContent + ) + + [Environment]::newline + # then a newline + '```' # then close the code fence. + ) + } + # If -BulletPoint was passed, render a Bullet Point list. + elseif ($BulletPoint) + { + $markdownLines += "*$(if ($Checkbox) { "[$(if ($Checked) {"x"} else {" "})]"}) $($inputObject | LinkInput)" + } + # If -NumberedList was passed, render a numbered list. + elseif ($NumberedList -or $Number) + { + $numberedListCounter++ # Increment the counter + $markdownLines += "$(if ($number) { $number } else {$numberedListCounter}).$(if ($Checkbox) {" [$(if ($Checked) {"x"} else {" "})]"}) $($inputObject | LinkInput)" + } + elseif ($BlockQuote -or $BlockQuoteDepth) { + if (-not $BlockQuoteDepth) { $BlockQuoteDepth = 1 } + $markdownLines += (">" * $BlockQuoteDepth ) + ' ' + ( + "$inputObject" -split '(?>\r\n|\n)' -join ( + [Environment]::NewLine + (">" * $BlockQuoteDepth) + ' ' + ) + ) + } + # Otherwise, we have to determine if -InputObject should be a -MarkdownTable or a -MarkdownParagraph. + else + { + # If the input is a primitive type or a string, it should be a markdown paragraph + if (($inputObject.GetType -and $inputObject.GetType().IsPrimitive) -or + $inputObject -is [string]) { + $MarkdownParagraph = $true } - if ($Italic) { - if ($canUseHTML) { "font-weight:bold" } - elseif ($canUseANSI) {'' + $esc + "[3m" } + # If it is a dictionary, it should be a markdown table. + elseif ($inputObject -is [Collections.IDictionary]) + { + $MarkdownTable = $true } - - if ($Underline -and -not $doubleUnderline) { - if ($canUseHTML) { "text-decoration:underline"} - elseif ($canUseANSI) {'' +$esc + "[4m" } + # If the input is an array, apply the same logic: + elseif ($inputObject -is [Object[]] -or $InputObject -is [PSObject[]]) { + $allPrimitives = 1 + # if the array was all primitives or strings + foreach ($in in $InputObject) { + $allPrimitives = $allPrimitives -band ( + ($in.GetType -and $in.GetType().IsPrimitive) -or $in -is [string] + ) + } + if ($allPrimitives) { # output as a paragraph. + $MarkdownParagraph = $true + } else { + $MarkdownTable = $true + } } - - if ($Blink) { - if ($canUseANSI) { '' +$esc + "[5m" } + # If we're still not sure, output as a table. + else { + $MarkdownTable = $true } + } - if ($invert) { - if ($canUseHTML) {"filter:invert(100%)"} - elseif ($canUseANSI) { '' + $esc + "[7m"} - } + if ($MarkdownParagraph) { + # If we're outputting as a paragraph, add the input and link it if needed. + $markdownLines += $inputObject | LinkInput + } elseif ($MarkdownTable) { + # If we're rendering a table, we need to go row-by-row. + foreach ($in in $InputObject) { + $propertyList = @( + # we first need to get a list of properties. + # If there was a -Property parameter provided, use it. + if ($Property) { + foreach ($prop in $Property) { + if ($prop -is [string]) { # Strings in -Property should be taken as property names + $prop + } elseif ($prop.Name -and $prop.Expression -and $prop.Expression -is [scriptblock]) { + # and anything with a name and expression script block will run the expression script block. + $_ = $psItem = $in + @{name=$prop.Name;Value = . $prop.Expression} + } + } + } + # Otherwise, if the input was a dictionary + elseif ($in -is [Collections.IDictionary]) + { + foreach ($k in $in.Keys) { # take all keys from the dictionary + if ($MyInvocation.MyCommand.Parameters[$k]) { continue } # that are not parameters of this function. + $k + } + } + # Otherwise, walk over all properties on the object + else { + foreach ($psProp in $In.psobject.properties) { + # and skip any properties that are parameters of this function. + if ($psProp.Name -notin $MyInvocation.MyCommand.Parameters.Keys) { + $psProp + } + } + } + ) - if ($hide) { - if ($canUseHTML) {"opacity:0"} - elseif ($canUseANSI) { '' + $esc + "[8m"} - } - - if ($Strikethru) { - if ($canUseHTML) {"text-decoration: line-through"} - elseif ($canUseANSI) { '' +$esc + "[9m" } - } - - if ($DoubleUnderline) { - if ($canUseHTML) { "border-bottom: 3px double;"} - elseif ($canUseANSI) {'' +$esc + "[21m" } - } + # If we're rendering the first row of a table + if ($IsFirst) { + # Create the header + $markdownLines += + '|' + (@(foreach ($prop in $propertyList) { + if ($prop -is [string]) { + $prop + } else { + $prop.Name + } + }) -replace ([Environment]::newline), '<br/>' -replace '\|', '\|' -join '|') + '|' + # Then create the alignment row. + $markdownLines += + '|' + $( + $columnNumber =0 + @( + foreach ($prop in $propertyList) { + $colLength = + if ($prop -is [string]) { + $prop.Length + } else { + $prop.Name.Length + } + if ($MarkdownTableAlignment) { + if ($MarkdownTableAlignment[$columnNumber] -eq 'Left') { + ':' + ("-" * ([Math]::Max($colLength,2) - 1)) + } + elseif ($MarkdownTableAlignment[$columnNumber] -eq 'Right') { + ("-" * ([Math]::Max($colLength,2) - 1)) + ':' + } + elseif ($MarkdownTableAlignment[$columnNumber] -eq 'Center') { + ':' + ("-" * ([Math]::max($colLength, 3) - 2)) + ':' + } else { + "-" * $colLength + } + } else { + "-" * $colLength + } + + $columnNumber++ + } + ) -replace ([Environment]::newline), '<br/>' -replace '\|', '\|' -join '|') + '|' + $IsFirst = $false + } + + # Now we create the row for this object. - if ($Alignment -and $canUseHTML) { - "display:block;text-align:$($Alignment.ToLower())" - } + $markdownLine = '|' + ( + @( + foreach ($prop in $propertyList) { + if ($prop -is [string]) { + $in.$prop | LinkInput + } else { + $prop.Value | LinkInput + } + } + ) -replace ([Environment]::newline), '<br/>' -replace '\|', '\|' -join '|') + '|' + + $markdownLines += $markdownLine + } + } - if ($Link) { - if ($canUseHTML) { - # Hyperlinks need to be a nested element - # so we will not add it to style attributes for HTML - } - elseif ($canUseANSI) { - # For ANSI, - '' + $esc + ']8;;' + $Link + $esc + '\' - } - } - ) - - $header = - if ($canUseHTML) { - "<span$( - if ($styleAttributes) { " style='$($styleAttributes -join ';')'"} - )$( - if ($cssClasses) { " class='$($cssClasses -join ' ')'"} - )>" + $( - if ($Link) { - "<a href='$link'>" - } - ) - } elseif ($canUseANSI) { - $styleAttributes -join '' - } - } + if ( # There are a few combinations of parameters that make us want to write the -InputObject as a paragraph: + ($ScriptBlock -and $inputObject) -or # * If -ScriptBlock and -InputObject were both provided. + ($Heading -and $inputObject) # * if -Heading and -InputObject were both provided + ) { + $markdownLines += $InputObject | LinkInput + } - process { - $inputObjectAsString = - "$(if ($inputObject) { $inputObject | Out-String})".Trim() - $inputObjectAsString = - if ($Alignment -and -not $canUseHTML) { - (@(foreach ($inputObjectLine in ($inputObjectAsString -split '(?>\r\n|\n)')) { - $inputObjectLength = $ansiCode.Replace($inputObjectLine, '').Length - if ($inputObjectLength -lt $LineLength) { - if ($Alignment -eq 'Left') { - $inputObjectLine - } elseif ($Alignment -eq 'Right') { - (' ' * ($LineLength - $inputObjectLength)) + $inputObjectLine - } else { - $half = ($LineLength - $inputObjectLength)/2 - (' ' * [Math]::Floor($half)) + $inputObjectLine + - (' ' * [Math]::Ceiling($half)) - } - } - else { - $inputObjectLine - } - }) -join [Environment]::NewLine) + [Environment]::newline + # If we're going to render a horizontal rule (and -MarkdownTable has not been set) + if ($HorizontalRule -and -not $MarkdownTable) { + # add the horizontal rule at the end. + if ($host.UI.RawUI.BufferSize.Width) { + $markdownLines += (([string]$HorizontalRuleCharacter) * ($Host.UI.RawUI.BufferSize.Width - 1)) } else { - $inputObjectAsString - } - - $allOutput += - if ($header) { - "$header" + $inputObjectAsString - } - elseif ($inputObject) { - $inputObjectAsString - } + $markdownLines += "---" + } + } } end { - - if (-not $NoClear) { - $allOutput += - if ($canUseHTML) { - if ($Link) { - "</a>" + # Now we need to make one last pass to normalize tables + if ($markdownLines -match '^\|') { # (that is, if we have tables to normalize). + $maxColumnSize = @{} # To normalize the table, we need to track the maximum size per column + foreach ($ml in $markdownLines) { + if ($ml -match '\^|') { + $columnCount = 0 + foreach ($tablePart in $ml -split '(?<!\\)\|' -ne '') { + if ((-not $maxColumnSize[$columnCount]) -or $maxColumnSize[$columnCount] -lt $tablePart.Length) { + $maxColumnSize[$columnCount] = [Math]::Max($tablePart.Length, 2) + } + $columnCount++ } - "</span>" } - elseif ($canUseANSI) { - if ($Bold -or $Faint -or $colorAttributes -match '\[1;') { - "$esc[22m" - } - if ($Italic) { - "$esc[23m" - } - if ($Underline -or $doubleUnderline) { - "$esc[24m" - } - if ($Blink) { - "$esc[25m" - } - if ($Invert) { - "$esc[27m" - } - if ($hide) { - "$esc[28m" - } - if ($Strikethru) { - "$esc[29m" - } - if ($ForegroundColor) { - "$esc[39m" - } - if ($BackgroundColor) { - "$esc[49m" - } - - if ($Link) { - "$esc]8;;$esc\" - } - - if (-not ($Underline -or $Bold -or $Invert -or $ForegroundColor -or $BackgroundColor)) { - '' + $esc + '[0m' - } + } + # One we know the maximum size per column, walk over each line + $markdownLines = @(foreach ($ml in $markdownLines) { + if ($ml -match '\^|') { + $columnCount = 0 + # Recreate the line with the right amount of padding. + '|' + (@(foreach ($tablePart in $ml -split '(?<!\\)\|' -ne '') { + if ($tablePart -match '^[:\-]+$') { + if ($tablePart -match '^\:-{0,}\:$') { # If it's an alignment column, make sure to keep the alignment. + if ($maxColumnSize[$columnCount] -gt 2) { + ':' + ('-' * ($maxColumnSize[$columnCount] - 2)) + ':' + } else { + '::' + } + } + elseif ($tablePart -match '\:$') { + $tablePart.PadLeft($maxColumnSize[$columnCount], '-') + } + elseif ($tablePart -match '^\:') { + $tablePart.PadRight($maxColumnSize[$columnCount], '-') + } + else { + $tablePart.PadRight($maxColumnSize[$columnCount], '-') + } + } else { + $tablePart.PadRight($maxColumnSize[$columnCount], ' ') + } + $columnCount++ + }) -join '|') + '|' + } else { + $ml } + }) } - - $allOutput -join '' + $markdownLines -join [Environment]::NewLine } @@ -2499,7 +2582,7 @@ if ($Request -or $Host.UI.SupportsHTML) { - ${Posh_Format-Markdown} + ${Posh_Format-Heatmap} @@ -2508,502 +2591,495 @@ if ($Request -or $Host.UI.SupportsHTML) { <# .SYNOPSIS - Formats an object as Markdown + Formats a value as a heatmap .DESCRIPTION - Formats an object as Markdown, with many options to work with - .EXAMPLE - Format-Markdown -ScriptBlock { - Get-Process - } - .EXAMPLE - 1..6 | Format-Markdown -HeadingSize { $_ } + Returns the color used to generate a heatmap for a given value. #> - [Management.Automation.Cmdlet("Format","Object")] + [Management.Automation.Cmdlet("Format", "Object")] [ValidateScript({return $true})] - param( - [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)] - [PSObject] + param( + # The value that will be heatmapped. + [Parameter(ValueFromPipeline)] $InputObject, - # If set, will treat the -InputObject as a paragraph. - # This is the default for strings, booleans, numbers, and other primitive types. - [Parameter(ValueFromPipelineByPropertyName)] - [switch] - $MarkdownParagraph, + # The Heatmap maximum, by default 1gb + [Parameter(Mandatory)] + $HeatMapMax = 1gb, + + # The Heatmap middle value, by default 512mb + $HeatMapMiddle = 512mb, + + # The Heatmap minimum value, by default 0 + $HeatMapMin = 0, + + # The color for cool. + # To pass a Hex color as an int, simply replace # with 0x + # (e.g. 0x00ff00 for green instead of '#00ff00') + [int] + $HeatMapCool =0x05dd00, + + # The color for hot. + # To pass a Hex color as an int, simply replace # with 0x + # (e.g. 0xff0000 for red instead of '#ff0000') + [int] + $HeatMapHot = 0xef1100 + ) - # If set, will generate a markdown table. - [Parameter(ValueFromPipelineByPropertyName)] - [switch] - $MarkdownTable, + process { + # Separate out the segments of the color, + $coolRedPart = [byte](($HeatMapCool -band 0xff0000) -shr 16) # by bitmasking and then shifting right until it's bytes + $coolGreenPart = [byte](($HeatMapCool -band 0x00ff00) -shr 8) + $coolBluePart = [byte]($HeatMapCool -band 0x0000ff) - # If provided, will align columnns in a markdown table. - [Parameter(ValueFromPipelineByPropertyName)] - [ValidateSet("Left","Right","Center", "")] - [string[]] - $MarkdownTableAlignment, + $hotRedPart = [byte](($HeatMapHot -band 0xff0000) -shr 16) + $hotGreenPart = [byte](($HeatMapHot -band 0x00ff00) -shr 8) + $hotBluePart = [byte]($HeatMapHot -band 0x0000ff) + + "#{0:x2}{1:x2}{2:x2}" -f @( + if ($InputObject -le $HeatMapMin) + { + $coolRedPart, $coolGreenPart, $coolBluePart + } + elseif ($InputObject -ge $HeatMapMax) + { + $hotRedPart, $hotGreenPart, $hotBluePart + } else { + if ($InputObject -le $HeatMapMiddle) + { + $d = 1 - ([double]$InputObject / ($HeatMapMiddle - $HeatMapMin)) + [Byte][Math]::Min(255, $hotRedPart * $d + $coolRedPart) + [Byte][Math]::Min(255, $hotGreenPart * $d + $coolGreenPart) + [Byte][Math]::Min(255, $hotBluePart * $d + $coolBluePart) + } else + { + $d = 1 - ([double]$InputObject / ($HeatMapMax - $HeatMapMiddle)) + [Byte][Math]::Min(255, $coolRedPart * $d + $hotRedPart) + [Byte][Math]::Min(255, $coolGreenPart * $d + $hotGreenPart) + [Byte][Math]::Min(255, $coolBluePart * $d + $hotBluePart) + } + }) + } + + + + + + + + + ${Posh_Format-RichText} + + + + + + + <# + .Synopsis + Formats the text color of output + .Description + Formats the text color of output + + * ForegroundColor + * BackgroundColor + * Bold + * Underline + .Notes + Stylized Output works in two contexts at present: + * Rich consoles (Windows Terminal, PowerShell.exe, Pwsh.exe) (when $host.UI.SupportsVirtualTerminal) + * Web pages (Based off the presence of a $Request variable, or when $host.UI.SupportsHTML (you must add this property to $host.UI)) + #> + [Management.Automation.Cmdlet("Format","Object")] + [ValidateScript({ + $canUseANSI = $host.UI.SupportsVirtualTerminal + $canUseHTML = $Request -or $host.UI.SupportsHTML -or $OutputMode -eq 'HTML' + if (-not ($canUseANSI -or $canUseHTML)) { return $false} + return $true + })] + [OutputType([string])] + param( + # The input object + [Parameter(ValueFromPipeline)] + [PSObject] + $InputObject, + + # The foreground color + [string]$ForegroundColor, - # An array of properties. Providing this implies -MarkdownTable - [Parameter(ValueFromPipelineByPropertyName)] - [PSObject[]] - $Property, + # The background color + [string]$BackgroundColor, - # A heading. - # If provided without -HeadingSize, -HeadingSize will default to 2. - # If provided with -InputObject, -Heading will take priority. - [Parameter(ValueFromPipelineByPropertyName)] - [string] - $Heading, + # If set, will render as bold + [switch]$Bold, - # The heading size (1-6) - # If provided without -Heading, the -InputObject will be considered to be a heading. - [Parameter(ValueFromPipelineByPropertyName)] - [ValidateRange(1,6)] - [int] - $HeadingSize, + # If set, will render as italic. + [Alias('Italics')] + [switch]$Italic, - # If set, will create a link. The -InputObject will be used as the link content - [Parameter(ValueFromPipelineByPropertyName)] - [Alias('Hyperlink', 'Href')] - [string] - $Link, + # If set, will render as faint + [switch]$Faint, - # If set, will create an image link. The -Inputobject will be used as the link content. - [Parameter(ValueFromPipelineByPropertyName)] - [string] - $ImageLink, + # If set, will render as hidden text. + [switch]$Hide, - # If set, will generate a bullet point list. - [Parameter(ValueFromPipelineByPropertyName)] - [Alias('BulletpointList')] - [switch] - $BulletPoint, - - # If set, bullet or numbered list items will have a checkbox. - # Each piped -InputObject will be an additional list item. - [Parameter(ValueFromPipelineByPropertyName)] - [switch] - $Checkbox, + # If set, will render as blinking (not supported in all terminals or HTML) + [switch]$Blink, - # If set, bullet or numbered list items will be checked. - [Parameter(ValueFromPipelineByPropertyName)] - [switch] - $Checked, + # If set, will render as strikethru + [Alias('Strikethrough', 'Crossout')] + [switch]$Strikethru, - # If set, will generate a numbered list. - # Each piped -InputObject will be an additional list item. - [Parameter(ValueFromPipelineByPropertyName)] - [switch] - $NumberedList, + # If set, will underline text + [switch]$Underline, - # If set, will generate a block quote. - # Each line of the -InputObject will be block quoted. - [Parameter(ValueFromPipelineByPropertyName)] - [switch] - $BlockQuote, + # If set, will double underline text. + [switch]$DoubleUnderline, - # If set, will generate a block quote of a particular depth. - # Each line of the -InputObject will be block quoted. - [Parameter(ValueFromPipelineByPropertyName)] - [ValidateRange(1,3)] - [int] - $BlockQuoteDepth, - - # If provided, will create a markdown numbered list with this particular item as the number. - [Parameter(ValueFromPipelineByPropertyName)] - [int] - $Number, + # If set, will invert text + [switch]$Invert, - # If set, will generate a horizontal rule. - # If other parameters are provided, the horiztonal rule will be placed after. - [Parameter(ValueFromPipelineByPropertyName)] - [switch] - $HorizontalRule, + # If provided, will create a hyperlink to a given uri + [Alias('Hyperlink', 'Href')] + [uri] + $Link, - # If set, will output the -InputObject as a Markdown code block - [Parameter(ValueFromPipelineByPropertyName)] - [switch] - $Code, + # If set, will not clear formatting + [switch]$NoClear, - # If set, will output the -InputObject as a Markdown code block, with a given language - # If the -InputObject is a ScriptBlock, -CodeLanguage will be set to PowerShell. - [Parameter(ValueFromPipelineByPropertyName)] + # The alignment. Defaulting to Left. + # Setting an alignment will pad the remaining space on each line. + [ValidateSet('Left','Right','Center')] [string] - $CodeLanguage, + $Alignment, - # If provided, will output a script block as a Markdown code block. - [Parameter(ValueFromPipelineByPropertyName)] - [ScriptBlock] - $ScriptBlock - ) + # The length of a line. By default, the buffer width + [int]$LineLength = $($host.UI.RawUI.BufferSize.Width) + ) begin { - $numberedListCounter = 0 - $IsFirst = $true - filter LinkInput { - $in = $_ - if ($ImageLink) { - "![$in]($imageLink)" - } elseif ($link) { - "[$in]($link)" - } else { - "$in" - } - } - - $markdownLines = @() - } + $canUseANSI = $host.UI.SupportsVirtualTerminal + $canUseHTML = $Request -or $host.UI.SupportsHTML -or $OutputMode -eq 'HTML' + $knownStreams = @{ + Output='';Error='BrightRed';Warning='BrightYellow'; + Verbose='BrightCyan';Debug='Yellow';Progress='Cyan'; + Success='BrightGreen';Failure='Red';Default=''} - process { + $ansiCode = [Regex]::new(@' + (?<ANSI_Code> + (?-i)\e # An Escape + \[ # Followed by a bracket + (?<ParameterBytes>[\d\:\;\<\=\>\?]{0,}) # Followed by zero or more parameter + bytes + (?<IntermediateBytes>[\s\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/]{0,}) # Followed by zero or more + intermediate bytes + (?<FinalByte>[\@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\\\]\^_\`abcdefghijklmnopqrstuvwxyz\{\|\}\~]) # Followed by a final byte - if ($ScriptBlock -or $inputObject -is [scriptblock]) { # If a -ScriptBlock was provided - $CodeLanguage = 'PowerShell' # use PowerShell as a Code Language. - } + ) +'@) + $esc = [char]0x1b + $standardColors = 'Black', 'Red', 'Green', 'Yellow', 'Blue','Magenta', 'Cyan', 'White' + $brightColors = 'BrightBlack', 'BrightRed', 'BrightGreen', 'BrightYellow', 'BrightBlue','BrightMagenta', 'BrightCyan', 'BrightWhite' - # If a -HeadingSize or a -Heading were provided, render a heading. - if ($HeadingSize -or $Heading) - { - if (-not $HeadingSize) { $HeadingSize = 2} # If the -HeadingSize was not set, set it to 2. - $headingContent = "$(if ($Heading) { $Heading} else { $inputObject | LinkInput})" - $markdownLines += - if ($HeadingSize -eq 1) { - $headingContent - '=' * [Math]::Max($headingContent.Length, 3) - } - elseif ($HeadingSize -eq 2) { - $headingContent - '-' * [Math]::Max($headingContent.Length, 3) - } - else { - ("#"*$HeadingSize) + " $headingContent" # Output the -Heading or the -InputObject. - } - } - # If -Code or -CodeLanguage was provided, render a Markdown code block. - elseif ($Code -or $CodeLanguage) - { - # If the -InputObject was a [ScriptBlock] or there is a -ScriptBlock - if ($InputObject -is [scriptblock] -or $ScriptBlock) { - $CodeLanguage = 'PowerShell' # set the code language to PowerShell. - } - $markdownLines += ( - '```' + # Start the code fence, - $(if ($CodeLanguage) { $CodeLanguage}) + # add the language, - [Environment]::newline + # then a newline, - $( - $codeContent = $(if ($ScriptBlock) { "$scriptBlock" } else { $inputObject | LinkInput}) # then the -ScriptBlock or -InputObject - $codeContent - ) + - [Environment]::newline + # then a newline - '```' # then close the code fence. - ) - } - # If -BulletPoint was passed, render a Bullet Point list. - elseif ($BulletPoint) - { - $markdownLines += "*$(if ($Checkbox) { "[$(if ($Checked) {"x"} else {" "})]"}) $($inputObject | LinkInput)" - } - # If -NumberedList was passed, render a numbered list. - elseif ($NumberedList -or $Number) - { - $numberedListCounter++ # Increment the counter - $markdownLines += "$(if ($number) { $number } else {$numberedListCounter}).$(if ($Checkbox) {" [$(if ($Checked) {"x"} else {" "})]"}) $($inputObject | LinkInput)" - } - elseif ($BlockQuote -or $BlockQuoteDepth) { - if (-not $BlockQuoteDepth) { $BlockQuoteDepth = 1 } - $markdownLines += (">" * $BlockQuoteDepth ) + ' ' + ( - "$inputObject" -split '(?>\r\n|\n)' -join ( - [Environment]::NewLine + (">" * $BlockQuoteDepth) + ' ' - ) - ) - } - # Otherwise, we have to determine if -InputObject should be a -MarkdownTable or a -MarkdownParagraph. - else - { - # If the input is a primitive type or a string, it should be a markdown paragraph - if (($inputObject.GetType -and $inputObject.GetType().IsPrimitive) -or - $inputObject -is [string]) { - $MarkdownParagraph = $true - } - # If it is a dictionary, it should be a markdown table. - elseif ($inputObject -is [Collections.IDictionary]) - { - $MarkdownTable = $true - } - # If the input is an array, apply the same logic: - elseif ($inputObject -is [Object[]] -or $InputObject -is [PSObject[]]) { - $allPrimitives = 1 - # if the array was all primitives or strings - foreach ($in in $InputObject) { - $allPrimitives = $allPrimitives -band ( - ($in.GetType -and $in.GetType().IsPrimitive) -or $in -is [string] - ) - } - if ($allPrimitives) { # output as a paragraph. - $MarkdownParagraph = $true - } else { - $MarkdownTable = $true - } - } - # If we're still not sure, output as a table. - else { - $MarkdownTable = $true - } - } + $allOutput = @() - if ($MarkdownParagraph) { - # If we're outputting as a paragraph, add the input and link it if needed. - $markdownLines += $inputObject | LinkInput - } elseif ($MarkdownTable) { - # If we're rendering a table, we need to go row-by-row. - foreach ($in in $InputObject) { - $propertyList = @( - # we first need to get a list of properties. - # If there was a -Property parameter provided, use it. - if ($Property) { - foreach ($prop in $Property) { - if ($prop -is [string]) { # Strings in -Property should be taken as property names - $prop - } elseif ($prop.Name -and $prop.Expression -and $prop.Expression -is [scriptblock]) { - # and anything with a name and expression script block will run the expression script block. - $_ = $psItem = $in - @{name=$prop.Name;Value = . $prop.Expression} + $n =0 + $cssClasses = @() + $colorAttributes = + @(:nextColor foreach ($hc in $ForegroundColor,$BackgroundColor) { + $n++ + if (-not $hc) { continue } + if ($hc[0] -eq $esc) { + if ($canUseANSI) { + $hc; continue + } + } + + $ansiStartPoint = if ($n -eq 1) { 30 } else { 40 } + if ($knownStreams.ContainsKey($hc)) { + $i = $brightColors.IndexOf($knownStreams[$hc]) + if ($canUseHTML) { + $cssClasses += $hc + } else { + if ($i -ge 0 -and $canUseANSI) { + '' + $esc + "[1;$($ansiStartPoint + $i)m" + } else { + $i = $standardColors.IndexOf($knownStreams[$hc]) + if ($i -ge 0 -and $canUseANSI) { + '' + $esc + "[1;$($ansiStartPoint + $i)m" + } elseif ($i -le 0 -and $canUseANSI) { + '' + $esc + "[$($ansistartpoint + 8):5m" } } - } - # Otherwise, if the input was a dictionary - elseif ($in -is [Collections.IDictionary]) - { - foreach ($k in $in.Keys) { # take all keys from the dictionary - if ($MyInvocation.MyCommand.Parameters[$k]) { continue } # that are not parameters of this function. - $k - } } - # Otherwise, walk over all properties on the object - else { - foreach ($psProp in $In.psobject.properties) { - # and skip any properties that are parameters of this function. - if ($psProp.Name -notin $MyInvocation.MyCommand.Parameters.Keys) { - $psProp + continue nextColor + } + elseif ($standardColors -contains $hc) { + for ($i = 0; $i -lt $standardColors.Count;$i++) { + if ($standardColors[$i] -eq $hc) { + if ($canUseANSI -and -not $canUseHTML) { + '' + $esc + "[$($ansiStartPoint + $i)m" + } else { + $cssClasses += $standardColors[$i] } + continue nextColor } } - ) - - # If we're rendering the first row of a table - if ($IsFirst) { - # Create the header - $markdownLines += - '|' + (@(foreach ($prop in $propertyList) { - if ($prop -is [string]) { - $prop + } elseif ($brightColors -contains $hc) { + for ($i = 0; $i -lt $brightColors.Count;$i++) { + if ($brightColors[$i] -eq $hc) { + if ($canUseANSI -and -not $canUseHTML) { + '' + $esc + "[1;$($ansiStartPoint + $i)m" } else { - $prop.Name + $cssClasses += $standardColors[$i] } - }) -replace ([Environment]::newline), '<br/>' -replace '\|', '\|' -join '|') + '|' - # Then create the alignment row. - $markdownLines += - '|' + $( - $columnNumber =0 - @( - foreach ($prop in $propertyList) { - $colLength = - if ($prop -is [string]) { - $prop.Length - } else { - $prop.Name.Length - } - if ($MarkdownTableAlignment) { - if ($MarkdownTableAlignment[$columnNumber] -eq 'Left') { - ':' + ("-" * ([Math]::Max($colLength,2) - 1)) - } - elseif ($MarkdownTableAlignment[$columnNumber] -eq 'Right') { - ("-" * ([Math]::Max($colLength,2) - 1)) + ':' - } - elseif ($MarkdownTableAlignment[$columnNumber] -eq 'Center') { - ':' + ("-" * ([Math]::max($colLength, 3) - 2)) + ':' - } else { - "-" * $colLength - } - } else { - "-" * $colLength - } - - $columnNumber++ - } - ) -replace ([Environment]::newline), '<br/>' -replace '\|', '\|' -join '|') + '|' - $IsFirst = $false + continue nextColor + } + } + } + elseif ($psStyle -and $psStyle.Formatting.$hc -and + $psStyle.Formatting.$hc -match '^\e') { + if ($canUseANSI -and -not $canUseHTML) { + $psStyle.Formatting.$hc + } else { + $cssClasses += "formatting-$hc" + } + } + elseif (-not $n -and $psStyle -and $psStyle.Foreground.$hc -and + $psStyle.Foreground.$hc -match '^\e' ) { + if ($canUseANSI -and -not $canUseHTML) { + $psStyle.Foreground.$hc + } else { + $cssClasses += "foreground-$hc" + } + } + elseif ($n -and $psStyle -and $psStyle.Background.$hc -and + $psStyle.Background.$hc -match '^\e') { + if ($canUseANSI -and -not $canUseHTML) { + $psStyle.Background.$hc + } else { + $cssClasses += "background-$hc" + } } - - # Now we create the row for this object. - $markdownLine = '|' + ( - @( - foreach ($prop in $propertyList) { - if ($prop -is [string]) { - $in.$prop | LinkInput - } else { - $prop.Value | LinkInput - } + + + if ($hc -and $hc -notmatch '^[\#\e]') { + $placesToLook= + @(if ($hc.Contains('.')) { + $module, $setting = $hc -split '\.', 2 + $theModule = Get-Module $module + $theModule.PrivateData.Color, + $theModule.PrivateData.Colors, + $theModule.PrivateData.Colour, + $theModule.PrivateData.Colours, + $theModule.PrivateData.EZOut, + $global:PSColors, + $global:PSColours + } else { + $setting = $hc + $moduleColorSetting = $theModule.PrivateData.PSColors.$setting + }) + + foreach ($place in $placesToLook) { + if (-not $place) { continue } + foreach ($propName in $setting -split '\.') { + $place = $place.$propName + if (-not $place) { break } } - ) -replace ([Environment]::newline), '<br/>' -replace '\|', '\|' -join '|') + '|' + if ($place -and "$place".StartsWith('#') -and 4,7 -contains "$place".Length) { + $hc = $place + continue + } + } + if (-not $hc.StartsWith -or -not $hc.StartsWith('#')) { + continue + } + } + $r,$g,$b = if ($hc.Length -eq 7) { + [int]::Parse($hc[1..2]-join'', 'HexNumber') + [int]::Parse($hc[3..4]-join '', 'HexNumber') + [int]::Parse($hc[5..6] -join'', 'HexNumber') + }elseif ($hc.Length -eq 4) { + [int]::Parse($hc[1], 'HexNumber') * 16 + [int]::Parse($hc[2], 'HexNumber') * 16 + [int]::Parse($hc[3], 'HexNumber') * 16 + } + + if ($canUseHTML) { + if ($n -eq 1) { "color:$hc" } + elseif ($n -eq 2) { "background-color:$hc"} + } + elseif ($canUseANSI) { + if ($n -eq 1) { $esc+"[38;2;$r;$g;${b}m" } + elseif ($n -eq 2) { $esc+"[48;2;$r;$g;${b}m" } + } + + }) + + $styleAttributes = @() + $colorAttributes + + $styleAttributes += @( + if ($Bold) { + if ($canUseHTML) {"font-weight:bold"} + elseif ($canUseANSI) { '' + $esc + "[1m" } + } + if ($Faint) { + if ($canUseHTML) { "opacity:.5" } + elseif ($canUseANSI) { '' + $esc + "[2m" } + } + if ($Italic) { + if ($canUseHTML) { "font-weight:bold" } + elseif ($canUseANSI) {'' + $esc + "[3m" } + } + + if ($Underline -and -not $doubleUnderline) { + if ($canUseHTML) { "text-decoration:underline"} + elseif ($canUseANSI) {'' +$esc + "[4m" } + } - $markdownLines += $markdownLine - } - } + if ($Blink) { + if ($canUseANSI) { '' +$esc + "[5m" } + } + + if ($invert) { + if ($canUseHTML) {"filter:invert(100%)"} + elseif ($canUseANSI) { '' + $esc + "[7m"} + } + + if ($hide) { + if ($canUseHTML) {"opacity:0"} + elseif ($canUseANSI) { '' + $esc + "[8m"} + } + + if ($Strikethru) { + if ($canUseHTML) {"text-decoration: line-through"} + elseif ($canUseANSI) { '' +$esc + "[9m" } + } + + if ($DoubleUnderline) { + if ($canUseHTML) { "border-bottom: 3px double;"} + elseif ($canUseANSI) {'' +$esc + "[21m" } + } + + if ($Alignment -and $canUseHTML) { + "display:block;text-align:$($Alignment.ToLower())" + } + if ($Link) { + if ($canUseHTML) { + # Hyperlinks need to be a nested element + # so we will not add it to style attributes for HTML + } + elseif ($canUseANSI) { + # For ANSI, + '' + $esc + ']8;;' + $Link + $esc + '\' + } + } - if ( # There are a few combinations of parameters that make us want to write the -InputObject as a paragraph: - ($ScriptBlock -and $inputObject) -or # * If -ScriptBlock and -InputObject were both provided. - ($Heading -and $inputObject) # * if -Heading and -InputObject were both provided - ) { - $markdownLines += $InputObject | LinkInput - } + ) + + $header = + if ($canUseHTML) { + "<span$( + if ($styleAttributes) { " style='$($styleAttributes -join ';')'"} + )$( + if ($cssClasses) { " class='$($cssClasses -join ' ')'"} + )>" + $( + if ($Link) { + "<a href='$link'>" + } + ) + } elseif ($canUseANSI) { + $styleAttributes -join '' + } + } + process { + $inputObjectAsString = + "$(if ($inputObject) { $inputObject | Out-String})".Trim() - # If we're going to render a horizontal rule (and -MarkdownTable has not been set) - if ($HorizontalRule -and -not $MarkdownTable) { - # add the horizontal rule at the end. - if ($host.UI.RawUI.BufferSize.Width) { - $markdownLines += (([string]$HorizontalRuleCharacter) * ($Host.UI.RawUI.BufferSize.Width - 1)) + $inputObjectAsString = + if ($Alignment -and -not $canUseHTML) { + (@(foreach ($inputObjectLine in ($inputObjectAsString -split '(?>\r\n|\n)')) { + $inputObjectLength = $ansiCode.Replace($inputObjectLine, '').Length + if ($inputObjectLength -lt $LineLength) { + if ($Alignment -eq 'Left') { + $inputObjectLine + } elseif ($Alignment -eq 'Right') { + (' ' * ($LineLength - $inputObjectLength)) + $inputObjectLine + } else { + $half = ($LineLength - $inputObjectLength)/2 + (' ' * [Math]::Floor($half)) + $inputObjectLine + + (' ' * [Math]::Ceiling($half)) + } + } + else { + $inputObjectLine + } + }) -join [Environment]::NewLine) + [Environment]::newline } else { - $markdownLines += "---" - } - } + $inputObjectAsString + } + + $allOutput += + if ($header) { + "$header" + $inputObjectAsString + } + elseif ($inputObject) { + $inputObjectAsString + } } end { - # Now we need to make one last pass to normalize tables - if ($markdownLines -match '^\|') { # (that is, if we have tables to normalize). - $maxColumnSize = @{} # To normalize the table, we need to track the maximum size per column - foreach ($ml in $markdownLines) { - if ($ml -match '\^|') { - $columnCount = 0 - foreach ($tablePart in $ml -split '(?<!\\)\|' -ne '') { - if ((-not $maxColumnSize[$columnCount]) -or $maxColumnSize[$columnCount] -lt $tablePart.Length) { - $maxColumnSize[$columnCount] = [Math]::Max($tablePart.Length, 2) - } - $columnCount++ + + if (-not $NoClear) { + $allOutput += + if ($canUseHTML) { + if ($Link) { + "</a>" } + "</span>" } - } - # One we know the maximum size per column, walk over each line - $markdownLines = @(foreach ($ml in $markdownLines) { - if ($ml -match '\^|') { - $columnCount = 0 - # Recreate the line with the right amount of padding. - '|' + (@(foreach ($tablePart in $ml -split '(?<!\\)\|' -ne '') { - if ($tablePart -match '^[:\-]+$') { - if ($tablePart -match '^\:-{0,}\:$') { # If it's an alignment column, make sure to keep the alignment. - if ($maxColumnSize[$columnCount] -gt 2) { - ':' + ('-' * ($maxColumnSize[$columnCount] - 2)) + ':' - } else { - '::' - } - } - elseif ($tablePart -match '\:$') { - $tablePart.PadLeft($maxColumnSize[$columnCount], '-') - } - elseif ($tablePart -match '^\:') { - $tablePart.PadRight($maxColumnSize[$columnCount], '-') - } - else { - $tablePart.PadRight($maxColumnSize[$columnCount], '-') - } - } else { - $tablePart.PadRight($maxColumnSize[$columnCount], ' ') - } - $columnCount++ - }) -join '|') + '|' - } else { - $ml + elseif ($canUseANSI) { + if ($Bold -or $Faint -or $colorAttributes -match '\[1;') { + "$esc[22m" + } + if ($Italic) { + "$esc[23m" + } + if ($Underline -or $doubleUnderline) { + "$esc[24m" + } + if ($Blink) { + "$esc[25m" + } + if ($Invert) { + "$esc[27m" + } + if ($hide) { + "$esc[28m" + } + if ($Strikethru) { + "$esc[29m" + } + if ($ForegroundColor) { + "$esc[39m" + } + if ($BackgroundColor) { + "$esc[49m" + } + + if ($Link) { + "$esc]8;;$esc\" + } + + if (-not ($Underline -or $Bold -or $Invert -or $ForegroundColor -or $BackgroundColor)) { + '' + $esc + '[0m' + } } - }) } - $markdownLines -join [Environment]::NewLine - } - - - - - - - - - ${Posh_Format-Heatmap} - - - - - - - <# - .SYNOPSIS - Formats a value as a heatmap - .DESCRIPTION - Returns the color used to generate a heatmap for a given value. - #> - [Management.Automation.Cmdlet("Format", "Object")] - [ValidateScript({return $true})] - param( - # The value that will be heatmapped. - [Parameter(ValueFromPipeline)] - $InputObject, - - # The Heatmap maximum, by default 1gb - [Parameter(Mandatory)] - $HeatMapMax = 1gb, - - # The Heatmap middle value, by default 512mb - $HeatMapMiddle = 512mb, - - # The Heatmap minimum value, by default 0 - $HeatMapMin = 0, - - # The color for cool. - # To pass a Hex color as an int, simply replace # with 0x - # (e.g. 0x00ff00 for green instead of '#00ff00') - [int] - $HeatMapCool =0x05dd00, - - # The color for hot. - # To pass a Hex color as an int, simply replace # with 0x - # (e.g. 0xff0000 for red instead of '#ff0000') - [int] - $HeatMapHot = 0xef1100 - ) - - process { - # Separate out the segments of the color, - $coolRedPart = [byte](($HeatMapCool -band 0xff0000) -shr 16) # by bitmasking and then shifting right until it's bytes - $coolGreenPart = [byte](($HeatMapCool -band 0x00ff00) -shr 8) - $coolBluePart = [byte]($HeatMapCool -band 0x0000ff) - - $hotRedPart = [byte](($HeatMapHot -band 0xff0000) -shr 16) - $hotGreenPart = [byte](($HeatMapHot -band 0x00ff00) -shr 8) - $hotBluePart = [byte]($HeatMapHot -band 0x0000ff) - "#{0:x2}{1:x2}{2:x2}" -f @( - if ($InputObject -le $HeatMapMin) - { - $coolRedPart, $coolGreenPart, $coolBluePart - } - elseif ($InputObject -ge $HeatMapMax) - { - $hotRedPart, $hotGreenPart, $hotBluePart - } else { - if ($InputObject -le $HeatMapMiddle) - { - $d = 1 - ([double]$InputObject / ($HeatMapMiddle - $HeatMapMin)) - [Byte][Math]::Min(255, $hotRedPart * $d + $coolRedPart) - [Byte][Math]::Min(255, $hotGreenPart * $d + $coolGreenPart) - [Byte][Math]::Min(255, $hotBluePart * $d + $coolBluePart) - } else - { - $d = 1 - ([double]$InputObject / ($HeatMapMax - $HeatMapMiddle)) - [Byte][Math]::Min(255, $coolRedPart * $d + $hotRedPart) - [Byte][Math]::Min(255, $coolGreenPart * $d + $hotGreenPart) - [Byte][Math]::Min(255, $coolBluePart * $d + $hotBluePart) - } - }) + $allOutput -join '' } @@ -4600,79 +4676,55 @@ To see everything Posh can do: `$posh | Get-Member - System.Type.Summary + Inheritance + + System.Type + + + + " + ... | Format-Custom -View Full # To show public and private members + ... | Format-Custom -View Public # To show public members + ... | Format-Custom -View Private # To show private members + " + + + + + + + + + $_ + TypeInheritanceControl + + + + + + + + Interfaces System.Type - '| Format-Custom -View System.Type.Full for more' - + + " + ... | Format-Custom -View Full # To show public and private members + ... | Format-Custom -View Public # To show public members + ... | Format-Custom -View Private # To show private members + " + + - - - '-' * ($Host.UI.RawUI.BufferSize.Width - 1) - - - ' ' * 1 - - - $moduleName = 'Posh' - - do { - $lm = Get-Module -Name $moduleName -ErrorAction Ignore - if (-not $lm) { continue } - if ($lm.FormatPartsLoaded) { break } - $wholeScript = @(foreach ($formatFilePath in $lm.exportedFormatFiles) { - foreach ($partNodeName in Select-Xml -LiteralPath $formatFilePath -XPath "/Configuration/Controls/Control/Name[starts-with(., '$')]") { - $ParentNode = $partNodeName.Node.ParentNode - "$($ParentNode.Name)={ - $($ParentNode.CustomControl.CustomEntries.CustomEntry.CustomItem.ExpressionBinding.ScriptBlock)}" - } - }) -join [Environment]::NewLine - New-Module -Name "${ModuleName}.format.ps1xml" -ScriptBlock ([ScriptBlock]::Create(($wholeScript + ';Export-ModuleMember -Variable *'))) | - Import-Module -Global - $onRemove = [ScriptBlock]::Create("Remove-Module '${ModuleName}.format.ps1xml'") - - if (-not $lm.OnRemove) { - $lm.OnRemove = $onRemove - } else { - $lm.OnRemove = [ScriptBlock]::Create($onRemove.ToString() + '' + [Environment]::NewLine + $lm.OnRemove) - } - $lm | Add-Member NoteProperty FormatPartsLoaded $true -Force - - } while ($false) - - -@(& ${Posh_Format-RichText} -ForegroundColor 'Verbose' -NoClear) -join '' - $_ - TypeNameControl - - - @(& ${Posh_Format-RichText} -ForegroundColor 'Verbose' ) -join '' - - - ' ' * 1 - - - - $_.BaseType -and -not $_.IsValueType - - - ':' - - - - - $_.BaseType -and -not $_.IsValueType -and $_.BaseType -ne [Object] - - BaseType - TypeBase + TypeInheritanceControl @@ -4680,7 +4732,7 @@ To see everything Posh can do: `$posh | Get-Member $_.GetInterfaces() | Sort-Object Name - TypeBase + TypeInterfaceControl @@ -4688,191 +4740,269 @@ To see everything Posh can do: `$posh | Get-Member - System.Type.Full + Public System.Type + + + " + ... | Format-Custom -View Full # To show public and private members + ... | Format-Custom -View Public # To show public members + ... | Format-Custom -View Private # To show private members + " + + + - - '-' * ($Host.UI.RawUI.BufferSize.Width - 1) - - - ' ' * 1 + + +$_ | + Add-Member NoteProperty '.View' 'Public' -PassThru -Force | + Add-Member NoteProperty '.BindingFlags' ([Reflection.BindingFlags]'Public') -Force + + + "" - $moduleName = 'Posh' - - do { - $lm = Get-Module -Name $moduleName -ErrorAction Ignore - if (-not $lm) { continue } - if ($lm.FormatPartsLoaded) { break } - $wholeScript = @(foreach ($formatFilePath in $lm.exportedFormatFiles) { - foreach ($partNodeName in Select-Xml -LiteralPath $formatFilePath -XPath "/Configuration/Controls/Control/Name[starts-with(., '$')]") { - $ParentNode = $partNodeName.Node.ParentNode - "$($ParentNode.Name)={ - $($ParentNode.CustomControl.CustomEntries.CustomEntry.CustomItem.ExpressionBinding.ScriptBlock)}" - } - }) -join [Environment]::NewLine - New-Module -Name "${ModuleName}.format.ps1xml" -ScriptBlock ([ScriptBlock]::Create(($wholeScript + ';Export-ModuleMember -Variable *'))) | - Import-Module -Global - $onRemove = [ScriptBlock]::Create("Remove-Module '${ModuleName}.format.ps1xml'") - - if (-not $lm.OnRemove) { - $lm.OnRemove = $onRemove - } else { - $lm.OnRemove = [ScriptBlock]::Create($onRemove.ToString() + '' + [Environment]::NewLine + $lm.OnRemove) - } - $lm | Add-Member NoteProperty FormatPartsLoaded $true -Force - - } while ($false) - - -@(& ${Posh_Format-RichText} -ForegroundColor 'Verbose' -NoClear) -join '' + + + $_.GetInterfaces() + + + + $_.GetInterfaces() | Sort-Object Name + + + TypeInterfaceControl $_ - TypeNameControl + TypeInheritanceControl - @(& ${Posh_Format-RichText} -ForegroundColor 'Verbose' ) -join '' + + if ($_.'.BindingFlags') { + @{Type=$_;BindingFlags="Instance,$($_.'.BindingFlags')"} + } else { + $_ + } + + TypeConstructorsControl - ' ' * 1 + + if ($_.'.BindingFlags') { + @{Type=$_;BindingFlags="Instance,$($_.'.BindingFlags')"} + } else { + $_ + } + + TypeEventsControl - - $_.BaseType -and -not $_.IsValueType -and $_.BaseType -ne [Object] - - ':' + if ($_.'.BindingFlags') { + @{Type=$_;BindingFlags="$($_.'.BindingFlags')"} + } else { + $_ + } + TypePropertiesControl - - $_.BaseType -and -not $_.IsValueType -and $_.BaseType -ne [Object] - - BaseType - TypeBase + + if ($_.'.BindingFlags') { + @{Type=$_;BindingFlags="$($_.'.BindingFlags')"} + } else { + $_ + } + + TypeMethodsControl + + + + + + + Private + + System.Type + + + + " + ... | Format-Custom -View Full # To show public and private members + ... | Format-Custom -View Public # To show public members + ... | Format-Custom -View Private # To show private members + " + + + + + + + - $_.GetInterfaces() + +$_ | + Add-Member NoteProperty '.View' 'Private' -PassThru -Force | + Add-Member NoteProperty '.BindingFlags' ([Reflection.BindingFlags]'NonPublic') -Force + - $_.GetInterfaces() | Sort-Object Name - - TypeBase + "" - $_.GetConstructors('Instance,Public') + + $_.GetInterfaces() + - [Environment]::NewLine + ('#' * 3) + ' Constructors:' + $_.GetInterfaces() | Sort-Object Name + + TypeInterfaceControl - - $_.GetConstructors('Instance,Public') - - - $_.GetConstructors('Instance,Public') - - - TypeMethodControl + $_ + TypeInheritanceControl - - $_.GetEvents('Instance,Public') - - - [Environment]::NewLine + ('#' * 3) + ' Events:' + + if ($_.'.BindingFlags') { + @{Type=$_;BindingFlags="Instance,$($_.'.BindingFlags')"} + } else { + $_ + } + TypeConstructorsControl - - $_.GetEvents('Instance,Public') - - - $_.GetEvents('Instance,Public') | Sort-Object Name + + if ($_.'.BindingFlags') { + @{Type=$_;BindingFlags="Instance,$($_.'.BindingFlags')"} + } else { + $_ + } - - TypeEventControl + TypeEventsControl - - $_.GetProperties('Static,Public') - - - [Environment]::NewLine + ('#' * 3) + ' Static Properties:' + + if ($_.'.BindingFlags') { + @{Type=$_;BindingFlags="$($_.'.BindingFlags')"} + } else { + $_ + } + TypePropertiesControl - - $_.GetProperties('Static,Public') - - - $_.GetProperties('Static,Public') | Sort-Object Name + + if ($_.'.BindingFlags') { + @{Type=$_;BindingFlags="$($_.'.BindingFlags')"} + } else { + $_ + } - - TypePropertyControl + TypeMethodsControl + + + + + + + Full + + System.Type + + + + " + ... | Format-Custom -View Full # To show public and private members + ... | Format-Custom -View Public # To show public members + ... | Format-Custom -View Private # To show private members + " + + + + + + + - $_.GetProperties('Instance,Public') + +$_ | + Add-Member NoteProperty '.View' 'Full' -PassThru -Force | + Add-Member NoteProperty '.BindingFlags' ([Reflection.BindingFlags]'Public,NonPublic') -Force + - - [Environment]::NewLine + ('#' * 3) + ' Properties:' - + "" - $_.GetProperties('Instance,Public') + + $_.GetInterfaces() + - - $_.GetProperties('Instance,Public') | Sort-Object Name + + $_.GetInterfaces() | Sort-Object Name - TypePropertyControl + TypeInterfaceControl - - $_.GetMethods('Static,Public') - - - [Environment]::NewLine + ('#' * 3) + ' Static Methods:' + $_ + TypeInheritanceControl + + + + if ($_.'.BindingFlags') { + @{Type=$_;BindingFlags="Instance,$($_.'.BindingFlags')"} + } else { + $_ + } + TypeConstructorsControl - - $_.GetMethods('Static,Public') - - - $_.GetMethods('Static,Public') | Sort-Object Name | Where-Object { -not $_.IsSpecialName } + + if ($_.'.BindingFlags') { + @{Type=$_;BindingFlags="Instance,$($_.'.BindingFlags')"} + } else { + $_ + } - - TypeMethodControl + TypeEventsControl - - $_.GetMethods('Instance,Public') - - - [Environment]::NewLine + ('#' * 3) + ' Methods:' + + if ($_.'.BindingFlags') { + @{Type=$_;BindingFlags="$($_.'.BindingFlags')"} + } else { + $_ + } + TypePropertiesControl - - $_.GetMethods('Instance,Public') - - - $_.GetMethods('Instance,Public') | Sort-Object Name | Where-Object { -not $_.IsSpecialName } + + if ($_.'.BindingFlags') { + @{Type=$_;BindingFlags="$($_.'.BindingFlags')"} + } else { + $_ + } - - TypeMethodControl + TypeMethodsControl From fac2b635e173fa84cf2570047a117a825a187a52 Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sat, 26 Aug 2023 16:57:49 -0700 Subject: [PATCH 26/41] Updating Reflection Formatting Interfaces after type (re #217, #236) --- Formatting/Reflection/System.Type.format.ps1 | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Formatting/Reflection/System.Type.format.ps1 b/Formatting/Reflection/System.Type.format.ps1 index 5c719de..77f387f 100644 --- a/Formatting/Reflection/System.Type.format.ps1 +++ b/Formatting/Reflection/System.Type.format.ps1 @@ -17,9 +17,10 @@ Write-FormatView -TypeName n/a -AsControl -Name TypeInheritanceControl -Action { $TypeGrouping = [Ordered]@{ GroupByScript = { " - ... | Format-Custom -View Full # To show public and private members - ... | Format-Custom -View Public # To show public members - ... | Format-Custom -View Private # To show private members + ... | Format-Custom -View Full # To show public and private members + ... | Format-Custom -View Public # To show public members + ... | Format-Custom -View Private # To show private members + ... | Format-Custom -View Interfaces # To show interfaces " } } @@ -54,12 +55,15 @@ foreach ($viewName in 'Public','Private','Full') { Write-FormatView -TypeName System.Type -Action { Write-FormatViewExpression -If $assignView -ScriptBlock { "" } + + Write-FormatViewExpression -ControlName TypeInheritanceControl -ScriptBlock { $_ } + Write-FormatViewExpression -If { $_.GetInterfaces() } -ScriptBlock { $_.GetInterfaces() | Sort-Object Name } -Enumerate -ControlName TypeInterfaceControl - Write-FormatViewExpression -ControlName TypeInheritanceControl -ScriptBlock { $_ } + Write-FormatViewExpression -ControlName TypeConstructorsControl -ScriptBlock { if ($_.'.BindingFlags') { @{Type=$_;BindingFlags="Instance,$($_.'.BindingFlags')"} From 4e1cd5af0c9b7dbeec9bd020dc132bc892396355 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sat, 26 Aug 2023 23:58:48 +0000 Subject: [PATCH 27/41] Updating Reflection Formatting Interfaces after type (re #217, #236) --- Posh.format.ps1xml | 59 +++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/Posh.format.ps1xml b/Posh.format.ps1xml index b6f0fc0..dfb46ef 100644 --- a/Posh.format.ps1xml +++ b/Posh.format.ps1xml @@ -4683,9 +4683,10 @@ To see everything Posh can do: `$posh | Get-Member " - ... | Format-Custom -View Full # To show public and private members - ... | Format-Custom -View Public # To show public members - ... | Format-Custom -View Private # To show private members + ... | Format-Custom -View Full # To show public and private members + ... | Format-Custom -View Public # To show public members + ... | Format-Custom -View Private # To show private members + ... | Format-Custom -View Interfaces # To show interfaces " @@ -4711,9 +4712,10 @@ To see everything Posh can do: `$posh | Get-Member " - ... | Format-Custom -View Full # To show public and private members - ... | Format-Custom -View Public # To show public members - ... | Format-Custom -View Private # To show private members + ... | Format-Custom -View Full # To show public and private members + ... | Format-Custom -View Public # To show public members + ... | Format-Custom -View Private # To show private members + ... | Format-Custom -View Interfaces # To show interfaces " @@ -4747,9 +4749,10 @@ To see everything Posh can do: `$posh | Get-Member " - ... | Format-Custom -View Full # To show public and private members - ... | Format-Custom -View Public # To show public members - ... | Format-Custom -View Private # To show private members + ... | Format-Custom -View Full # To show public and private members + ... | Format-Custom -View Public # To show public members + ... | Format-Custom -View Private # To show private members + ... | Format-Custom -View Interfaces # To show interfaces " @@ -4768,6 +4771,10 @@ $_ | "" + + $_ + TypeInheritanceControl + @@ -4780,10 +4787,6 @@ $_ | TypeInterfaceControl - - $_ - TypeInheritanceControl - if ($_.'.BindingFlags') { @@ -4837,9 +4840,10 @@ $_ | " - ... | Format-Custom -View Full # To show public and private members - ... | Format-Custom -View Public # To show public members - ... | Format-Custom -View Private # To show private members + ... | Format-Custom -View Full # To show public and private members + ... | Format-Custom -View Public # To show public members + ... | Format-Custom -View Private # To show private members + ... | Format-Custom -View Interfaces # To show interfaces " @@ -4858,6 +4862,10 @@ $_ | "" + + $_ + TypeInheritanceControl + @@ -4870,10 +4878,6 @@ $_ | TypeInterfaceControl - - $_ - TypeInheritanceControl - if ($_.'.BindingFlags') { @@ -4927,9 +4931,10 @@ $_ | " - ... | Format-Custom -View Full # To show public and private members - ... | Format-Custom -View Public # To show public members - ... | Format-Custom -View Private # To show private members + ... | Format-Custom -View Full # To show public and private members + ... | Format-Custom -View Public # To show public members + ... | Format-Custom -View Private # To show private members + ... | Format-Custom -View Interfaces # To show interfaces " @@ -4948,6 +4953,10 @@ $_ | "" + + $_ + TypeInheritanceControl + @@ -4960,10 +4969,6 @@ $_ | TypeInterfaceControl - - $_ - TypeInheritanceControl - if ($_.'.BindingFlags') { From dfb646f79adf0dd8918330fbf790458a612d3974 Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sat, 26 Aug 2023 17:00:05 -0700 Subject: [PATCH 28/41] Updating Posh Demo (Fixes #237) --- Demos/Posh.demo.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Demos/Posh.demo.ps1 b/Demos/Posh.demo.ps1 index 7a0cb33..00f9b4b 100644 --- a/Demos/Posh.demo.ps1 +++ b/Demos/Posh.demo.ps1 @@ -62,13 +62,13 @@ Get-Command | Get-Member # To see _everything_ about an object, use something like -[int] | Format-Custom -View System.Type.Full +[int] | Format-Custom -View Public # This also works for generic types. [Collections.Generic.Dictionary[string, PSObject]] | - Format-Custom -View System.Type.Full + Format-Custom -View Public #2.5 Colorized XML From 5a3bf2f0f2827e4cf908d36f0b8f25241b71adc5 Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sat, 26 Aug 2023 17:02:54 -0700 Subject: [PATCH 29/41] Updating Feature Request Template (Fixes #199) --- .github/ISSUE_TEMPLATE/FeatureRequest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/FeatureRequest.yml b/.github/ISSUE_TEMPLATE/FeatureRequest.yml index 99a9aaf..d62b003 100644 --- a/.github/ISSUE_TEMPLATE/FeatureRequest.yml +++ b/.github/ISSUE_TEMPLATE/FeatureRequest.yml @@ -1,6 +1,6 @@ name: Feature Request description: Request a Feature -title: "" +title: "Request - " labels: ["enhancement"] body: - type: markdown From 2ecde355c9d8c6408ffafd5ac0e31a3b896c183f Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sat, 26 Aug 2023 17:31:38 -0700 Subject: [PATCH 30/41] Updating Posh.RSS.Article.Name (Fixes #229) --- Types/Posh.RSS.Article/get_Name.ps1 | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Types/Posh.RSS.Article/get_Name.ps1 b/Types/Posh.RSS.Article/get_Name.ps1 index 3001502..221ab2c 100644 --- a/Types/Posh.RSS.Article/get_Name.ps1 +++ b/Types/Posh.RSS.Article/get_Name.ps1 @@ -4,8 +4,15 @@ .DESCRIPTION Gets the name of an article in an RSS feed. #> -if ($this.Title -isnot [string]) { - $this.Title.InnerText -} else { +if ($this.Title -and $this.Title -isnot [string]) { + if ($this.Title.InnerText) { + $this.Title.InnerText + } elseif ($this.Title -is [object[]]) { + $this.Title | Select-Object -Unique -First 1 + } +} elseif ($this.Title) { $this.Title +} elseif ($this.URL) { + $thisURI = $this.URL -as [uri] + $thisURI.Segments[-1] -replace '-', ' ' } \ No newline at end of file From 45d4d7a5c9f0a6fa4db5decc31fa25c785bee403 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sun, 27 Aug 2023 00:32:32 +0000 Subject: [PATCH 31/41] Updating Posh.RSS.Article.Name (Fixes #229) --- Posh.types.ps1xml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Posh.types.ps1xml b/Posh.types.ps1xml index 0a3eb88..e1764bf 100644 --- a/Posh.types.ps1xml +++ b/Posh.types.ps1xml @@ -2284,10 +2284,17 @@ else { .DESCRIPTION Gets the name of an article in an RSS feed. #> -if ($this.Title -isnot [string]) { - $this.Title.InnerText -} else { +if ($this.Title -and $this.Title -isnot [string]) { + if ($this.Title.InnerText) { + $this.Title.InnerText + } elseif ($this.Title -is [object[]]) { + $this.Title | Select-Object -Unique -First 1 + } +} elseif ($this.Title) { $this.Title +} elseif ($this.URL) { + $thisURI = $this.URL -as [uri] + $thisURI.Segments[-1] -replace '-', ' ' } From 5def8b902b6cc507548276f55d770936cb8086c0 Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sat, 26 Aug 2023 17:37:53 -0700 Subject: [PATCH 32/41] Adding Posh.Host.Choose (Fixes #131) --- Types/Posh.Host/Choose.ps1 | 84 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 Types/Posh.Host/Choose.ps1 diff --git a/Types/Posh.Host/Choose.ps1 b/Types/Posh.Host/Choose.ps1 new file mode 100644 index 0000000..7555830 --- /dev/null +++ b/Types/Posh.Host/Choose.ps1 @@ -0,0 +1,84 @@ +<# +.SYNOPSIS + Prompts a choice +.DESCRIPTION + Prompts a choice between multiple options. + + An option can be a string, hashtable, or scriptblock. + + Hashtables keys and arrays will become a list of possible choices. + + Strings will be outputted as a message. + + A boolean will indicate multiple items can be chosen. +.Example + $Posh.Host.Choose( + "Cake Or Death?", + @("Cake", "Death") + ) +#> +param() + +$captionAndMessage = @() + +$choiceList = @() + +$defaultChoices = @() + +$multiselect = $false + +foreach ($argument in $args) { + if ($argument -is [string]) { + $captionAndMessage += $argument + } + if ($argument -is [bool] -and $argument) { + $multiselect = $true + } + + if ($argument -is [Collections.IDictionary]) { + if ($argument -is [hashtable]) { + $choiceList += @($argument.GetEnumerator() | Sort-Object Key).Key + } else { + $choiceList += @($argument.GetEnumerator()).Key + } + } elseif ($argument -is [object[]]) { + if ($argument -as [int[]]) { + $defaultChoices += $argument + } else { + $choiceList += $argument + } + } +} + +$choiceList = @( + foreach ($potentialChoice in $choiceList) { + [Management.Automation.Host.ChoiceDescription]::new("$potentialChoice") + } +) + +if (-not $choiceList) { return } + + +$caption, $message = $captionAndMessage +if ($defaultChoices) { + if (-not $multiselect) { + $defaultChoices = $defaultChoices[0] + $choice = $host.UI.PromptForChoice($caption, $message, $choiceList, $defaultChoices) + } else { + $choice = $host.UI.PromptForChoice($caption, $message, $choiceList, $defaultChoices) + } + +} else { + $choice = + if ($multiselect) { + $host.UI.PromptForChoice($caption, $message, $choiceList, [int[]]@(0)) + } else { + $host.UI.PromptForChoice($caption, $message, $choiceList, 0) + } + +} + +if ($choice -ne -1) { + $choiceList[$choice].Label +} + From fe3f2135077466203386dbbf04c02a17735b6c33 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sun, 27 Aug 2023 00:39:31 +0000 Subject: [PATCH 33/41] Adding Posh.Host.Choose (Fixes #131) --- Posh.types.ps1xml | 90 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/Posh.types.ps1xml b/Posh.types.ps1xml index e1764bf..3b6a16f 100644 --- a/Posh.types.ps1xml +++ b/Posh.types.ps1xml @@ -958,6 +958,96 @@ $this.All | Get-Random Posh.Host + + Choose + + Height From 85bccb9daf4ae5812238a2d819c985465c4dbe99 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sun, 27 Aug 2023 00:39:45 +0000 Subject: [PATCH 34/41] Adding Posh.Host.Choose (Fixes #131) --- docs/Posh.Host.Choose.md | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 docs/Posh.Host.Choose.md diff --git a/docs/Posh.Host.Choose.md b/docs/Posh.Host.Choose.md new file mode 100644 index 0000000..290f839 --- /dev/null +++ b/docs/Posh.Host.Choose.md @@ -0,0 +1,43 @@ +Posh.Host.Choose() +------------------ + + + + +### Synopsis +Prompts a choice + + + +--- + + +### Description + +Prompts a choice between multiple options. + +An option can be a string, hashtable, or scriptblock. + +Hashtables keys and arrays will become a list of possible choices. + +Strings will be outputted as a message. + +A boolean will indicate multiple items can be chosen. + + + +--- + + +### Examples +#### EXAMPLE 1 +```PowerShell +$Posh.Host.Choose( + "Cake Or Death?", + @("Cake", "Death") +) +``` + + + +--- From 01f7585098e4629064e3188d19914e40997339da Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sun, 27 Aug 2023 12:33:08 -0700 Subject: [PATCH 35/41] Adding Posh.Link.Play control (Fixes #241) --- Formatting/Posh/Posh.LinkControl.format.ps1 | 24 ++++++++------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/Formatting/Posh/Posh.LinkControl.format.ps1 b/Formatting/Posh/Posh.LinkControl.format.ps1 index d890f58..cfe07d2 100644 --- a/Formatting/Posh/Posh.LinkControl.format.ps1 +++ b/Formatting/Posh/Posh.LinkControl.format.ps1 @@ -17,22 +17,16 @@ Write-FormatView -TypeName n/a -Name "Posh.Link" -AsControl -Action { ) -join '' } -Write-FormatView -TypeName n/a -Name "Posh.Link.Line" -AsControl -Action { +Write-FormatView -TypeName n/a -Name "Posh.Link.Play" -AsControl -Action { @( - if ($_.Name -and $_.Url) { - if ($psStyle.FormatHyperlink -and -not $env:GITHUB_WORKSPACE) { - $psStyle.FormatHyperlink($_.Name, $_.Url) - } else { - "[$($_.Name)]($($_.Url))" - } - } elseif ($_.Url) { - $uri = [uri]$_.Url - if ($psStyle.FormatHyperlink -and -not $env:GITHUB_WORKSPACE) { - $psStyle.FormatHyperlink($_.Url, $uri) - } else { - "[$($_.Url)]($($uri))" - } + if ($_.enclosure.url -and + $psStyle.FormatHyperlink -and -not $env:GITHUB_WORKSPACE) { + " $($psStyle.FormatHyperlink("▶", $_.enclosure.url)) " } - [Environment]::NewLine ) -join '' +} + +Write-FormatView -TypeName n/a -Name "Posh.Link.Line" -AsControl -Action { + Write-FormatViewExpression -ControlName Posh.Link -ScriptBlock { $_ } + Write-FormatViewExpression -Newline } \ No newline at end of file From 743cc90ed791aab2d3b41f8b5f724f6b6888f0fa Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sun, 27 Aug 2023 19:34:22 +0000 Subject: [PATCH 36/41] Adding Posh.Link.Play control (Fixes #241) --- Posh.format.ps1xml | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/Posh.format.ps1xml b/Posh.format.ps1xml index dfb46ef..51e6f08 100644 --- a/Posh.format.ps1xml +++ b/Posh.format.ps1xml @@ -124,7 +124,7 @@ $script:TreeDepth++; - Posh.Link.Line + Posh.Link.Play @@ -132,21 +132,10 @@ $script:TreeDepth++; @( - if ($_.Name -and $_.Url) { - if ($psStyle.FormatHyperlink -and -not $env:GITHUB_WORKSPACE) { - $psStyle.FormatHyperlink($_.Name, $_.Url) - } else { - "[$($_.Name)]($($_.Url))" - } - } elseif ($_.Url) { - $uri = [uri]$_.Url - if ($psStyle.FormatHyperlink -and -not $env:GITHUB_WORKSPACE) { - $psStyle.FormatHyperlink($_.Url, $uri) - } else { - "[$($_.Url)]($($uri))" - } + if ($_.enclosure.url -and + $psStyle.FormatHyperlink -and -not $env:GITHUB_WORKSPACE) { + " $($psStyle.FormatHyperlink("▶", $_.enclosure.url)) " } - [Environment]::NewLine ) -join '' @@ -155,6 +144,22 @@ $script:TreeDepth++; + + Posh.Link.Line + + + + + + $_ + Posh.Link + + + + + + + Posh.Tip.Control From c8cba25f3e89bc493ea5863b5980c4ebaa1175da Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sun, 27 Aug 2023 12:34:52 -0700 Subject: [PATCH 37/41] Updating Posh.RSS.Article Formatting (Fixes #239 Fixes #240) --- Formatting/Posh/Posh.RSS.Article.format.ps1 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Formatting/Posh/Posh.RSS.Article.format.ps1 b/Formatting/Posh/Posh.RSS.Article.format.ps1 index 2d6671c..87c9c57 100644 --- a/Formatting/Posh/Posh.RSS.Article.format.ps1 +++ b/Formatting/Posh/Posh.RSS.Article.format.ps1 @@ -1,5 +1,10 @@ Write-FormatView -TypeName Posh.RSS.Article -Action { - Write-FormatViewExpression -ScriptBlock { $_ } -ControlName Posh.Link + Write-FormatViewExpression -ScriptBlock { $_ } -ControlName Posh.Link + Write-FormatViewExpression -If { $_.DatePublished -is [datetime] } -ScriptBlock { + " ($($_.DatePublished.ToShortDateString())) " + } + Write-FormatViewExpression -If { $_.Enclosure } -ScriptBlock { $_ } -ControlName Posh.Link.Play + } -GroupByProperty Source Write-FormatView -TypeName Posh.RSS.Article -Property Title, Link \ No newline at end of file From 13f0fde19ce0df30a15dbb8b65010a705969dbb9 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sun, 27 Aug 2023 19:36:17 +0000 Subject: [PATCH 38/41] Updating Posh.RSS.Article Formatting (Fixes #239 Fixes #240) --- Posh.format.ps1xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Posh.format.ps1xml b/Posh.format.ps1xml index 51e6f08..da89cb9 100644 --- a/Posh.format.ps1xml +++ b/Posh.format.ps1xml @@ -4436,6 +4436,21 @@ To see everything Posh can do: `$posh | Get-Member $_ Posh.Link + + + $_.DatePublished -is [datetime] + + + " ($($_.DatePublished.ToShortDateString())) " + + + + + $_.Enclosure + + $_ + Posh.Link.Play + From d6079b7649a01a35cda71445c02b51aadf05037d Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sun, 27 Aug 2023 12:42:41 -0700 Subject: [PATCH 39/41] Updating Tests (avoiding Get-FormatData) --- Tests/Posh.tests.ps1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Tests/Posh.tests.ps1 b/Tests/Posh.tests.ps1 index 030027a..e49a38b 100644 --- a/Tests/Posh.tests.ps1 +++ b/Tests/Posh.tests.ps1 @@ -1,7 +1,9 @@ describe Posh { context "Improving the shell experience" { it "Formats itself" { - Get-FormatData -TypeName Posh + (Get-Module -Name Posh).ExportedFormatFiles | + Select-Xml -path { $_ } -xpath '//TypeName' | + Where-Object { $_.Node.InnerText -eq 'Posh' } } it "Adds .Tip(s) to every module" { (Get-TypeData -TypeName PSModuleInfo).Members.Tip | Should -Not -BeNullOrEmpty From fa476483453e817837ac6e85f0eb54a803e1ce85 Mon Sep 17 00:00:00 2001 From: James Brundage <@github.com> Date: Sun, 27 Aug 2023 12:46:27 -0700 Subject: [PATCH 40/41] Updating Module Version [0.1.6] and CHANGELOG Fixes #228 --- CHANGELOG.md | 14 ++++++++++++++ Posh.psd1 | 37 ++++++++++++++++--------------------- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 498f597..46c74f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +## Posh 0.1.6: Posh Reflection + +* Added multiple custom views for System.Type (#216): + * Can now view 'Inheritance', 'Interfaces', 'Public', 'Private', 'Full' + * Private methods are highlighted in red. +* New Formatting: + * System.Version (#230, #231, #232) +* New Methods: + * Adding Posh.Host.Choose (#131) +* Improving formatting for RSS Feeds (#238) +* Adding PowerShell Podcast to .News/.Links (#228) + +--- + ## Posh 0.1.5: Posh Issues and Discussions * Adding PSModuleInfo.Discussion (Fixes #212) diff --git a/Posh.psd1 b/Posh.psd1 index 494e24d..0b1fd09 100644 --- a/Posh.psd1 +++ b/Posh.psd1 @@ -1,5 +1,5 @@ @{ - ModuleVersion = '0.1.5' + ModuleVersion = '0.1.6' FormatsToProcess = 'Posh.format.ps1xml' TypesToProcess = 'Posh.types.ps1xml' RootModule = 'Posh.psm1' @@ -15,28 +15,21 @@ IconURI = 'https://raw.githubusercontent.com/StartAutomating/Posh/main/Assets/Posh.png' Tags = 'Posh', '.ps1xml', 'Format','Output','Types', 'Colorized', 'Prompt', 'Customization' ReleaseNotes = @' -## Posh 0.1.5: Posh Issues and Discussions - -* Adding PSModuleInfo.Discussion (Fixes #212) -* Adding PSModuleInfo.Issue (Fixes #137) -* Improving Issue Templates -* Adding Stefan Stanger's Blog to $Posh.News (#209) (thanks @stefanstranger) -* Adding RTPSUG Video to Posh (#213) (`$posh.Video`) - ---- - -## Posh 0.1.4: Some Posh News - -* Added .News to every module (#173) -* Populated Posh with lots of blogs (#176) - -Try $Posh.News after importing. - -Also, added tests (#204). +## Posh 0.1.6: Posh Reflection + +* Added multiple custom views for System.Type (#216): + * Can now view 'Inheritance', 'Interfaces', 'Public', 'Private', 'Full' + * Private methods are highlighted in red. +* New Formatting: + * System.Version (#230, #231, #232) +* New Methods: + * Adding Posh.Host.Choose (#131) +* Improving formatting for RSS Feeds (#238) +* Adding PowerShell Podcast to .News/.Links (#228) --- -More History in [CHANGELOG](CHANGELOG.md) +More History in [CHANGELOG](https://github.com/StartAutomating/Posh/blob/main/CHANGELOG.md) '@ } FileTypes = @{ @@ -67,6 +60,7 @@ More History in [CHANGELOG](CHANGELOG.md) 'PowerShell Guide' = 'https://PowerShellGuide.com/' 'PowerShell.Org' = 'https://powershell.org/' 'PowerShell Discord' = 'https://discord.com/invite/powershell' + 'PowerShell Podcast' = 'https://powershellpodcast.podbean.com/' 'PowerShell Project' = 'https://github.com/PowerShell/PowerShell' 'PowerShell GitHub' = 'https://github.com/topics/powershell' 'PowerShell Twitter' = 'https://twitter.com/search?q=%23PowerShell' @@ -79,7 +73,8 @@ More History in [CHANGELOG](CHANGELOG.md) } News = - @{"PowerShell Blog" = "https://devblogs.microsoft.com/powershell/feed/"}, + @{"PowerShell Blog" = "https://devblogs.microsoft.com/powershell/feed/"}, + @{"PowerShell Podcast"="https://feed.podbean.com/powershellpodcast/feed.xml"}, @{"Evotec"="https://evotec.xyz/feed/"}, @{"DBATools"="https://dbatools.io/feed/"}, @{"The Lazy Admin" = "https://lazyadmin.nl/feed/"}, From a165c6aedced1a2521e47d5d98995b583be72492 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Sun, 27 Aug 2023 19:47:42 +0000 Subject: [PATCH 41/41] Updating Module Version [0.1.6] and CHANGELOG Fixes #228 --- docs/CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 498f597..46c74f7 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,3 +1,17 @@ +## Posh 0.1.6: Posh Reflection + +* Added multiple custom views for System.Type (#216): + * Can now view 'Inheritance', 'Interfaces', 'Public', 'Private', 'Full' + * Private methods are highlighted in red. +* New Formatting: + * System.Version (#230, #231, #232) +* New Methods: + * Adding Posh.Host.Choose (#131) +* Improving formatting for RSS Feeds (#238) +* Adding PowerShell Podcast to .News/.Links (#228) + +--- + ## Posh 0.1.5: Posh Issues and Discussions * Adding PSModuleInfo.Discussion (Fixes #212)