posh-git.psm1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
param([bool]$ForcePoshGitPrompt, [bool]$UseLegacyTabExpansion, [bool]$EnableProxyFunctionExpansion) if (Test-Path Env:\POSHGIT_ENABLE_STRICTMODE) { # Set strict mode to latest to help catch scripting errors in the module. This is done by the Pester tests. Set-StrictMode -Version Latest } . $PSScriptRoot\CheckRequirements.ps1 > $null . $PSScriptRoot\ConsoleMode.ps1 . $PSScriptRoot\Utils.ps1 . $PSScriptRoot\AnsiUtils.ps1 . $PSScriptRoot\WindowTitle.ps1 . $PSScriptRoot\PoshGitTypes.ps1 . $PSScriptRoot\GitUtils.ps1 . $PSScriptRoot\GitPrompt.ps1 . $PSScriptRoot\GitParamTabExpansion.ps1 . $PSScriptRoot\GitTabExpansion.ps1 . $PSScriptRoot\TortoiseGit.ps1 $IsAdmin = Test-Administrator # Get the default prompt definition. $initialSessionState = [System.Management.Automation.Runspaces.Runspace]::DefaultRunspace.InitialSessionState if (!$initialSessionState -or !$initialSessionState.PSObject.Properties.Match('Commands') -or !$initialSessionState.Commands['prompt']) { $defaultPromptDef = "`$(if (test-path variable:/PSDebugContext) { '[DBG]: ' } else { '' }) + 'PS ' + `$(Get-Location) + `$(if (`$nestedpromptlevel -ge 1) { '>>' }) + '> '" } else { $defaultPromptDef = $initialSessionState.Commands['prompt'].Definition } # The built-in posh-git prompt function in ScriptBlock form. $GitPromptScriptBlock = { $origDollarQuestion = $global:? $origLastExitCode = $global:LASTEXITCODE if (!$global:GitPromptValues) { $global:GitPromptValues = [PoshGitPromptValues]::new() } $global:GitPromptValues.DollarQuestion = $origDollarQuestion $global:GitPromptValues.LastExitCode = $origLastExitCode $global:GitPromptValues.IsAdmin = $IsAdmin $settings = $global:GitPromptSettings if (!$settings) { return "<`$GitPromptSettings not found> " } if ($settings.DefaultPromptEnableTiming) { $sw = [System.Diagnostics.Stopwatch]::StartNew() } if ($settings.SetEnvColumns) { # Set COLUMNS so git knows how wide the terminal is $Env:COLUMNS = $Host.UI.RawUI.WindowSize.Width } # Construct/write the prompt text $prompt = '' # Write default prompt prefix $prompt += Write-Prompt $settings.DefaultPromptPrefix.Expand() # Get the current path - formatted correctly $promptPath = $settings.DefaultPromptPath.Expand() # Write the delimited path and Git status summary information if ($settings.DefaultPromptWriteStatusFirst) { $prompt += Write-VcsStatus $prompt += Write-Prompt $settings.BeforePath.Expand() $prompt += Write-Prompt $promptPath $prompt += Write-Prompt $settings.AfterPath.Expand() } else { $prompt += Write-Prompt $settings.BeforePath.Expand() $prompt += Write-Prompt $promptPath $prompt += Write-Prompt $settings.AfterPath.Expand() $prompt += Write-VcsStatus } # Write default prompt before suffix text $prompt += Write-Prompt $settings.DefaultPromptBeforeSuffix.Expand() # If stopped in the debugger, the prompt needs to indicate that by writing default propmt debug if ((Test-Path Variable:/PSDebugContext) -or [runspace]::DefaultRunspace.Debugger.InBreakpoint) { $prompt += Write-Prompt $settings.DefaultPromptDebug.Expand() } # Get the prompt suffix text $promptSuffix = $settings.DefaultPromptSuffix.Expand() # When using Write-Host, we return a single space from this function to prevent PowerShell from displaying "PS>" # So to avoid two spaces at the end of the suffix, remove one here if it exists if (!$settings.AnsiConsole -and $promptSuffix.Text.EndsWith(' ')) { $promptSuffix.Text = $promptSuffix.Text.Substring(0, $promptSuffix.Text.Length - 1) } # This has to be *after* the call to Write-VcsStatus, which populates $global:GitStatus Set-WindowTitle $global:GitStatus $IsAdmin # If prompt timing enabled, write elapsed milliseconds if ($settings.DefaultPromptEnableTiming) { $timingInfo = [PoshGitTextSpan]::new($settings.DefaultPromptTimingFormat) $sw.Stop() $timingInfo.Text = $timingInfo.Text -f $sw.ElapsedMilliseconds $prompt += Write-Prompt $timingInfo } $prompt += Write-Prompt $promptSuffix # When using Write-Host, return at least a space to avoid "PS>" being unexpectedly displayed if (!$settings.AnsiConsole) { $prompt += " " } else { # If using ANSI, set this global to help debug ANSI issues $global:GitPromptValues.LastPrompt = EscapeAnsiString $prompt } $global:LASTEXITCODE = $origLastExitCode $prompt } $currentPromptDef = if ($funcInfo = Get-Command prompt -ErrorAction SilentlyContinue) { $funcInfo.Definition } # If prompt matches pre-0.7 posh-git prompt, ignore it $collapsedLegacyPrompt = '$realLASTEXITCODE = $LASTEXITCODE;Write-Host($pwd.ProviderPath) -nonewline;Write-VcsStatus;$global:LASTEXITCODE = $realLASTEXITCODE;return "> "' if ($currentPromptDef -and (($currentPromptDef.Trim() -replace '[\r\n\t]+\s*',';') -eq $collapsedLegacyPrompt)) { Write-Warning 'Replacing old posh-git prompt. Did you copy profile.example.ps1 into $PROFILE?' $currentPromptDef = $null } if (!$currentPromptDef) { # HACK: If prompt is missing, create a global one we can overwrite with Set-Item function global:prompt { ' ' } } # If there is no prompt function or the prompt function is the default, replace the current prompt function definition if ($ForcePoshGitPrompt -or !$currentPromptDef -or ($currentPromptDef -eq $defaultPromptDef)) { # Set the posh-git prompt as the default prompt Set-Item Function:\prompt -Value $GitPromptScriptBlock } # Install handler for removal/unload of the module $ExecutionContext.SessionState.Module.OnRemove = { $global:VcsPromptStatuses = $global:VcsPromptStatuses | Where-Object { $_ -ne $PoshGitVcsPrompt } Reset-WindowTitle # 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) { Set-Item Function:\prompt -Value ([scriptblock]::Create($defaultPromptDef)) return } Write-Warning 'If your prompt function uses any posh-git commands, it will cause posh-git to be re-imported every time your prompt function is invoked.' } $exportModuleMemberParams = @{ Function = @( 'Add-PoshGitToProfile', 'Expand-GitCommand', 'Format-GitBranchName', 'Get-GitBranchStatusColor', 'Get-GitDirectory', 'Get-GitStatus', 'Get-PromptConnectionInfo', 'Get-PromptPath', 'New-GitPromptSettings', 'Remove-GitBranch', 'Update-AllBranches', 'Write-GitStatus', 'Write-GitBranchName', 'Write-GitBranchStatus', 'Write-GitIndexStatus', 'Write-GitStashCount', 'Write-GitWorkingDirStatus', 'Write-GitWorkingDirStatusSummary', 'Write-Prompt', 'Write-VcsStatus', 'TabExpansion', 'tgit' ) Variable = @( 'GitPromptScriptBlock' ) } Export-ModuleMember @exportModuleMemberParams |