Skip to content

Commit 7348f13

Browse files
committed
Fix that exported variable
1 parent 495948d commit 7348f13

File tree

4 files changed

+166
-63
lines changed

4 files changed

+166
-63
lines changed

Source/Assembly/Commands/ExpandVariableCommand.cs

Lines changed: 72 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -9,91 +9,114 @@
99

1010
namespace PoshCode.Pansies.Commands
1111
{
12-
13-
14-
[Cmdlet("Expand","Variable")]
12+
[Cmdlet("Expand", "Variable", DefaultParameterSetName = "Content")]
1513
public class ExpandVariableCommand : PSCmdlet
1614
{
17-
[Parameter(Mandatory = true, Position = 0)]
15+
[Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")]
16+
[Alias("PSPath")]
1817
public string Path { get; set; }
1918

19+
[Parameter(Mandatory = true, ValueFromPipeline = true, ParameterSetName = "Content")]
20+
public string Content { get; set; }
21+
2022
[Parameter()]
2123
public SwitchParameter Unescaped { get; set; }
2224

2325
[Parameter()]
2426
public string[] Drive { get; set; } = ["bg", "emoji", "esc", "extra", "fg", "nf"];
2527

26-
[Parameter()]
28+
[Parameter(ParameterSetName = "Path")]
2729
public SwitchParameter InPlace { get; set; }
2830

29-
protected override void EndProcessing()
31+
[Parameter(ParameterSetName = "Path")]
32+
public SwitchParameter Passthru { get; set; }
33+
34+
protected override void ProcessRecord()
3035
{
36+
if (ParameterSetName == "Content")
37+
{
38+
var result = ExpandVariable(Content, "Content");
39+
WriteObject(result);
40+
return;
41+
}
42+
3143
var resolvedProviderPath = GetResolvedProviderPathFromPSPath(Path, out ProviderInfo provider);
32-
foreach (var file in resolvedProviderPath) {
33-
var result = new StringBuilder();
34-
var replacements = new List<TextReplacement>();
35-
Ast ast = null;
36-
string code;
44+
foreach (var file in resolvedProviderPath)
45+
{
3746
string fullName = file;
3847
if (provider.Name != "Variable" && provider.Name != "FileSystem" && !fullName.Contains(":"))
3948
{
4049
fullName = $"{provider.Name}:{file}";
4150
}
42-
code = GetVariableValue(fullName).ToString();
43-
ast = Parser.ParseInput(code, fullName, out var tokens, out var parseErrors);
44-
if (parseErrors.Length > 0) {
45-
WriteError(new ErrorRecord(new Exception($"{parseErrors.Length} Parse Errors in {fullName}, cannot expand."), "ParseErrors", ErrorCategory.InvalidOperation, fullName));
46-
continue;
47-
}
48-
result.AppendLine(code);
49-
50-
var variables = ast.FindAll(a => a is VariableExpressionAst, true).
51-
Cast<VariableExpressionAst>().
52-
Where(v => (!v.VariablePath.IsUnqualified || // variable:foo is IsUnqualified = False and IsVariable = True
53-
v.VariablePath.IsDriveQualified) && // fg:red is IsDriveQualified = True and IsVariable = False
54-
Drive.Contains(v.VariablePath.DriveName ?? "variable", StringComparer.OrdinalIgnoreCase));
51+
string code = GetVariableValue(fullName).ToString();
52+
var result = ExpandVariable(code, fullName);
5553

56-
foreach (var variable in variables)
54+
if (result != null)
5755
{
58-
try
56+
if (InPlace)
5957
{
60-
var replacement = GetVariableValue(variable.VariablePath.UserPath).ToString();
61-
if (!Unescaped)
62-
{
63-
replacement = replacement.ToPsEscapedString();
64-
}
65-
if (variable.Parent is ExpandableStringExpressionAst)
58+
SessionState.PSVariable.Set(fullName, result);
59+
if (Passthru)
6660
{
67-
replacements.Add(new TextReplacement(replacement, variable.Extent));
68-
}
69-
else
70-
{
71-
replacements.Add(new TextReplacement('"' + replacement + '"', variable.Extent));
61+
WriteObject(SessionState.InvokeProvider.Item.Get(fullName), true);
7262
}
7363
}
74-
catch
64+
else
7565
{
76-
WriteWarning($"VariableNotFound: '{variable.VariablePath.UserPath}' at {fullName}:{variable.Extent.StartLineNumber}:{variable.Extent.StartColumnNumber}");
77-
continue;
66+
WriteObject(result);
7867
}
7968
}
69+
}
70+
}
8071

81-
foreach (var replacement in replacements.OrderByDescending(r => r.StartOffset))
82-
{
83-
result.Remove(replacement.StartOffset, replacement.Length).Insert(replacement.StartOffset, replacement.Text);
84-
}
72+
private string ExpandVariable(string code, string fullName = null)
73+
{
74+
var builder = new StringBuilder(code);
75+
var replacements = new List<TextReplacement>();
76+
Ast ast = null;
77+
ast = Parser.ParseInput(code, fullName, out var tokens, out var parseErrors);
78+
if (parseErrors.Length > 0)
79+
{
80+
WriteError(new ErrorRecord(new Exception($"{parseErrors.Length} Parse Errors in {fullName}, cannot expand."), "ParseErrors", ErrorCategory.InvalidOperation, fullName));
81+
return null;
82+
}
83+
84+
var variables = ast.FindAll(a => a is VariableExpressionAst, true).
85+
Cast<VariableExpressionAst>().
86+
Where(v => (!v.VariablePath.IsUnqualified || // variable:foo is IsUnqualified = False and IsVariable = True
87+
v.VariablePath.IsDriveQualified) && // fg:red is IsDriveQualified = True and IsVariable = False
88+
Drive.Contains(v.VariablePath.DriveName ?? "variable", StringComparer.OrdinalIgnoreCase));
8589

86-
if (InPlace)
90+
foreach (var variable in variables)
91+
{
92+
try
8793
{
88-
SessionState.PSVariable.Set(fullName, result.ToString());
94+
var replacement = GetVariableValue(variable.VariablePath.UserPath).ToString();
95+
if (!Unescaped)
96+
{
97+
replacement = replacement.ToPsEscapedString();
98+
}
99+
if (variable.Parent is ExpandableStringExpressionAst)
100+
{
101+
replacements.Add(new TextReplacement(replacement, variable.Extent));
102+
}
103+
else
104+
{
105+
replacements.Add(new TextReplacement('"' + replacement + '"', variable.Extent));
106+
}
89107
}
90-
else
108+
catch
91109
{
92-
WriteObject(result.ToString());
110+
WriteWarning($"VariableNotFound: '{variable.VariablePath.UserPath}' at {fullName}:{variable.Extent.StartLineNumber}:{variable.Extent.StartColumnNumber}");
111+
continue;
93112
}
94-
95113
}
96114

115+
foreach (var replacement in replacements.OrderByDescending(r => r.StartOffset))
116+
{
117+
builder.Remove(replacement.StartOffset, replacement.Length).Insert(replacement.StartOffset, replacement.Text);
118+
}
119+
return builder.ToString();
97120
}
98121

99122
private class TextReplacement(string text, IScriptExtent extent)

Source/Pansies.format.ps1xml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<SelectionSet>
1919
<Name>Grapheme</Name>
2020
<Types>
21-
<TypeName>PoshCode.Pansies.Provider.Grapheme</TypeName>
21+
<TypeName>PoshCode.Pansies.Grapheme</TypeName>
2222
</Types>
2323
</SelectionSet>
2424
</SelectionSets>
@@ -35,7 +35,7 @@
3535
<Label>Name</Label>
3636
</TableColumnHeader>
3737
<TableColumnHeader>
38-
<Label>Entity</Label>
38+
<Label>Value</Label>
3939
</TableColumnHeader>
4040
</TableHeaders>
4141
<TableRowEntries>
@@ -61,7 +61,9 @@
6161
<WideEntries>
6262
<WideEntry>
6363
<WideItem>
64-
<PropertyName>Value</PropertyName>
64+
<ScriptBlock>
65+
$_.Value + " " + $_.Name
66+
</ScriptBlock>
6567
</WideItem>
6668
</WideEntry>
6769
</WideEntries>

Source/Pansies.psm1

Lines changed: 88 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,105 @@
1+
using namespace PoshCode.Pansies
2+
using namespace PoshCode.Pansies.Palettes
3+
using namespace System.Collections.Generic
4+
using namespace System.Collections
5+
using namespace ColorMine.ColorSpaces
6+
using namespace System.Management.Automation
7+
using namespace System.Management.Automation.Language
8+
19
Import-Module $PSScriptRoot\lib\Pansies.dll
210

3-
if(-not $IsLinux) {
4-
[PoshCode.Pansies.Console.WindowsHelper]::EnableVirtualTerminalProcessing()
11+
# On first import, if HostPreference doesn't exist, set it and strongly type it
12+
if (!(Test-Path Variable:HostPreference) -or $null -eq $HostPreference) {
13+
[System.Management.Automation.ActionPreference]$global:HostPreference = "Continue"
14+
}
15+
16+
Set-Variable HostPreference -Description "Dictates the action taken when a host message is delivered" -Visibility Public -Scope Global
17+
18+
if (-not $IsLinux -and -not $IsMacOS) {
19+
[PoshCode.Pansies.NativeMethods]::EnableVirtualTerminalProcessing()
520
}
621

722
# dot source the functions
823
(Join-Path $PSScriptRoot Private\*.ps1 -Resolve -ErrorAction SilentlyContinue).ForEach{ . $_ }
924
(Join-Path $PSScriptRoot Public\*.ps1 -Resolve).ForEach{ . $_ }
1025

1126

27+
if (Get-Command Add-MetadataConverter -ErrorAction Ignore) {
28+
Add-MetadataConverter @{
29+
RgbColor = { [PoshCode.Pansies.RgbColor]$args[0] }
30+
[PoshCode.Pansies.RgbColor] = { "RgbColor '$_'" }
31+
}
32+
}
33+
34+
$Accelerators = @{
35+
"RGBColor" = [PoshCode.Pansies.RgbColor]
36+
"Entities" = [PoshCode.Pansies.Entities]
37+
}
38+
39+
# IArgumentCompleterFactory only available on PS7+
40+
if ("System.Management.Automation.IArgumentCompleterFactory" -as [type]) {
41+
Add-Type @"
42+
using System.Management.Automation;
43+
using PoshCode.Pansies.Palettes;
44+
namespace PoshCode.Pansies {
45+
public class ColorCompleterAttribute : ArgumentCompleterAttribute, IArgumentCompleterFactory {
46+
public ColorCompleterAttribute(){}
47+
public IArgumentCompleter Create() {
48+
return new X11Palette();
49+
}
50+
}
51+
}
52+
"@ -ReferencedAssemblies ([psobject].Assembly), ([PoshCode.Pansies.RgbColor].Assembly), "netstandard" -CompilerOptions "-NoWarn:1701"
53+
54+
$Accelerators["ColorCompleterAttribute"] = [PoshCode.Pansies.ColorCompleterAttribute]
55+
56+
}
57+
58+
$xlr8r = [psobject].assembly.gettype("System.Management.Automation.TypeAccelerators")
59+
$Accelerators.GetEnumerator().ForEach({
60+
$Name = $_.Key
61+
$Type = $_.Value
62+
if ($xlr8r::AddReplace) {
63+
$xlr8r::AddReplace( $Name, $Type)
64+
} else {
65+
$null = $xlr8r::Remove( $Name )
66+
$xlr8r::Add( $Name, $Type)
67+
}
68+
trap [System.Management.Automation.MethodInvocationException] {
69+
if ($xlr8r::get.keys -contains $Name) {
70+
if ($xlr8r::get[$Name] -ne $Type) {
71+
Write-Error "Cannot add accelerator [$Name] for [$($Type.FullName)]n [$Name] is already defined as [$($xlr8r::get[$Name].FullName)]"
72+
}
73+
continue;
74+
}
75+
throw
76+
}
77+
})
78+
79+
$script:X11Palette = [X11Palette]::new()
80+
$RgbColorCompleter = {
81+
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
82+
$script:X11Palette.CompleteArgument($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
83+
}
84+
85+
$global:PansiesColorCompleterRegistration = Register-EngineEvent -SourceIdentifier PowerShell.OnIdle {
86+
foreach ($command in Get-Command -ParameterType RgbColor) {
87+
foreach ($parameter in $command.Parameters.Values.Where{ $_.ParameterType -eq [RgbColor] }) {
88+
Register-ArgumentCompleter -CommandName $command.Name -ParameterName $parameter.Name -ScriptBlock $RgbColorCompleter
89+
}
90+
}
91+
Stop-Job $global:PansiesColorCompleterRegistration # This removes the event
92+
Remove-Variable PansiesColorCompleterRegistration -Scope global
93+
}
94+
95+
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingCmdletAliases', 'Pansies', Justification = 'This is an exported variable')]
1296
$Pansies = @{
13-
fg = @{}
14-
bg = @{}
97+
color = [RgbColor]::X11Palette
1598
esc = [PoshCode.Pansies.Entities]::EscapeSequences
1699
nf = [PoshCode.Pansies.Entities]::NerdFontSymbols
17100
emoji = [PoshCode.Pansies.Entities]::Emoji
18101
extra = [PoshCode.Pansies.Entities]::ExtendedCharacters
19102
}
20103

21-
Get-ChildItem Fg: | ForEach-Object {
22-
$Pansies.fg[$_.Name] = Get-Content $_
23-
}
24-
Get-ChildItem Bg: | ForEach-Object {
25-
$Pansies.bg[$_.Name] = Get-Content $_
26-
}
27104

28-
Export-ModuleMember -Variable Pansies -Function * -Cmdlet * -Alias * -Variable RgbColorCompleter
105+
Export-ModuleMember -Variable Pansies, RgbColorCompleter -Function *-* -Cmdlet * -Alias *

Source/Private/_init.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ $global:PansiesColorCompleterRegistration = Register-EngineEvent -SourceIdentifi
8585
Remove-Variable PansiesColorCompleterRegistration -Scope global
8686
}
8787

88+
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingCmdletAliases', 'Pansies', Justification = 'This is an exported variable')]
8889
$Pansies = @{
8990
color = [RgbColor]::X11Palette
9091
esc = [PoshCode.Pansies.Entities]::EscapeSequences

0 commit comments

Comments
 (0)