Repository: JanDeDobbeleer/oh-my-posh
Pull request #6369 (2025-04-17 05:06:13)

next
### Prerequisites

- [x] I have read and understood the [contributing guide][CONTRIBUTING.md].
- [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

- **fix(engine): invert powerline on previous segment too**
- **feat(docker): add display_mode files**

<!---

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.

-->

[CONTRIBUTING.md]: https://github.com/JanDeDobbeleer/oh-my-posh/blob/main/CONTRIBUTING.md
[cc]: https://www.conventionalcommits.org/en/v1.0.0/#summary



Patch:
diff --git a/src/prompt/engine.go b/src/prompt/engine.go
index 160a5d02..f02ae0d9 100644
--- a/src/prompt/engine.go
+++ b/src/prompt/engine.go
@@ -392,7 +392,7 @@ func (e *Engine) writeSeparator(final bool) {
 		bgColor = color.Background
 	}
 
-	if e.activeSegment.InvertPowerline {
+	if e.activeSegment.InvertPowerline || e.previousActiveSegment.InvertPowerline {
 		terminal.Write(e.getPowerlineColor(), bgColor, symbol)
 		return
 	}
diff --git a/src/segments/docker.go b/src/segments/docker.go
index c37e5039..089620f7 100644
--- a/src/segments/docker.go
+++ b/src/segments/docker.go
@@ -3,6 +3,15 @@ package segments
 import (
 	"encoding/json"
 	"path/filepath"
+
+	"slices"
+
+	"github.com/jandedobbeleer/oh-my-posh/src/properties"
+)
+
+const (
+	// FetchContext is the property used to fetch the current docker context
+	FetchContext properties.Property = "fetch_context"
 )
 
 type DockerConfig struct {
@@ -37,6 +46,35 @@ func (d *Docker) configFiles() []string {
 }
 
 func (d *Docker) Enabled() bool {
+	extensions := []string{
+		"docker-compose.yml",
+		"docker-compose.yaml",
+		"Dockerfile",
+	}
+
+	extensions = d.props.GetStringArray(LanguageExtensions, extensions)
+
+	displayMode := d.props.GetString(DisplayMode, DisplayModeContext)
+	switch displayMode {
+	case DisplayModeContext:
+		return d.fetchContext()
+	case DisplayModeFiles:
+		if !slices.ContainsFunc(extensions, d.env.HasFiles) {
+			return false
+		}
+
+		// always respect the context fetching
+		if d.props.GetBool(FetchContext, true) {
+			_ = d.fetchContext()
+		}
+
+		return true
+	}
+
+	return false
+}
+
+func (d *Docker) fetchContext() bool {
 	// Check if there is a non-empty environment variable named `DOCKER_HOST` or `DOCKER_CONTEXT`
 	// These variables are set by the docker CLI and override the config file
 	// Return the current context if it is not empty and not `default`
diff --git a/src/segments/language.go b/src/segments/language.go
index 7953b894..8be6f5b3 100644
--- a/src/segments/language.go
+++ b/src/segments/language.go
@@ -7,6 +7,8 @@ import (
 	"path/filepath"
 	runtime_ "runtime"
 
+	"slices"
+
 	"github.com/jandedobbeleer/oh-my-posh/src/cache"
 	"github.com/jandedobbeleer/oh-my-posh/src/log"
 	"github.com/jandedobbeleer/oh-my-posh/src/properties"
@@ -175,12 +177,7 @@ func (l *language) Enabled() bool {
 }
 
 func (l *language) hasLanguageFiles() bool {
-	for _, extension := range l.extensions {
-		if l.env.HasFiles(extension) {
-			return true
-		}
-	}
-	return false
+	return slices.ContainsFunc(l.extensions, l.env.HasFiles)
 }
 
 func (l *language) hasProjectFiles() bool {
diff --git a/website/docs/segments/cli/docker.mdx b/website/docs/segments/cli/docker.mdx
index 070182f5..0712164f 100644
--- a/website/docs/segments/cli/docker.mdx
+++ b/website/docs/segments/cli/docker.mdx
@@ -10,16 +10,26 @@ Display the current Docker context. Will not be active when using the default co
 
 ## Sample Configuration
 
-import Config from '@site/src/components/Config.js';
-
-<Config data={{
-  "type": "docker",
-  "style": "powerline",
-  "powerline_symbol": "\uE0B0",
-  "foreground": "#000000",
-  "background": "#0B59E7",
-  "template": " \uf308 {{ .Context }} "
-}}/>
+import Config from "@site/src/components/Config.js";
+
+<Config
+  data={{
+    type: "docker",
+    style: "powerline",
+    powerline_symbol: "\uE0B0",
+    foreground: "#000000",
+    background: "#0B59E7",
+    template: " \uf308 {{ .Context }} ",
+  }}
+/>
+
+## Properties
+
+| Name            |    Type    |                        Default                        | Description                                                                                                                                                              |
+| --------------- | :--------: | :---------------------------------------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `display_mode`  |  `string`  |                       `context`                       | <ul><li>`files`: the segment is only displayed when a file `extensions` listed is present</li><li>`context`: displays the segment when a Docker context active</li></ul> |
+| `fetch_context` | `boolean`  |                        `true`                         | also fetch the current active Docker context when in the `files` display mode                                                                                            |
+| `extensions`    | `[]string` | `docker-compose.yml, docker-compose.yaml, Dockerfile` | allows to override the default list of file extensions to validate                                                                                                       |
 
 ## Template ([info][templates])
 


Test patch:
diff --git a/src/config/config_test.go b/src/config/config_test.go
index 17021a5e..abdbb6e7 100644
--- a/src/config/config_test.go
+++ b/src/config/config_test.go
@@ -158,27 +158,27 @@ func TestUpgradeFeatures(t *testing.T) {
 
 	for _, tc := range cases {
 		env := &mock.Environment{}
-		cache := &cache_.Cache{}
-		env.On("Cache").Return(cache)
+		c := &cache_.Cache{}
+		env.On("Cache").Return(c)
 
 		if tc.UpgradeCacheKeyExists {
-			cache.On("Get", upgrade.CACHEKEY).Return("", true)
+			c.On("Get", upgrade.CACHEKEY).Return("", true)
 		} else {
-			cache.On("Get", upgrade.CACHEKEY).Return("", false)
+			c.On("Get", upgrade.CACHEKEY).Return("", false)
 		}
 
-		cache.On("Set", upgrade.CACHEKEY, "", mock_.Anything).Return()
+		c.On("Set", upgrade.CACHEKEY, "", mock_.Anything).Return()
 
 		if tc.AutoUpgradeKey {
-			cache.On("Get", AUTOUPGRADE).Return("", true)
+			c.On("Get", AUTOUPGRADE).Return("", true)
 		} else {
-			cache.On("Get", AUTOUPGRADE).Return("", false)
+			c.On("Get", AUTOUPGRADE).Return("", false)
 		}
 
 		if tc.NoticeKey {
-			cache.On("Get", UPGRADENOTICE).Return("", true)
+			c.On("Get", UPGRADENOTICE).Return("", true)
 		} else {
-			cache.On("Get", UPGRADENOTICE).Return("", false)
+			c.On("Get", UPGRADENOTICE).Return("", false)
 		}
 
 		cfg := &Config{
diff --git a/src/segments/docker_test.go b/src/segments/docker_test.go
index 24f9ba87..dc4f8830 100644
--- a/src/segments/docker_test.go
+++ b/src/segments/docker_test.go
@@ -7,9 +7,10 @@ import (
 	"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"
 
 	"github.com/stretchr/testify/assert"
+	mock_ "github.com/stretchr/testify/mock"
 )
 
-func TestDockerSegment(t *testing.T) {
+func TestDockerContext(t *testing.T) {
 	type envVar struct {
 		name  string
 		value string
@@ -58,3 +59,32 @@ func TestDockerSegment(t *testing.T) {
 		}
 	}
 }
+
+func TestDockerFiles(t *testing.T) {
+	cases := []struct {
+		Case            string
+		ExpectedEnabled bool
+		HasFiles        bool
+	}{
+		{Case: "docker-compose.yml", ExpectedEnabled: true, HasFiles: true},
+		{Case: "docker-compose.yaml", ExpectedEnabled: true, HasFiles: true},
+		{Case: "Dockerfile", ExpectedEnabled: true, HasFiles: true},
+		{Case: "docker-compose.yml - not found", ExpectedEnabled: false, HasFiles: false},
+	}
+
+	for _, tc := range cases {
+		docker := &Docker{}
+		env := new(mock.Environment)
+		props := properties.Map{
+			DisplayMode:  DisplayModeFiles,
+			FetchContext: false,
+		}
+
+		docker.Init(props, env)
+
+		env.On("HasFiles", tc.Case).Return(true)
+		env.On("HasFiles", mock_.Anything).Return(false)
+
+		assert.Equal(t, tc.ExpectedEnabled, docker.Enabled(), tc.Case)
+	}
+}