-
-
Notifications
You must be signed in to change notification settings - Fork 802
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor Settings & Write-GitStatus function #513
Conversation
Not sure whether all these individual methods should be exposed but I'm inclined to expose them so folks can compose their Git status in their own order.
This turns out to be important when you've changed the structure of the settings. For instance, setting $GitPromptSettings.BranchColor = [consolecolor]::red doesn't work as expected because BranchColor is supposed to be a [PoshGitCellColor] object. With the strongly typed settings, the above assignement will generate an error. The assignment should be $GitPromptSettings.BranchColor.ForegroundColor = [ConsoleColor]::.
src/posh-git.psd1
Outdated
'Write-GitBranchStatus', | ||
'Write-GitIndexStatus', | ||
'Write-GitStashCount', | ||
'Write-GitWorkingDirStatus', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe get rid of Dir
in this name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about combining Write-GitIndexStatus
, Write-GitWorkingDirStatus
and Write-GitWorkingDirLocalStatus
as Write-GitFileStatus
, named in alignment with EnableFileStatus
? Then instead of checking the flag outside the function, we'd check it once inside the function and return early if appropriate.
Rename Write-GitWorkingDirLocalStatus to Write-GitWorkingDirStatusSummary Add -NoLeadingSpace parameter to individual Write-Git* functions to control output of leading space.
ModuleVersion must use semver - major.minor.patch (no fourth part). Set Prerelease to `-beta1` per instructions on https://blogs.msdn.microsoft.com/powershell/2017/12/05/prerelease-versioning-added-to-powershellget-and-powershell-gallery/ Update copyright date to 2018.
@@ -24,29 +24,60 @@ $AnsiEscape = [char]27 + "[" | |||
$ColorTranslatorType = 'System.Drawing.ColorTranslator' -as [Type] | |||
$ColorType = 'System.Drawing.Color' -as [Type] | |||
|
|||
function EscapseAnsiString([string]$AnsiString) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Allow advanced users to invoke the $scriptblock from their own prompt functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First pass of feedback... sorry I didn't take the time to review #499 a few months ago. 😬
$res | ||
} | ||
|
||
function Test-VirtualTerminalSequece([psobject]$Object) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the [psobject]
here actually do anything, or is it just a type declaration for our reference?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a type declaration to make clear this function accepts any type.
src/AnsiUtils.ps1
Outdated
if ($ColorTranslatorType) { | ||
$color = $ColorTranslatorType::FromHtml($color) | ||
if ($color -as [ConsoleColor]) { | ||
$color = [System.ConsoleColor]$color |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For my reference, is there an advantage to fully qualifying [ConsoleColor]
? We should probably be consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Slight perf improvement. PowerShell looks for [ConsoleColor] in the global namespace first, when that fails, it prepends System.
and tries again.
@@ -4,7 +4,7 @@ | |||
RootModule = 'posh-git.psm1' | |||
|
|||
# Version number of this module. | |||
ModuleVersion = '1.0.0.0' | |||
ModuleVersion = '1.0.0' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this have to change? It seems to have been helpful on bug reports to let the last .0
differentiate between cloned-from-source and actual releases, but I may be imagining that?
I guess what I'm saying is: adjusting this file is part of the release process, but we probably don't want to actually commit it. Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It definitely needs to be 1.0.0
when it is published - see https://docs.microsoft.com/en-us/powershell/gallery/psget/module/prereleasemodule.
I worry a bit about precedence order when a user has a prerelease installed and has cloned the repo. But perhaps the fact that our repo dir struct doesn't lend itself to being added to PSModulePath
works in our favor in this case.
In trying to test the precedence order with the new SemanticVersion type in PS Core, I see that it chokes on 1.0.0.0
:
14:143ms> [System.Management.Automation.SemanticVersion]'1.0.0.0'
Cannot convert value "1.0.0.0" to type "System.Management.Automation.SemanticVersion". Error: "Input string was not in a correct format."
At line:1 char:1
+ [System.Management.Automation.SemanticVersion]'1.0.0.0'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastParseTargetInvocation
[rkeithhill/refactor-write-prompt ≡] ~\GitHub\dahlbyk\posh-git
15:96ms> [System.Management.Automation.SemanticVersion]'1.0.0-beta1'
Major Minor Patch PreReleas BuildLabel
eLabel
----- ----- ----- --------- ----------
1 0 0 beta1
That still doesn't mean we can't leave it at 1.0.0.0
in the repo but perhaps we should think about moving away from this strategy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wish the newer version of PowerShellGet reported the pre-release info. If it did, I'd say we leave it at 1.0.0
and set the Prerelease
private data field to alpha0
. That would imply we would want to bump the patch to 1.0.1
right after release so that a local/cloned 1.0.1-alpha0
would load ahead of 1.0.0
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue template includes PreReleaseVersion
, so as long as that's something dev-ish we should be fine. 1.0.0-dev
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't -dev
sort after -alpha
and -beta
in semver 1? That's why I suggested alpha0
for the checked in version of the psd1 file. Or we could just make that alpha
since alpha
sorts before alpha0
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess my thought was that a local version should always take precedence over a packaged version, but I suppose an actual prerelease of 1.0.1 should take priority over the first commit on the way to 1.0.1? Really not worth overthinking...
But since overthinking is fun, the SemVer 1.0.0 spec says:
A pre-release version number MAY be denoted by appending an arbitrary string immediately following the patch version and a dash. The string MUST be comprised of only alphanumerics plus dash [0-9A-Za-z-]. Pre-release versions satisfy but have a lower precedence than the associated normal version. Precedence SHOULD be determined by lexicographic ASCII sort order. For instance: 1.0.0-alpha1 < 1.0.0-beta1 < 1.0.0-beta2 < 1.0.0-rc1 < 1.0.0.
So, a PreReleaseVersion
of -0
seems to have the absolute lowest precedence, but I'm fine with -alpha
/-beta
(no number) indicating dev versions and actual prereleases of -alpha0
, -alpha1
, -beta0
, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to set it to alpha
. According to docs (and peeking at PSReadline beta) the -
prefix is not required.
src/GitPrompt.ps1
Outdated
BeforeBackgroundColor = $null | ||
class PoshGitCellColor { | ||
[psobject]$BackgroundColor | ||
[psobject]$ForegroundColor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the class is named Color, thoughts on renaming to Background
/Foreground
to make our code less noisy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went back and forth on this one. Even though the class has the name color in it, when it comes to using it in Intellisense (or reading it), what matters is the name of the property that is of type [PoshGitCellColor]
. I was also channeling CSS a bit - background-color
and foreground-color
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made this comment before I had reviewed most of the code. We don't refer to these properties by name that much, so let's leave them.
src/GitPrompt.ps1
Outdated
BeforeText = ' [' | ||
BeforeForegroundColor = [ConsoleColor]::Yellow | ||
BeforeBackgroundColor = $null | ||
class PoshGitCellColor { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these supporting types live in a separate file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure could. I was just following my perception that we tend to group related things (i.e. multiple functions) into a single script file. GitPrompt.ps1 is the only place these classes are used. But I have no problem breaking them out into separate script files. Would we want a single file for all the classes or class per file? BTW I believe there is a small module startup perf hit the more files you dot source.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do tend to group related things, and I don't have concrete intuition for how big is too big. I guess my gut says including them here is too big, but it's not worth having a file per. Maybe PoshGitTypes.ps1
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good. I'll make it so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/GitPrompt.ps1
Outdated
$sb | Write-WorkingDirectoryStatus $Status > $null | ||
} | ||
|
||
$sb | Write-WorkingDirectoryLocalStatus $Status > $null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be a change in behavior, but it doesn't make sense to call this if EnableFileStatus
is off.
System.Management.Automation.PSCustomObject | ||
This is PSCustomObject returned by Get-GitStatus | ||
.OUTPUTS | ||
PoshGitTextSpan |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this return a PoshGitCellColor
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This points out a bit of a flaw where [PoshGitTextSpan]
allows the user to specify a custom ANSI seq but [PoshGitCellColor]
doesn't. That sequence is output before the text span's Text
and we automatically close the seq with ${esc}[0m
. The use of a custom ANSI seq renders Fg/BgColor unused. So if you want to control both, make sure both are set in the ANSI seq.
[PoshGitCellColor]
color doesn't have a $CusomAnsi
property and perhaps it should. If so, then yeah, this function should return [PoshGitCellColor]
. Without that support, I didn't want to lose any custom ANSI the user may have specified in the various Branch*StatusSymbol
properties (which are of type [PoshGitTextSpan]
).
src/GitPrompt.ps1
Outdated
@@ -415,146 +575,323 @@ function Write-BranchStatus { | |||
|
|||
$str = "" | |||
if ($branchStatusTextSpan.Text) { | |||
$textSpan = [PoshGitTextSpan]::new($branchStatusTextSpan) | |||
$textSpan.Text = " " + $branchStatusTextSpan.Text |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still strikes me as a bit awkward. Could we teach Write-Prompt
to understand -Prefix ' '
or something?
src/posh-git.psd1
Outdated
'Write-GitBranchStatus', | ||
'Write-GitIndexStatus', | ||
'Write-GitStashCount', | ||
'Write-GitWorkingDirStatus', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about combining Write-GitIndexStatus
, Write-GitWorkingDirStatus
and Write-GitWorkingDirLocalStatus
as Write-GitFileStatus
, named in alignment with EnableFileStatus
? Then instead of checking the flag outside the function, we'd check it once inside the function and return early if appropriate.
src/GitPrompt.ps1
Outdated
[bool]$AnsiConsole = $Host.UI.SupportsVirtualTerminal -or ($Env:ConEmuANSI -eq "ON") | ||
|
||
[PoshGitCellColor]$DefaultColor = [PoshGitCellColor]::new() | ||
[PoshGitCellColor]$BranchColor = [PoshGitCellColor]::new([ConsoleColor]::Cyan) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are PowerShell classes able to define type coersion? Would be handy to be able to assign [ConsoleColor]::Cyan
here and have it automatically convert to a foreground-only color.
PS Prompt wants a single string - not an array of strings. Address PR feedback on using PoshGitTextSpan in error handler.
The more I think on this, the more I'm convinced $workingText = " $($s.FileAddedText)$($status.Working.Added.Count)"
$sb | Write-Prompt $s.WorkingColor $workingText > $null Instead of this: $workingTextSpan = [PoshGitTextSpan]::new($s.WorkingColor)
$workingTextSpan.Text = " $($s.FileAddedText)$($status.Working.Added.Count)"
$sb | Write-Prompt $workingTextSpan > $null |
Or we could just add another parameter set to Write-Prompt that takes a $workingText = " $($s.FileAddedText)$($status.Working.Added.Count)"
$sb | Write-Prompt $workingText $s.WorkingColor > $null |
src/GitPrompt.ps1
Outdated
} | ||
} | ||
|
||
$sb.ToString() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I may be oversimplifying, but isn't this the same as:
$OFS = ""
"$($global:VcsPromptStatuses | ForEach-Object { & $_ })"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not. I was following the pattern we'd established in Write-Git*Status methods. Just thinking of the case where AnsiConsole is disabled - that should write to the host and not return anything (or empty strings) and those should concat to an empty string. So yeah, that should work. Want me to change this (and test it)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I'm all for less code. 99.99+% of the time there's a single status function with a single result.
src/PoshGitTypes.ps1
Outdated
|
||
[PoshGitTextSpan]$LocalDefaultStatusSymbol = [PoshGitTextSpan]::new('', [ConsoleColor]::DarkGreen) | ||
[PoshGitTextSpan]$LocalWorkingStatusSymbol = [PoshGitTextSpan]::new('!', [ConsoleColor]::DarkRed) | ||
[PoshGitTextSpan]$LocalStagedStatusSymbol = [PoshGitTextSpan]::new('~', [ConsoleColor]::DarkCyan) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case you missed the comment on an outdated line: was this deliberately changed from Cyan
to DarkCyan
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like that was in the very first commit I made back on 10/28. I honestly don't remember. I wonder if my color scheme was having issues with Cyan that day? In my current scheme (OneHalfDark) I can't see any diff between Cyan and DarkCyan. Want me to change it back to Cyan
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Also redo column alignment that got reset after paste into new file.
This is a weird one. I only found it by debugging the script. While `"Black" -as [ConsoleColor]` returns `System.ConsoleColor.Black`, that doesn't cause the `if` condition to be true. Ah, the issue is that the enum value for Black is 0. Doh!
This cleaned up a number of the Write-Git*Status functions a bit. Fixed bug in Write-GitStashCount where we were incorrectly redirecting the $str assignments to $null.
I think I've addressed most (all?) of the concerns so far. So where are we at with this one? |
I'll rebase this tonight, which should identify any remaining feedback. |
This builds on PR #499 (refactor settings) by refactoring
Write-GitStatus
into several smaller parts that can be called individually.Also of interest is the added support for 24-bit color e.g. `$GitPromptSettings.BranchColor.ForegroundColor = 0xFFA000
@dahlbyk At the very least, we should consider applying the part that adds support for 24-bit color and move ConsoleColor strings ahead of HTML color strings. PS Core 6.0.0 GA is set for mid-January. It would be nice to at least get a beta of posh-git 1.0.0 into the PSGallery.. Oh yeah, PSGallery finally supports pre-release modules - https://blogs.msdn.microsoft.com/powershell/2017/12/05/prerelease-versioning-added-to-powershellget-and-powershell-gallery/
NOTE: this PR and #499 uses PS classes for perf reasons (using Add-Type C# code was too slow on Linux) so we would need to set the min PS version in the PSD1 file to 5.0. I think this would be OK if we pitch this release as primarily support for PS Core and PS on Windows 10 conhost w/VT seq functionality.