diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..68579ff0 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,43 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Package", + "type": "go", + "request": "launch", + "mode": "debug", + "program": "${workspaceRoot}/src", + "args": ["-config=${workspaceRoot}/themes/jandedobbeleer.omp.json"] + }, + { + "name": "Launch tests", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceRoot}/src", + "args": ["-test.v"] + }, + { + "name": "Print debug", + "type": "go", + "request": "launch", + "mode": "debug", + "program": "${workspaceRoot}/src", + "args": [ + "--debug", + "-config=${workspaceRoot}/themes/jandedobbeleer.omp.json" + ] + }, + { + "name": "Print init pwsh", + "type": "go", + "request": "launch", + "mode": "debug", + "program": "${workspaceRoot}/src", + "args": ["--print-init","-shell=pwsh","-config=${workspaceRoot}/themes/jandedobbeleer.omp.json"] + }, + ] +} diff --git a/packages/powershell/oh-my-posh/oh-my-posh.psm1 b/packages/powershell/oh-my-posh/oh-my-posh.psm1 index a212a842..67c5ca09 100644 --- a/packages/powershell/oh-my-posh/oh-my-posh.psm1 +++ b/packages/powershell/oh-my-posh/oh-my-posh.psm1 @@ -5,7 +5,6 @@ $global:PoshSettings = New-Object -TypeName PSObject -Property @{ Theme = "$PSScriptRoot\themes\jandedobbeleer.json"; - ShowDebug = $false } function Get-PoshCommand { @@ -29,6 +28,7 @@ function Set-PoshContext {} function Set-GitStatus { if (Get-Command -Name "Get-GitStatus" -ErrorAction SilentlyContinue) { + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSProvideCommentHelp', '', Justification='Variable used later(not in this scope)')] $Global:GitStatus = Get-GitStatus } } @@ -37,14 +37,9 @@ function Set-PoshPrompt { param( [Parameter(Mandatory = $false)] [string] - $Theme, - [Parameter(Mandatory = $false)] - [bool] - $ShowDebug = $false + $Theme ) - $global:PoshSettings.ShowDebug = $ShowDebug - if (Test-Path "$PSScriptRoot/themes/$Theme.omp.json") { $global:PoshSettings.Theme = "$PSScriptRoot/themes/$Theme.omp.json" } @@ -81,9 +76,8 @@ function Set-PoshPrompt { $startInfo = New-Object System.Diagnostics.ProcessStartInfo $startInfo.FileName = Get-PoshCommand $config = $global:PoshSettings.Theme - $showDebug = $global:PoshSettings.ShowDebug $cleanPWD = $PWD.ProviderPath.TrimEnd("\") - $startInfo.Arguments = "--debug=""$showDebug"" --config=""$config"" --error=$errorCode --pwd=""$cleanPWD"" --execution-time=$executionTime" + $startInfo.Arguments = "--config=""$config"" --error=$errorCode --pwd=""$cleanPWD"" --execution-time=$executionTime" $startInfo.Environment["TERM"] = "xterm-256color" $startInfo.CreateNoWindow = $true $startInfo.StandardOutputEncoding = [System.Text.Encoding]::UTF8 diff --git a/src/engine.go b/src/engine.go index d3cbe273..8a29fdc2 100644 --- a/src/engine.go +++ b/src/engine.go @@ -3,6 +3,7 @@ package main import ( "fmt" "sync" + "time" ) type engine struct { @@ -17,6 +18,17 @@ type engine struct { rprompt string } +type SegmentTiming struct { + name string + nameLength int + enabled bool + stringValue string + enabledDuration time.Duration + stringDuration time.Duration + background string + foreground string +} + func (e *engine) getPowerlineColor(foreground bool) string { if e.previousActiveSegment == nil { return Transparent @@ -74,9 +86,6 @@ func (e *engine) renderText(text string) { prefix := e.activeSegment.getValue(Prefix, defaultValue) postfix := e.activeSegment.getValue(Postfix, defaultValue) e.color.write(e.activeSegment.Background, e.activeSegment.Foreground, fmt.Sprintf("%s%s%s", prefix, text, postfix)) - if *e.env.getArgs().Debug { - e.color.write(e.activeSegment.Background, e.activeSegment.Foreground, fmt.Sprintf("(%s:%s)", e.activeSegment.Type, e.activeSegment.timing)) - } } func (e *engine) renderSegmentText(text string) { @@ -117,11 +126,10 @@ func (e *engine) setStringValues(segments []*Segment) { wg.Add(len(segments)) defer wg.Wait() cwd := e.env.getcwd() - debug := *e.env.getArgs().Debug for _, segment := range segments { go func(s *Segment) { defer wg.Done() - s.setStringValue(e.env, cwd, debug) + s.setStringValue(e.env, cwd) }(segment) } } @@ -159,6 +167,71 @@ func (e *engine) render() { e.write() } +// debug will lool through your config file and output the timings for each segments +func (e *engine) debug() { + var segmentTimings []SegmentTiming + nameMaxLength := 0 + e.renderer.print("\nHere are the timings of segments in your prompt:\n") + // loop each segments of each blocks + for _, block := range e.settings.Blocks { + for _, segment := range block.Segments { + err := segment.mapSegmentWithWriter(e.env) + if err != nil || segment.shouldIgnoreFolder(e.env.getcwd()) { + return + } + + var segmentTiming SegmentTiming + + segmentTiming.name = string(segment.Type) + segmentTiming.nameLength = len(segmentTiming.name) + + if segmentTiming.nameLength > nameMaxLength { + nameMaxLength = segmentTiming.nameLength + } + + segmentTiming.background = segment.Background + segmentTiming.foreground = segment.Foreground + + // enabled timing + start := time.Now() + segmentTiming.enabled = segment.enabled() + segmentTiming.enabledDuration = time.Since(start) + + // string timing + if segmentTiming.enabled { + start = time.Now() + segmentTiming.stringValue = segment.string() + segmentTiming.stringDuration = time.Since(start) + + // not pretty rendering could be refactored for a better separation of concern + e.previousActiveSegment = nil + e.activeSegment = segment + e.activeSegment.Background = segment.props.background + e.activeSegment.Foreground = segment.props.foreground + e.renderSegmentText(segmentTiming.stringValue) + segmentTiming.stringValue = e.color.string() + e.color.buffer.Reset() + } + + segmentTimings = append(segmentTimings, segmentTiming) + } + } + + // 7 => (false) + nameMaxLength += 7 + + for _, segment := range segmentTimings { + duration := segment.enabledDuration.Milliseconds() + if segment.enabled { + duration += segment.stringDuration.Milliseconds() + } + e.renderer.print(fmt.Sprintf("%-*s - %3d ms - %s\n", nameMaxLength, fmt.Sprintf("%s(%t)", segment.name, segment.enabled), + duration, segment.stringValue)) + } + + fmt.Print(e.renderer.string()) +} + func (e *engine) write() { switch e.env.getShellName() { case zsh: diff --git a/src/init/omp.ps1 b/src/init/omp.ps1 index 8debaf15..22e86fdf 100644 --- a/src/init/omp.ps1 +++ b/src/init/omp.ps1 @@ -1,6 +1,5 @@ $global:PoshSettings = New-Object -TypeName PSObject -Property @{ Theme = ""; - ShowDebug = $false } if (Test-Path "::CONFIG::") { @@ -10,6 +9,7 @@ function Set-PoshContext {} function Set-GitStatus { if (Get-Command -Name "Get-GitStatus" -ErrorAction SilentlyContinue) { + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSProvideCommentHelp', '', Justification='Variable used later(not in this scope)')] $Global:GitStatus = Get-GitStatus } } @@ -40,9 +40,8 @@ function Set-GitStatus { $startInfo = New-Object System.Diagnostics.ProcessStartInfo $startInfo.FileName = "::OMP::" $config = $global:PoshSettings.Theme - $showDebug = $global:PoshSettings.ShowDebug $cleanPWD = $PWD.ProviderPath.TrimEnd("\") - $startInfo.Arguments = "--debug=""$showDebug"" --config=""$config"" --error=$errorCode --pwd=""$cleanPWD"" --execution-time=$executionTime" + $startInfo.Arguments = "--config=""$config"" --error=$errorCode --pwd=""$cleanPWD"" --execution-time=$executionTime" $startInfo.Environment["TERM"] = "xterm-256color" $startInfo.CreateNoWindow = $true $startInfo.StandardOutputEncoding = [System.Text.Encoding]::UTF8 diff --git a/src/main.go b/src/main.go index d558bd9e..835e456b 100644 --- a/src/main.go +++ b/src/main.go @@ -127,8 +127,10 @@ func main() { fmt.Println(Version) return } + formats := &ansiFormats{} formats.init(env.getShellName()) + renderer := &AnsiRenderer{ buffer: new(bytes.Buffer), formats: formats, @@ -149,7 +151,12 @@ func main() { renderer: renderer, consoleTitle: title, } - engine.render() + + if *args.Debug { + engine.debug() + } else { + engine.render() + } } func initShell(shell, config string) string { diff --git a/src/segment.go b/src/segment.go index e413dceb..8174ce89 100644 --- a/src/segment.go +++ b/src/segment.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "regexp" - "time" ) // Segment represent a single segment and it's configuration @@ -22,7 +21,6 @@ type Segment struct { writer SegmentWriter stringValue string active bool - timing time.Duration } // SegmentWriter is the interface used to define what and if to write to the prompt @@ -164,24 +162,11 @@ func (segment *Segment) mapSegmentWithWriter(env environmentInfo) error { return errors.New("unable to map writer") } -func (segment *Segment) setStringValue(env environmentInfo, cwd string, debug bool) { +func (segment *Segment) setStringValue(env environmentInfo, cwd string) { err := segment.mapSegmentWithWriter(env) if err != nil || segment.shouldIgnoreFolder(cwd) { return } - // add timing only in debug - if debug { - start := time.Now() - defer (func() { - // force segment rendering to display the time it took - // to check if the segment is enabled or not - // depending on the segement, calling enabled() - // can be time consuming - segment.active = true - elapsed := time.Since(start) - segment.timing = elapsed - })() - } if segment.enabled() { segment.stringValue = segment.string() }