Public/Set-CustomPrompt.ps1

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
function Set-CustomPrompt {
  <#
  .SYNOPSIS
    Custom PowerShell prompt.
  .DESCRIPTION
    This prompt adds the following functionality:
 
    1. Invocation ID count (how many times a command was executed)
    2. The custom output of the current directory, with optional trimming if the current directory is determined to be too long.
    3. Posh-Git integration
    4. Built-in timers for each command executed in the console
    5. The current local time
    6. A custom ASCII symbol placed before the cursor
  .PARAMETER Symbol
    ASCII code for the symbol placed before the cursor in the console.
  .PARAMETER Force
    Controls whether or not the user is prompted to change their prompt.
  .EXAMPLE
    Set-CustomPrompt -Symbol '26A1' -Force
 
    Forces the prompt to change, using the 'High Voltage' Emoji (⚡) as the
    ASCII character is placed before the cursor.
  .NOTES
    This theme has taken inspiration heavily from the Agnoster oh-my-posh theme.
  #>

  [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]
  param (
    [string]$Symbol = '1F680', # Heart
    [switch]$Force
  )

  begin {
    $black = [System.ConsoleColor]::Black
    $blue = [System.ConsoleColor]::Blue
    $dark_cyan = [System.ConsoleColor]::DarkCyan
    $gray = [System.ConsoleColor]::Gray
    $magenta = [System.ConsoleColor]::Magenta
    $red = [System.ConsoleColor]::Red
    $white = [System.ConsoleColor]::White

    $custom_symbol = [char]::ConvertFromUtf32("0x$Symbol")
    $house_symbol = [char]::ConvertFromUtf32('0x1F3E0')

    $forward_arrow = [char]::ConvertFromUtf32(0xE0B1)
    $backward_symbol = [char]::ConvertFromUtf32(0xE0B2)
    $forward_symbol = [char]::ConvertFromUtf32(0xE0B0)
    $warning_symbol = [char]::ConvertFromUtf32(0x203C)
  }

  process {
    if ($Force -or $PSCmdlet.ShouldProcess('PowerShell prompt', 'overwrite')) {
      # Check the last command state and indicate if failed
      if ($Global:Error.Count -gt $Global:err_count) {
        $Global:err_count ++
        $prompt += Write-Prompt -Object $warning_symbol -ForegroundColor $white -BackgroundColor $red
        $prompt += Write-Prompt -Object $forward_symbol -ForegroundColor $red -BackgroundColor $blue
      }

      # Add invocation number
      $prompt += Write-Prompt -Object " $($MyInvocation.HistoryId) " -ForegroundColor $dark_gray -BackgroundColor $blue
      $prompt += Write-Prompt -Object $($forward_symbol) -ForegroundColor $blue -BackgroundColor $gray

      $full_path = $pwd.Path.Replace("$($pwd.Drive.Name)\", '').Replace('\', ' ' + $forward_arrow + ' ')

      if (Test-VirtualEnv) {
        $prompt += Write-Prompt -Object "$($forward_symbol) " -ForegroundColor $black -BackgroundColor $red
        $prompt += Write-Prompt -Object "$($sl.PromptSymbols.VirtualEnvSymbol) $(Get-VirtualEnvName) " -ForegroundColor $white -BackgroundColor $red
        $prompt += Write-Prompt -Object "$($forward_symbol) " -ForegroundColor $red -BackgroundColor $dark_cyan
      }
      else {
        $prompt += Write-Prompt -Object " $($pwd.Drive.Name) " -ForegroundColor $dark_cyan -BackgroundColor $gray
        $prompt += Write-Prompt -Object $($forward_symbol) -ForegroundColor $gray -BackgroundColor $dark_cyan
      }

      # Writes the drive portion
      # Reduce the path displayed if it is long
      if (($full_path.Split($forward_arrow).count -gt 2)) {
        $One = $full_path.split($forward_arrow)[-1]
        $Two = $full_path.split($forward_arrow)[-2]

        if ($One.Length -gt 10) { $One = "$($One[0..7] -join '')~" }
        if ($Two.Length -gt 10) { $Two = "$($Two[0..7] -join '')~" }

        # Don't include drive letter
        $partial_path = ' .. ', $Two, $One -join $forward_arrow
        $prompt += Write-Prompt -Object "$partial_path " -ForegroundColor $white -BackgroundColor $dark_cyan
      }
      else {
        # Don't include drive letter
        $partial_path = $($full_path.split($forward_arrow)[1..($full_path.length)])
        $prompt += Write-Prompt -Object "$partial_path "-ForegroundColor $white -BackgroundColor $dark_cyan
      }

      # Adds Pre/Postfix to the VCS Prompt
      $status = Get-VCSStatus
      if ($status) {
        $themeInfo = Get-VcsInfo -status ($status)
        $prompt += Write-Prompt -Object $forward_symbol -ForegroundColor $dark_cyan -BackgroundColor $magenta
        $prompt += Write-Prompt -Object " $($themeInfo.VcInfo) " -BackgroundColor $magenta -ForegroundColor $black
        $prompt += Write-Prompt -Object $forward_symbol -ForegroundColor $magenta
      }
      else {
        $prompt += Write-Prompt -Object $forward_symbol -ForegroundColor $dark_cyan
      }

      $timestamp = Get-Date -f "T"

      # Writes the Invocation time and date
      $prompt += Set-CursorForRightBlockWrite -textLength ($timestamp.Length + 13)
      $prompt += Write-Prompt $backward_symbol -ForegroundColor $dark_cyan
      $prompt += Write-Prompt $(Get-Elapsed) -ForegroundColor $gray -BackgroundColor $dark_cyan
      $prompt += Write-Prompt $backward_symbol -ForegroundColor $blue -BackgroundColor $dark_cyan
      $prompt += Write-Prompt $timestamp -ForegroundColor $gray -BackgroundColor $blue

      # Move the actual prompt to the next line and set the prompt
      $prompt += Set-Newline

      if ($pwd.Path -eq "$env:HOMEDRIVE\Tmp") {
        $prompt += Write-Prompt -Object " $house_symbol " -ForegroundColor $red -BackgroundColor $gray
      }
      else {
        $prompt += Write-Prompt -Object " $custom_symbol " -ForegroundColor $red -BackgroundColor $gray
      }
      $prompt += Write-Prompt -Object "$forward_symbol " -ForegroundColor $gray
      $prompt += ' '
    }
  }
  end {
    return $prompt
  }
}