From 0fb0b9a82f0f372a223f638f42e7473bbf697b2a Mon Sep 17 00:00:00 2001 From: George Cheyne Date: Fri, 17 Aug 2018 00:39:33 +0100 Subject: [PATCH 1/5] rename tabs to match the repo and branch when in powershell ise --- src/GitPrompt.ps1 | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/GitPrompt.ps1 b/src/GitPrompt.ps1 index 70ce398c2..9550c19c9 100644 --- a/src/GitPrompt.ps1 +++ b/src/GitPrompt.ps1 @@ -209,6 +209,29 @@ function Write-GitStatus { } $sb.ToString() + + # If the user is running Powershell ISE then name the tab + if($psISE){ + $repo = $Status.RepoName + $branch = $Status.Branch + $tabName = "$repo=>$branch" + #you can't have 2 tabs with the same name so shove a number on the end + $tabCount = 0 + foreach($tab in $psISE.PowerShellTabs){ + $existingTabName = $tab.DisplayName + if($existingTabName.StartsWith($tabName) -and $existingTabName -ne $psise.CurrentPowerShellTab.DisplayName){ + $tabCount++ + $tabNumber = [int]$existingTabName.Replace($tabName, "").Replace("(", "").Replace(")", "").Trim() + if($tabCount -lt $tabNumber + 1){ + $tabCount = $tabNumber + 1 + } + } + } + if($tabCount -gt 0){ + $tabName= "$tabName ($tabCount)" + } + $psise.CurrentPowerShellTab.DisplayName = $tabName + } } <# From fc5dec14cbca684877317d8e0201b3c42d56e184 Mon Sep 17 00:00:00 2001 From: George Cheyne Date: Fri, 17 Aug 2018 00:47:11 +0100 Subject: [PATCH 2/5] I realised I wasn't following the standard convention of repo [branch]. --- src/GitPrompt.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GitPrompt.ps1 b/src/GitPrompt.ps1 index 9550c19c9..c5e70bd59 100644 --- a/src/GitPrompt.ps1 +++ b/src/GitPrompt.ps1 @@ -214,7 +214,7 @@ function Write-GitStatus { if($psISE){ $repo = $Status.RepoName $branch = $Status.Branch - $tabName = "$repo=>$branch" + $tabName = "$repo [$branch]" #you can't have 2 tabs with the same name so shove a number on the end $tabCount = 0 foreach($tab in $psISE.PowerShellTabs){ From b8d0042e86060641a0909a66d4afa1e055edf5f2 Mon Sep 17 00:00:00 2001 From: George Cheyne Date: Sat, 18 Aug 2018 12:49:03 +0100 Subject: [PATCH 3/5] refactoring the code based on comments Changes to be committed: modified: src/GitPrompt.ps1 remove the old code modified: src/PoshGitTypes.ps1 add config entry to disable tab labelling modified: src/WindowTitle.ps1 added functions to label tabs modified: src/posh-git.psm1 added call to tab labelling code --- src/GitPrompt.ps1 | 23 ----------------------- src/PoshGitTypes.ps1 | 2 ++ src/WindowTitle.ps1 | 42 ++++++++++++++++++++++++++++++++++++++++++ src/posh-git.psm1 | 1 + 4 files changed, 45 insertions(+), 23 deletions(-) diff --git a/src/GitPrompt.ps1 b/src/GitPrompt.ps1 index c5e70bd59..70ce398c2 100644 --- a/src/GitPrompt.ps1 +++ b/src/GitPrompt.ps1 @@ -209,29 +209,6 @@ function Write-GitStatus { } $sb.ToString() - - # If the user is running Powershell ISE then name the tab - if($psISE){ - $repo = $Status.RepoName - $branch = $Status.Branch - $tabName = "$repo [$branch]" - #you can't have 2 tabs with the same name so shove a number on the end - $tabCount = 0 - foreach($tab in $psISE.PowerShellTabs){ - $existingTabName = $tab.DisplayName - if($existingTabName.StartsWith($tabName) -and $existingTabName -ne $psise.CurrentPowerShellTab.DisplayName){ - $tabCount++ - $tabNumber = [int]$existingTabName.Replace($tabName, "").Replace("(", "").Replace(")", "").Trim() - if($tabCount -lt $tabNumber + 1){ - $tabCount = $tabNumber + 1 - } - } - } - if($tabCount -gt 0){ - $tabName= "$tabName ($tabCount)" - } - $psise.CurrentPowerShellTab.DisplayName = $tabName - } } <# diff --git a/src/PoshGitTypes.ps1 b/src/PoshGitTypes.ps1 index 65636ebb2..10da5ac15 100644 --- a/src/PoshGitTypes.ps1 +++ b/src/PoshGitTypes.ps1 @@ -273,6 +273,8 @@ class PoshGitPromptSettings { [string]$DescribeStyle = '' [psobject]$WindowTitle = {param($GitStatus, [bool]$IsAdmin) "$(if ($IsAdmin) {'Admin: '})$(if ($GitStatus) {"$($GitStatus.RepoName) [$($GitStatus.Branch)]"} else {Get-PromptPath}) ~ PowerShell $($PSVersionTable.PSVersion) $([IntPtr]::Size * 8)-bit ($PID)"} + [bool]$TabTitle = $true + [PoshGitTextSpan]$DefaultPromptPrefix = '$(Get-PromptConnectionInfo -Format "[{1}@{0}]: ")' [PoshGitTextSpan]$DefaultPromptPath = '$(Get-PromptPath)' [PoshGitTextSpan]$DefaultPromptBeforeSuffix = '' diff --git a/src/WindowTitle.ps1 b/src/WindowTitle.ps1 index 9fbc00733..208b2917b 100644 --- a/src/WindowTitle.ps1 +++ b/src/WindowTitle.ps1 @@ -58,3 +58,45 @@ function Set-WindowTitle { } } } + +function Set-TabTitle { + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] + param($GitStatus) + $settings = $global:GitPromptSettings + + if ($settings.TabTitle == $false) { + return + } + + # If the user is running Powershell ISE then name the tab + if($psISE -and $GitStatus){ + $existingTabNames = $psISE.PowerShellTabs | % {$_.DisplayName} + $currentTabName = $psise.CurrentPowerShellTab.DisplayName + $tabName = Get-TabTitle $GitStatus $existingTabNames $currentTabName + $psise.CurrentPowerShellTab.DisplayName = $tabName + } +} + +function Get-TabTitle { + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] + param($GitStatus, [string[]]$existingTabNames, [string]$currentTabName) + + $repo = $GitStatus.RepoName + $branch = $GitStatus.Branch + $tabName = "$repo [$branch]" + #you can't have 2 tabs with the same name so shove a number on the end + $tabCount = 0 + foreach($existingTabName in $existingTabNames){ + if($existingTabName.StartsWith($tabName) -and $existingTabName -ne $currentTabName){ + $tabCount++ + $tabNumber = [int]$existingTabName.Replace($tabName, "").Replace("(", "").Replace(")", "").Trim() + if($tabCount -lt $tabNumber + 1){ + $tabCount = $tabNumber + 1 + } + } + } + if($tabCount -gt 0){ + $tabName= "$tabName ($tabCount)" + } + return $tabName +} \ No newline at end of file diff --git a/src/posh-git.psm1 b/src/posh-git.psm1 index e3e4439b3..025ee502a 100644 --- a/src/posh-git.psm1 +++ b/src/posh-git.psm1 @@ -78,6 +78,7 @@ $GitPromptScriptBlock = { # This has to be *after* the call to Write-VcsStatus, which populates $global:GitStatus Set-WindowTitle $global:GitStatus $IsAdmin + Set-TabTitle $global:GitStatus # If prompt timing enabled, write elapsed milliseconds if ($settings.DefaultPromptEnableTiming) { From b1b7393397a2c4131780afbe608bf6d006fb62e0 Mon Sep 17 00:00:00 2001 From: George Cheyne Date: Sat, 18 Aug 2018 12:55:33 +0100 Subject: [PATCH 4/5] this isn't C# is it.... --- src/WindowTitle.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WindowTitle.ps1 b/src/WindowTitle.ps1 index 208b2917b..e66789be1 100644 --- a/src/WindowTitle.ps1 +++ b/src/WindowTitle.ps1 @@ -64,7 +64,7 @@ function Set-TabTitle { param($GitStatus) $settings = $global:GitPromptSettings - if ($settings.TabTitle == $false) { + if ($settings.TabTitle -eq $false) { return } From 24ee260a9d3669f02ac6ac897c0af55641fb4a87 Mon Sep 17 00:00:00 2001 From: George Cheyne Date: Sun, 19 Aug 2018 13:07:52 +0100 Subject: [PATCH 5/5] Changes to be committed: modified: src/PoshGitTypes.ps1 Made the TabTitle setting more like WindowTitle so it can be customised by users modified: src/WindowTitle.ps1 Removed tab handling code from here new file: src/TabTitle.ps1 moved all Tab related functionality here added code to reset tab names when leaving a repo space also will reset when unloading the posh-git module implemented simpler unique tab naming algorithm as suggested modified: src/posh-git.psm1 Added references to the new TabTitle script file and it's functions --- src/PoshGitTypes.ps1 | 7 ++- src/TabTitle.ps1 | 108 +++++++++++++++++++++++++++++++++++++++++++ src/WindowTitle.ps1 | 42 ----------------- src/posh-git.psm1 | 4 +- 4 files changed, 117 insertions(+), 44 deletions(-) create mode 100644 src/TabTitle.ps1 diff --git a/src/PoshGitTypes.ps1 b/src/PoshGitTypes.ps1 index 10da5ac15..d442ad846 100644 --- a/src/PoshGitTypes.ps1 +++ b/src/PoshGitTypes.ps1 @@ -273,7 +273,12 @@ class PoshGitPromptSettings { [string]$DescribeStyle = '' [psobject]$WindowTitle = {param($GitStatus, [bool]$IsAdmin) "$(if ($IsAdmin) {'Admin: '})$(if ($GitStatus) {"$($GitStatus.RepoName) [$($GitStatus.Branch)]"} else {Get-PromptPath}) ~ PowerShell $($PSVersionTable.PSVersion) $([IntPtr]::Size * 8)-bit ($PID)"} - [bool]$TabTitle = $true + [psobject]$TabTitle = { + param($GitStatus, [bool]$IsAdmin) + if ($GitStatus) { + Get-UniqueTabTitle "$($GitStatus.RepoName) [$($GitStatus.Branch)]" + } + } [PoshGitTextSpan]$DefaultPromptPrefix = '$(Get-PromptConnectionInfo -Format "[{1}@{0}]: ")' [PoshGitTextSpan]$DefaultPromptPath = '$(Get-PromptPath)' diff --git a/src/TabTitle.ps1 b/src/TabTitle.ps1 new file mode 100644 index 000000000..f5bd8e9f3 --- /dev/null +++ b/src/TabTitle.ps1 @@ -0,0 +1,108 @@ +$HostSupportsSettingTabTitle = $null +$OriginalTabTitle = $null +$GetCurrentTab = $null +$SetCurrentTab = $null +$GetExistingTabs = $null + +#for support of other MDI IDEs we might add new blocks below. +#note that the MDI IDEs need to maintain a seperate powershell instance in each document interface +#for example powergui has tabs for scripts but not tabs for powershell instances (AFAIK) +$MdiIdeSupportConfig = @( + #each block should contain a test to ensure it's only run for the appropriate IDE + [scriptblock] { + Write-Debug "Testing for PowerShell ISE tab support" + if ($psISE) { + Write-Debug "PowerShell ISE environment detected setting delegates" + $script:GetCurrentTab = [scriptblock]{$psise.CurrentPowerShellTab.DisplayName} + $script:SetCurrentTab = [scriptblock]{param($tabName)$psise.CurrentPowerShellTab.DisplayName=$tabName} + $script:GetExistingTabs = [scriptblock]{$psISE.PowerShellTabs | Select-Object -ExpandProperty DisplayName} + Write-Debug "Setting HostSupportsSettingTabTitle to true" + $script:HostSupportsSettingTabTitle = $true + } + } +) + +function Test-TabTitleIsWriteable { + if ($null -eq $script:HostSupportsSettingTabTitle) { + # check to see if we're in a tabbed IDE and test to see if we can set tab names + try { + #run the config blocks to set up delegate calls to IDE tab naming methods + foreach ($item in $script:MdiIdeSupportConfig) { + Invoke-Command $item + } + + #if HostSupportsSettingTabTitle is still null then we must not be in an MDI IDE + if ($null -eq $script:HostSupportsSettingTabTitle) { + $script:HostSupportsSettingTabTitle = $false + } else { + Write-Debug "HostSupportsSettingTabTitle: $script:HostSupportsSettingTabTitle" + Write-Debug "Testing tab renaming actually works" + #cache the original tab name and test naming works + $script:OriginalTabTitle = & $script:GetCurrentTab + $testTitle = [System.Guid]::NewGuid().ToString() + Write-Debug "Setting tab title from $($script:OriginalTabTitle) to $testTitle" + & $script:SetCurrentTab $testTitle + Write-Debug "Setting tab title back to $($script:OriginalTabTitle)" + & $script:SetCurrentTab $script:OriginalTabTitle + Write-Debug "It works" + } + Write-Debug "HostSupportsSettingTabTitle: $script:HostSupportsSettingTabTitle" + Write-Debug "OriginalTabTitle: $script:OriginalTabTitle" + } + catch { + $script:OriginalTabTitle = $null + $script:HostSupportsSettingTabTitle = $false + Write-Debug "HostSupportsSettingTabTitle error: $_" + } + } + return $script:HostSupportsSettingTabTitle +} + +function Reset-TabTitle { + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] + param() + $settings = $global:GitPromptSettings + + # Revert to original TabTitle, but only if posh-git is currently configured to set it + if ($HostSupportsSettingTabTitle -and $OriginalTabTitle -and $settings.TabTitle) { + Write-Debug "Resetting TabTitle: '$OriginalTabTitle'" + & $script:SetCurrentTab $OriginalTabTitle + } +} + +function Set-TabTitle { + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] + param($GitStatus, $IsAdmin) + $settings = $global:GitPromptSettings + + # Update the host's TabTitle if + # host supports it + # user has not disabled $GitPromptSettings.TabTitle + # we are in a git repo + if ($settings.TabTitle -and (Test-TabTitleIsWriteable) -and $settings.TabTitle -is [scriptblock]) { + try { + if ($GitStatus) { + # ensure results returned by scriptblock are flattened into a string + $tabTitleText = "$(& $settings.TabTitle $GitStatus $IsAdmin)" + Write-Debug "Setting TabTitle: $tabTitleText" + & $script:SetCurrentTab "$tabTitleText" + } else { + Reset-TabTitle + } + } + catch { + Write-Debug "Error occurred during evaluation of `$GitPromptSettings.TabTitle: $_" + } + } +} + +function Get-UniqueTabTitle { + param($tabNameRoot, $Format="{0} {1}") + $tabNumber = 1 + $existingTabNames = & $script:GetExistingTabs + $uniqueTabName = $tabNameRoot + while ($existingTabNames -contains $uniqueTabName) { + $uniqueTabName = $Format -f $tabNameRoot,$tabNumber++ + } + return $uniqueTabName +} diff --git a/src/WindowTitle.ps1 b/src/WindowTitle.ps1 index e66789be1..9fbc00733 100644 --- a/src/WindowTitle.ps1 +++ b/src/WindowTitle.ps1 @@ -58,45 +58,3 @@ function Set-WindowTitle { } } } - -function Set-TabTitle { - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] - param($GitStatus) - $settings = $global:GitPromptSettings - - if ($settings.TabTitle -eq $false) { - return - } - - # If the user is running Powershell ISE then name the tab - if($psISE -and $GitStatus){ - $existingTabNames = $psISE.PowerShellTabs | % {$_.DisplayName} - $currentTabName = $psise.CurrentPowerShellTab.DisplayName - $tabName = Get-TabTitle $GitStatus $existingTabNames $currentTabName - $psise.CurrentPowerShellTab.DisplayName = $tabName - } -} - -function Get-TabTitle { - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] - param($GitStatus, [string[]]$existingTabNames, [string]$currentTabName) - - $repo = $GitStatus.RepoName - $branch = $GitStatus.Branch - $tabName = "$repo [$branch]" - #you can't have 2 tabs with the same name so shove a number on the end - $tabCount = 0 - foreach($existingTabName in $existingTabNames){ - if($existingTabName.StartsWith($tabName) -and $existingTabName -ne $currentTabName){ - $tabCount++ - $tabNumber = [int]$existingTabName.Replace($tabName, "").Replace("(", "").Replace(")", "").Trim() - if($tabCount -lt $tabNumber + 1){ - $tabCount = $tabNumber + 1 - } - } - } - if($tabCount -gt 0){ - $tabName= "$tabName ($tabCount)" - } - return $tabName -} \ No newline at end of file diff --git a/src/posh-git.psm1 b/src/posh-git.psm1 index 025ee502a..129c4e847 100644 --- a/src/posh-git.psm1 +++ b/src/posh-git.psm1 @@ -6,6 +6,7 @@ param([switch]$NoVersionWarn, [switch]$ForcePoshGitPrompt) . $PSScriptRoot\Utils.ps1 . $PSScriptRoot\AnsiUtils.ps1 . $PSScriptRoot\WindowTitle.ps1 +. $PSScriptRoot\TabTitle.ps1 . $PSScriptRoot\PoshGitTypes.ps1 . $PSScriptRoot\GitUtils.ps1 . $PSScriptRoot\GitPrompt.ps1 @@ -78,7 +79,7 @@ $GitPromptScriptBlock = { # This has to be *after* the call to Write-VcsStatus, which populates $global:GitStatus Set-WindowTitle $global:GitStatus $IsAdmin - Set-TabTitle $global:GitStatus + Set-TabTitle $global:GitStatus $IsAdmin # If prompt timing enabled, write elapsed milliseconds if ($settings.DefaultPromptEnableTiming) { @@ -129,6 +130,7 @@ $ExecutionContext.SessionState.Module.OnRemove = { $global:VcsPromptStatuses = $global:VcsPromptStatuses | Where-Object { $_ -ne $PoshGitVcsPrompt } Reset-WindowTitle + Reset-TabTitle # 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 }