Skip to content

Commit

Permalink
Merge pull request #541 from dahlbyk/rkeithhill/refactor-window-title
Browse files Browse the repository at this point in the history
Improved WindowTitle customization experience
  • Loading branch information
dahlbyk authored Jan 29, 2018
2 parents 46c47d7 + 5361bc8 commit d55d962
Show file tree
Hide file tree
Showing 6 changed files with 259 additions and 35 deletions.
2 changes: 1 addition & 1 deletion PSScriptAnalyzerSettings.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# Use ExcludeRules when you want to run most of the default set of rules except
# for a few rules you wish to "exclude". Note: if a rule is in both IncludeRules
# and ExcludeRules, the rule will be excluded.
ExcludeRules = @('PSAvoidUsingWriteHost', 'PSAvoidGlobalVars')
ExcludeRules = @('PSAvoidUsingWriteHost', 'PSAvoidGlobalVars', 'PSAvoidUsingInvokeExpression')

# You can use the following entry to supply parameters to rules that take parameters.
# For instance, the PSAvoidUsingCmdletAliases rule takes a whitelist for aliases you
Expand Down
32 changes: 3 additions & 29 deletions src/GitPrompt.ps1
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Inspired by Mark Embling
# http://www.markembling.info/view/my-ideal-powershell-prompt-with-git-integration

$global:GitPromptSettings = [GitPromptSettings]::new()
$global:GitPromptSettings = [PoshGitPromptSettings]::new()

# Override some of the normal colors if the background color is set to the default DarkMagenta.
$s = $global:GitPromptSettings
Expand All @@ -13,17 +13,6 @@ if ($Host.UI.RawUI.BackgroundColor -eq [ConsoleColor]::DarkMagenta) {
$s.WorkingColor.ForegroundColor = 'Red'
}

$isAdminProcess = Test-Administrator
$adminHeader = if ($isAdminProcess) { 'Administrator: ' } else { '' }

$WindowTitleSupported = $true
# TODO: Hmm, this is a curious way to detemine window title supported
# Could do $host.Name -eq "Package Manager Host" but that is kinda specific
# Could attempt to change it and catch any exception and then set this to $false
if (Get-Module NuGet) {
$WindowTitleSupported = $false
}

<#
.SYNOPSIS
Writes the object to the display or renders it as a string using ANSI/VT sequences.
Expand Down Expand Up @@ -142,7 +131,7 @@ function Write-Prompt {
return $StringBuilder
}

return ""
""
}

<#
Expand Down Expand Up @@ -183,10 +172,6 @@ function Write-GitStatus {

$s = $global:GitPromptSettings
if (!$Status -or !$s) {
if ($global:PreviousWindowTitle) {
$Host.UI.RawUI.WindowTitle = $global:PreviousWindowTitle
}

return ""
}

Expand All @@ -198,7 +183,6 @@ function Write-GitStatus {

if ($s.EnableFileStatus -and $Status.HasIndex) {
$sb | Write-Prompt $s.BeforeIndexText > $null

$sb | Write-GitIndexStatus $Status > $null

if ($Status.HasWorking) {
Expand All @@ -218,17 +202,7 @@ function Write-GitStatus {

$sb | Write-Prompt $s.AfterText > $null

if ($WindowTitleSupported -and $s.EnableWindowTitle) {
if (!$global:PreviousWindowTitle) {
$global:PreviousWindowTitle = $Host.UI.RawUI.WindowTitle
}

$repoName = Split-Path -Leaf (Split-Path $status.GitDir)
$prefix = if ($s.EnableWindowTitle -is [string]) { $s.EnableWindowTitle } else { '' }
$Host.UI.RawUI.WindowTitle = "${script:adminHeader}${prefix}${repoName} [$($Status.Branch)]"
}

return $sb.ToString()
$sb.ToString()
}

<#
Expand Down
1 change: 1 addition & 0 deletions src/GitUtils.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ function Get-GitStatus {

$result = New-Object PSObject -Property @{
GitDir = $GitDir
RepoName = Split-Path (Split-Path $GitDir -Parent) -Leaf
Branch = $branch
AheadBy = $aheadBy
BehindBy = $behindBy
Expand Down
6 changes: 3 additions & 3 deletions src/PoshGitTypes.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ class PoshGitTextSpan {
}
}

class GitPromptSettings {
class PoshGitPromptSettings {
[bool]$AnsiConsole = $Host.UI.SupportsVirtualTerminal -or ($Env:ConEmuANSI -eq "ON")

[PoshGitCellColor]$DefaultColor = [PoshGitCellColor]::new()
Expand Down Expand Up @@ -244,8 +244,8 @@ class GitPromptSettings {
[Nullable[bool]]$EnableFileStatusFromCache = $null
[string[]]$RepositoriesInWhichToDisableFileStatus = @()

[string]$DescribeStyle = ''
[psobject]$EnableWindowTitle = 'posh~git ~ '
[string]$DescribeStyle = ''
[psobject]$WindowTitle = {param($GitStatus, [bool]$IsAdmin) "$(if ($IsAdmin) {'Administrator: '})$(if ($GitStatus) {"posh~git ~ $($GitStatus.RepoName) [$($GitStatus.Branch)] ~ "})PowerShell $($PSVersionTable.PSVersion) ($PID)"}

[PoshGitTextSpan]$DefaultPromptPrefix = ''
[PoshGitTextSpan]$DefaultPromptSuffix = '$(''>'' * ($nestedPromptLevel + 1)) '
Expand Down
54 changes: 54 additions & 0 deletions src/posh-git.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@ param([switch]$NoVersionWarn, [switch]$ForcePoshGitPrompt)
if (!$Env:HOME) { $Env:HOME = "$Env:HOMEDRIVE$Env:HOMEPATH" }
if (!$Env:HOME) { $Env:HOME = "$Env:USERPROFILE" }

$IsAdmin = Test-Administrator

# Probe $Host.UI.RawUI.WindowTitle to see if it can be set without errors
$WindowTitleSupported = $false
try {
$global:PreviousWindowTitle = $Host.UI.RawUI.WindowTitle
$newTitle = "${global:PreviousWindowTitle} "
$Host.UI.RawUI.WindowTitle = $newTitle
$WindowTitleSupported = ($Host.UI.RawUI.WindowTitle -eq $newTitle)
$Host.UI.RawUI.WindowTitle = $global:PreviousWindowTitle
}
catch {
Write-Debug "Probing for WindowTitleSupported errored: $_"
}

# Get the default prompt definition.
$initialSessionState = [Runspace]::DefaultRunspace.InitialSessionState
if (!$initialSessionState.Commands -or !$initialSessionState.Commands['prompt']) {
Expand All @@ -29,6 +44,10 @@ else {
$GitPromptScriptBlock = {
$settings = $global:GitPromptSettings
if (!$settings) {
if ($WindowTitleSupported -and $global:PreviousWindowTitle) {
$Host.UI.RawUI.WindowTitle = $global:PreviousWindowTitle
}

return "<`$GitPromptSettings not found> "
}

Expand Down Expand Up @@ -70,6 +89,36 @@ $GitPromptScriptBlock = {
$promptSuffix.Text = ' '
}

# Update the host's WindowTitle is host supports it and user has not disabled $GitPromptSettings.WindowTitle
if ($WindowTitleSupported) {
$windowTitle = $settings.WindowTitle
if (!$windowTitle) {
if ($global:PreviousWindowTitle) {
$Host.UI.RawUI.WindowTitle = $global:PreviousWindowTitle
}
}
else {
try {
if ($windowTitle -is [scriptblock]) {
$windowTitleText = & $windowTitle $global:GitStatus $IsAdmin
}
else {
$windowTitleText = $ExecutionContext.SessionState.InvokeCommand.ExpandString("$windowTitle")
}

# Put $windowTitleText in a string to ensure results returned by scriptblock are flattened to a string
$Host.UI.RawUI.WindowTitle = "$windowTitleText"
}
catch {
if ($global:PreviousWindowTitle) {
$Host.UI.RawUI.WindowTitle = $global:PreviousWindowTitle
}

Write-Debug "Error occurred during evaluation of `$GitPromptSettings.WindowTitle: $_"
}
}
}

# If prompt timing enabled, display elapsed milliseconds
if ($settings.DefaultPromptEnableTiming) {
$sw.Stop()
Expand Down Expand Up @@ -106,6 +155,11 @@ if ($ForcePoshGitPrompt -or !$currentPromptDef -or ($currentPromptDef -eq $defau
$ExecutionContext.SessionState.Module.OnRemove = {
$global:VcsPromptStatuses = $global:VcsPromptStatuses | Where-Object { $_ -ne $PoshGitVcsPrompt }

# Revert original WindowTitle
if ($WindowTitleSupported -and $global:PreviousWindowTitle) {
$Host.UI.RawUI.WindowTitle = $global:PreviousWindowTitle
}

# Check if the posh-git prompt function itself has been replaced. If so, do not restore the prompt function
$promptDef = if ($funcInfo = Get-Command prompt -ErrorAction SilentlyContinue) { $funcInfo.Definition }
if ($promptDef -eq $GitPromptScriptBlock) {
Expand Down
Loading

0 comments on commit d55d962

Please sign in to comment.