Repository: JanDeDobbeleer/oh-my-posh
Pull request #2235 (2022-05-07 08:12:42)

fix: correct debug logic
### Prerequisites

- [x] I have read and understood the `CONTRIBUTING` guide
- [x] The commit message follows the [conventional commits][cc] guidelines
- [x] Tests for the changes have been added (for bug fixes/features)
- [x] Docs have been added / updated (for bug fixes/features)

### Description

relates to #2234


<!---

Tips:

If you're not comfortable with working with Git, we're working a guide (https://ohmyposh.dev/docs/contributing_git) to help you out.
Oh My Posh advises GitKraken (https://www.gitkraken.com/invite/nQmDPR9D) as your preferred cross platform Git GUI power tool.

-->

[cc]: https://www.conventionalcommits.org/en/v1.0.0/#summary



Patch:
diff --git a/src/cli/cache.go b/src/cli/cache.go
index 62ed184e..07e48151 100644
--- a/src/cli/cache.go
+++ b/src/cli/cache.go
@@ -36,7 +36,7 @@ You can do the following:
 		env := &environment.ShellEnvironment{
 			Version: cliVersion,
 		}
-		env.Init(false)
+		env.Init()
 		defer env.Close()
 		switch args[0] {
 		case "path":
diff --git a/src/cli/config_export.go b/src/cli/config_export.go
index 53c28283..d5ba6203 100644
--- a/src/cli/config_export.go
+++ b/src/cli/config_export.go
@@ -44,7 +44,7 @@ A backup of the current config can be found at ~/myconfig.omp.json.bak.`,
 				Config: config,
 			},
 		}
-		env.Init(false)
+		env.Init()
 		defer env.Close()
 		cfg := engine.LoadConfig(env)
 		if len(output) == 0 {
diff --git a/src/cli/config_export_image.go b/src/cli/config_export_image.go
index 047a46e7..7c1fa3df 100644
--- a/src/cli/config_export_image.go
+++ b/src/cli/config_export_image.go
@@ -54,7 +54,7 @@ Exports the config to an image file using customized output options.`,
 				Shell:  shell.PLAIN,
 			},
 		}
-		env.Init(false)
+		env.Init()
 		defer env.Close()
 		cfg := engine.LoadConfig(env)
 		ansi := &color.Ansi{}
diff --git a/src/cli/config_migrate.go b/src/cli/config_migrate.go
index 4dd642e1..392402f7 100644
--- a/src/cli/config_migrate.go
+++ b/src/cli/config_migrate.go
@@ -44,7 +44,7 @@ A backup of the current config can be found at ~/myconfig.omp.json.bak.`,
 				Migrate: true,
 			},
 		}
-		env.Init(false)
+		env.Init()
 		defer env.Close()
 		cfg := engine.LoadConfig(env)
 		if write {
diff --git a/src/cli/debug.go b/src/cli/debug.go
index 67f06bc0..69788936 100644
--- a/src/cli/debug.go
+++ b/src/cli/debug.go
@@ -23,9 +23,10 @@ var debugCmd = &cobra.Command{
 		env := &environment.ShellEnvironment{
 			CmdFlags: &environment.Flags{
 				Config: config,
+				Debug:  true,
 			},
 		}
-		env.Init(true)
+		env.Init()
 		defer env.Close()
 		cfg := engine.LoadConfig(env)
 		ansi := &color.Ansi{}
diff --git a/src/cli/get.go b/src/cli/get.go
index 746b6caa..1e007a66 100644
--- a/src/cli/get.go
+++ b/src/cli/get.go
@@ -31,7 +31,7 @@ This command is used to get the value of the following variables:
 		env := &environment.ShellEnvironment{
 			Version: cliVersion,
 		}
-		env.Init(false)
+		env.Init()
 		defer env.Close()
 		switch args[0] {
 		case "millis":
diff --git a/src/cli/init.go b/src/cli/init.go
index 9362ff4a..1ce3cc09 100644
--- a/src/cli/init.go
+++ b/src/cli/init.go
@@ -54,7 +54,7 @@ func runInit(shellName string) {
 			Strict: strict,
 		},
 	}
-	env.Init(false)
+	env.Init()
 	defer env.Close()
 	if print {
 		init := shell.PrintInit(env)
diff --git a/src/cli/print.go b/src/cli/print.go
index cc39460a..f44bbf2c 100644
--- a/src/cli/print.go
+++ b/src/cli/print.go
@@ -61,7 +61,7 @@ var printCmd = &cobra.Command{
 				ShellVersion:  shellVersion,
 			},
 		}
-		env.Init(false)
+		env.Init()
 		defer env.Close()
 		cfg := engine.LoadConfig(env)
 		ansi := &color.Ansi{}
diff --git a/src/engine/block.go b/src/engine/block.go
index 4fd738d8..28cc5974 100644
--- a/src/engine/block.go
+++ b/src/engine/block.go
@@ -4,7 +4,6 @@ import (
 	"oh-my-posh/color"
 	"oh-my-posh/environment"
 	"oh-my-posh/shell"
-	"strings"
 	"sync"
 	"time"
 )
@@ -49,8 +48,7 @@ func (b *Block) Init(env environment.Environment, writer color.Writer, ansi *col
 	b.env = env
 	b.writer = writer
 	b.ansi = ansi
-	b.setEnabledSegments()
-	b.setSegmentsText()
+	b.executeSegmentLogic()
 }
 
 func (b *Block) InitPlain(env environment.Environment, config *Config) {
@@ -62,6 +60,13 @@ func (b *Block) InitPlain(env environment.Environment, config *Config) {
 		AnsiColors:         config.MakeColors(env),
 	}
 	b.env = env
+	b.executeSegmentLogic()
+}
+
+func (b *Block) executeSegmentLogic() {
+	if b.env.Flags().Debug {
+		return
+	}
 	b.setEnabledSegments()
 	b.setSegmentsText()
 }
@@ -76,7 +81,7 @@ func (b *Block) Enabled() bool {
 		return true
 	}
 	for _, segment := range b.Segments {
-		if segment.enabled {
+		if segment.Enabled {
 			return true
 		}
 	}
@@ -90,7 +95,7 @@ func (b *Block) setEnabledSegments() {
 	for _, segment := range b.Segments {
 		go func(s *Segment) {
 			defer wg.Done()
-			s.setEnabled(b.env)
+			s.SetEnabled(b.env)
 		}(segment)
 	}
 }
@@ -102,19 +107,15 @@ func (b *Block) setSegmentsText() {
 	for _, segment := range b.Segments {
 		go func(s *Segment) {
 			defer wg.Done()
-			if !s.enabled {
-				return
-			}
-			s.text = s.string()
-			s.enabled = len(strings.ReplaceAll(s.text, " ", "")) > 0
+			s.SetText()
 		}(segment)
 	}
 }
 
-func (b *Block) renderSegments() (string, int) {
+func (b *Block) RenderSegments() (string, int) {
 	defer b.writer.Reset()
 	for _, segment := range b.Segments {
-		if !segment.enabled && segment.Style != Accordion {
+		if !segment.Enabled && segment.Style != Accordion {
 			continue
 		}
 		b.setActiveSegment(segment)
@@ -135,7 +136,7 @@ func (b *Block) renderActiveSegment() {
 		b.writer.Write(color.Background, color.Foreground, b.activeSegment.text)
 		b.writer.Write(color.Transparent, color.Background, b.activeSegment.TrailingDiamond)
 	case Accordion:
-		if b.activeSegment.enabled {
+		if b.activeSegment.Enabled {
 			b.writer.Write(color.Background, color.Foreground, b.activeSegment.text)
 		}
 	}
@@ -187,7 +188,7 @@ func (b *Block) getPowerlineColor() string {
 	return b.previousActiveSegment.background()
 }
 
-func (b *Block) debug() (int, []*SegmentTiming) {
+func (b *Block) Debug() (int, []*SegmentTiming) {
 	var segmentTimings []*SegmentTiming
 	largestSegmentNameLength := 0
 	for _, segment := range b.Segments {
@@ -198,7 +199,9 @@ func (b *Block) debug() (int, []*SegmentTiming) {
 			largestSegmentNameLength = segmentTiming.nameLength
 		}
 		start := time.Now()
-		segmentTiming.active = segment.enabled
+		segment.SetEnabled(b.env)
+		segment.SetText()
+		segmentTiming.active = segment.Enabled
 		if segmentTiming.active || segment.Style == Accordion {
 			b.setActiveSegment(segment)
 			b.renderActiveSegment()
diff --git a/src/engine/engine.go b/src/engine/engine.go
index 907b00b1..0128c7b0 100644
--- a/src/engine/engine.go
+++ b/src/engine/engine.go
@@ -129,7 +129,7 @@ func (e *Engine) renderBlock(block *Block) {
 		}
 		switch block.Alignment {
 		case Right:
-			text, length := block.renderSegments()
+			text, length := block.RenderSegments()
 			if padText, OK := e.shouldFill(block, length); OK {
 				e.write(padText)
 			}
@@ -138,12 +138,12 @@ func (e *Engine) renderBlock(block *Block) {
 			e.currentLineLength = 0
 			e.write(text)
 		case Left:
-			text, length := block.renderSegments()
+			text, length := block.RenderSegments()
 			e.currentLineLength += length
 			e.write(text)
 		}
 	case RPrompt:
-		text, length := block.renderSegments()
+		text, length := block.RenderSegments()
 		e.rpromptLength = length
 		if e.Env.Shell() == shell.BASH {
 			text = e.Ansi.FormatText(text)
@@ -166,22 +166,22 @@ func (e *Engine) PrintDebug(startTime time.Time, version string) string {
 	e.write(fmt.Sprintf("\n\x1b[1mVersion:\x1b[0m %s\n", version))
 	e.write("\n\x1b[1mSegments:\x1b[0m\n\n")
 	// console title timing
+	titleStartTime := time.Now()
 	title := e.ConsoleTitle.GetTitle()
 	title = strings.TrimPrefix(title, "\x1b]0;")
 	title = strings.TrimSuffix(title, "\a")
-	duration := time.Since(startTime)
 	segmentTiming := &SegmentTiming{
 		name:       "ConsoleTitle",
 		nameLength: 12,
 		active:     len(e.Config.ConsoleTitleTemplate) > 0,
 		text:       title,
-		duration:   duration,
+		duration:   time.Since(titleStartTime),
 	}
 	segmentTimings = append(segmentTimings, segmentTiming)
 	// loop each segments of each blocks
 	for _, block := range e.Config.Blocks {
 		block.Init(e.Env, e.Writer, e.Ansi)
-		longestSegmentName, timings := block.debug()
+		longestSegmentName, timings := block.Debug()
 		segmentTimings = append(segmentTimings, timings...)
 		if longestSegmentName > largestSegmentNameLength {
 			largestSegmentNameLength = longestSegmentName
@@ -243,7 +243,7 @@ func (e *Engine) PrintTooltip(tip string) string {
 	if !tooltip.writer.Enabled() {
 		return ""
 	}
-	tooltip.enabled = true
+	tooltip.Enabled = true
 	// little hack to reuse the current logic
 	block := &Block{
 		Alignment: Right,
@@ -252,11 +252,11 @@ func (e *Engine) PrintTooltip(tip string) string {
 	switch e.Env.Shell() {
 	case shell.ZSH, shell.CMD, shell.FISH:
 		block.Init(e.Env, e.Writer, e.Ansi)
-		text, _ := block.renderSegments()
+		text, _ := block.RenderSegments()
 		return text
 	case shell.PWSH, shell.PWSH5:
 		block.InitPlain(e.Env, e.Config)
-		text, length := block.renderSegments()
+		text, length := block.RenderSegments()
 		e.write(e.Ansi.ClearAfter())
 		e.write(e.Ansi.CarriageForward())
 		e.write(e.Ansi.GetCursorForRightWrite(length, 0))
@@ -355,7 +355,7 @@ func (e *Engine) PrintRPrompt() string {
 	if !block.Enabled() {
 		return ""
 	}
-	text, length := block.renderSegments()
+	text, length := block.RenderSegments()
 	e.rpromptLength = length
 	return text
 }
diff --git a/src/engine/segment.go b/src/engine/segment.go
index 13e21e43..e01485a3 100644
--- a/src/engine/segment.go
+++ b/src/engine/segment.go
@@ -9,6 +9,7 @@ import (
 	"oh-my-posh/segments"
 	"oh-my-posh/template"
 	"runtime/debug"
+	"strings"
 	"time"
 )
 
@@ -29,7 +30,7 @@ type Segment struct {
 	Properties          properties.Map  `json:"properties,omitempty"`
 
 	writer          SegmentWriter
-	enabled         bool
+	Enabled         bool
 	text            string
 	env             environment.Environment
 	backgroundCache string
@@ -325,7 +326,7 @@ func (segment *Segment) string() string {
 	return text
 }
 
-func (segment *Segment) setEnabled(env environment.Environment) {
+func (segment *Segment) SetEnabled(env environment.Environment) {
 	defer func() {
 		err := recover()
 		if err == nil {
@@ -334,14 +335,22 @@ func (segment *Segment) setEnabled(env environment.Environment) {
 		// display a message explaining omp failed(with the err)
 		message := fmt.Sprintf("\noh-my-posh fatal error rendering %s segment:%s\n\n%s\n", segment.Type, err, debug.Stack())
 		fmt.Println(message)
-		segment.enabled = true
+		segment.Enabled = true
 	}()
 	err := segment.mapSegmentWithWriter(env)
 	if err != nil || !segment.shouldIncludeFolder() {
 		return
 	}
 	if segment.writer.Enabled() {
-		segment.enabled = true
+		segment.Enabled = true
 		env.TemplateCache().AddSegmentData(string(segment.Type), segment.writer)
 	}
 }
+
+func (segment *Segment) SetText() {
+	if !segment.Enabled {
+		return
+	}
+	segment.text = segment.string()
+	segment.Enabled = len(strings.ReplaceAll(segment.text, " ", "")) > 0
+}
diff --git a/src/environment/shell.go b/src/environment/shell.go
index aa37521f..9819c0ae 100644
--- a/src/environment/shell.go
+++ b/src/environment/shell.go
@@ -50,6 +50,7 @@ type Flags struct {
 	Migrate       bool
 	TerminalWidth int
 	Strict        bool
+	Debug         bool
 }
 
 type CommandError struct {
@@ -223,10 +224,9 @@ type ShellEnvironment struct {
 	fileCache  *fileCache
 	tmplCache  *TemplateCache
 	logBuilder strings.Builder
-	debug      bool
 }
 
-func (env *ShellEnvironment) Init(debug bool) {
+func (env *ShellEnvironment) Init() {
 	if env.CmdFlags == nil {
 		env.CmdFlags = &Flags{}
 	}
@@ -236,8 +236,7 @@ func (env *ShellEnvironment) Init(debug bool) {
 	env.cmdCache = &commandCache{
 		commands: newConcurrentMap(),
 	}
-	if debug {
-		env.debug = true
+	if env.CmdFlags.Debug {
 		log.SetOutput(&env.logBuilder)
 	}
 }
@@ -294,7 +293,7 @@ func (env *ShellEnvironment) downloadConfig(location string) error {
 }
 
 func (env *ShellEnvironment) trace(start time.Time, function string, args ...string) {
-	if !env.debug {
+	if !env.CmdFlags.Debug {
 		return
 	}
 	elapsed := time.Since(start)
@@ -303,7 +302,7 @@ func (env *ShellEnvironment) trace(start time.Time, function string, args ...str
 }
 
 func (env *ShellEnvironment) log(lt logType, function, message string) {
-	if !env.debug {
+	if !env.CmdFlags.Debug {
 		return
 	}
 	trace := fmt.Sprintf("%s: %s\n%s", lt, function, message)
@@ -311,7 +310,7 @@ func (env *ShellEnvironment) log(lt logType, function, message string) {
 }
 
 func (env *ShellEnvironment) debugF(function string, fn func() string) {
-	if !env.debug {
+	if !env.CmdFlags.Debug {
 		return
 	}
 	trace := fmt.Sprintf("%s: %s\n%s", Debug, function, fn())


Test patch:
diff --git a/src/engine/block_test.go b/src/engine/block_test.go
index a17db81d..b108e895 100644
--- a/src/engine/block_test.go
+++ b/src/engine/block_test.go
@@ -14,10 +14,10 @@ func TestBlockEnabled(t *testing.T) {
 		Type     BlockType
 	}{
 		{Case: "line break block", Expected: true, Type: LineBreak},
-		{Case: "prompt enabled", Expected: true, Type: Prompt, Segments: []*Segment{{enabled: true}}},
-		{Case: "prompt disabled", Expected: false, Type: Prompt, Segments: []*Segment{{enabled: false}}},
-		{Case: "prompt enabled multiple", Expected: true, Type: Prompt, Segments: []*Segment{{enabled: false}, {enabled: true}}},
-		{Case: "rprompt enabled multiple", Expected: true, Type: RPrompt, Segments: []*Segment{{enabled: false}, {enabled: true}}},
+		{Case: "prompt enabled", Expected: true, Type: Prompt, Segments: []*Segment{{Enabled: true}}},
+		{Case: "prompt disabled", Expected: false, Type: Prompt, Segments: []*Segment{{Enabled: false}}},
+		{Case: "prompt enabled multiple", Expected: true, Type: Prompt, Segments: []*Segment{{Enabled: false}, {Enabled: true}}},
+		{Case: "rprompt enabled multiple", Expected: true, Type: RPrompt, Segments: []*Segment{{Enabled: false}, {Enabled: true}}},
 	}
 	for _, tc := range cases {
 		block := &Block{
diff --git a/src/engine/engine_test.go b/src/engine/engine_test.go
index 04a2ff36..4a97f15a 100644
--- a/src/engine/engine_test.go
+++ b/src/engine/engine_test.go
@@ -51,7 +51,7 @@ func BenchmarkEngineRender(b *testing.B) {
 
 func engineRender() {
 	env := &environment.ShellEnvironment{}
-	env.Init(false)
+	env.Init()
 	defer env.Close()
 
 	cfg := LoadConfig(env)