Repository: JanDeDobbeleer/oh-my-posh
Pull request #3150 (2022-12-01 16:27:22)

feat: add max_cols option in segment
If the terminal width exceeds this value, the segment will be hidden.
Need testing on Windows.

Follow up of discussion https://github.com/JanDeDobbeleer/oh-my-posh/discussions/3148

I hope the doc changes are good.
thanks ! 



mirsella: ![image](https://user-images.githubusercontent.com/45905567/205107818-db8a0994-b553-4cab-8289-fb9677fbbfb0.png)

i still need to figure out why the RPROMPT is on the newline, i want it on the first line with the PROMPT. if you have a guess i'm taking. thanks
JanDeDobbeleer: @mirsella rprompt will ALWAYS be on the same line as the cursor. That's by design.
mirsella: oh ok, thanks for clearing things up
JanDeDobbeleer: General question, do we want to add a `min_cols` setting as well? if so it can all become very responsive.
mirsella: I'll look into it tomorrow when I get back to my pc.
we can add a min_cols while we are at it 

JanDeDobbeleer: @mirsella we've got time. I'm not in a hurry.
mirsella: Tell me if there is anything else !
mirsella: Accidentally merged your main branch with this PR but the commit message wasn't conventional, so i deleted it

Patch:
diff --git a/src/cli/get.go b/src/cli/get.go
index 9de27c54..b2b03110 100644
--- a/src/cli/get.go
+++ b/src/cli/get.go
@@ -13,7 +13,7 @@ import (
 
 // getCmd represents the get command
 var getCmd = &cobra.Command{
-	Use:   "get [shell|millis|accent|toggles]",
+	Use:   "get [shell|millis|accent|toggles|width]",
 	Short: "Get a value from oh-my-posh",
 	Long: `Get a value from oh-my-posh.
 
@@ -22,12 +22,14 @@ This command is used to get the value of the following variables:
 - shell
 - millis
 - accent
-- toggles`,
+- toggles
+- width`,
 	ValidArgs: []string{
 		"millis",
 		"shell",
 		"accent",
 		"toggles",
+		"width",
 	},
 	Args: NoArgsOrOneValidArg,
 	Run: func(cmd *cobra.Command, args []string) {
@@ -71,6 +73,13 @@ This command is used to get the value of the following variables:
 			for _, toggle := range toggles {
 				fmt.Println("- " + toggle)
 			}
+		case "width":
+			width, err := env.TerminalWidth()
+			if err != nil {
+				fmt.Println("error getting terminal width:", err.Error())
+				return
+			}
+			fmt.Println(width)
 		default:
 			_ = cmd.Help()
 		}
diff --git a/src/engine/segment.go b/src/engine/segment.go
index f1d6442e..026e28b7 100644
--- a/src/engine/segment.go
+++ b/src/engine/segment.go
@@ -36,6 +36,8 @@ type Segment struct {
 	Properties          properties.Map `json:"properties,omitempty"`
 	Interactive         bool           `json:"interactive,omitempty"`
 	Alias               string         `json:"alias,omitempty"`
+	MaxWidth            int            `json:"max_width,omitempty"`
+	MinWidth            int            `json:"min_width,omitempty"`
 
 	writer          SegmentWriter
 	Enabled         bool `json:"-"`
@@ -399,6 +401,9 @@ func (segment *Segment) SetEnabled(env platform.Environment) {
 			}
 		}
 	}
+	if segment.shouldHideForWidth() {
+		return
+	}
 	if segment.writer.Enabled() {
 		segment.Enabled = true
 		name := segment.Alias
@@ -409,6 +414,26 @@ func (segment *Segment) SetEnabled(env platform.Environment) {
 	}
 }
 
+func (segment *Segment) shouldHideForWidth() bool {
+	if segment.MaxWidth == 0 && segment.MinWidth == 0 {
+		return false
+	}
+	width, err := segment.env.TerminalWidth()
+	if err != nil {
+		return false
+	}
+	if segment.MinWidth > 0 && segment.MaxWidth > 0 {
+		return width < segment.MinWidth || width > segment.MaxWidth
+	}
+	if segment.MaxWidth > 0 && width > segment.MaxWidth {
+		return true
+	}
+	if segment.MinWidth > 0 && width < segment.MinWidth {
+		return true
+	}
+	return false
+}
+
 func (segment *Segment) SetText() {
 	if !segment.Enabled {
 		return
diff --git a/themes/schema.json b/themes/schema.json
index 2e305ac4..7d5ce0da 100644
--- a/themes/schema.json
+++ b/themes/schema.json
@@ -318,6 +318,18 @@
           "description": "https://ohmyposh.dev/docs/configuration/segment#templates",
           "enum": ["first_match", "join"]
         },
+		"max_cols": {
+			"type": "integer",
+			"title": "if the terminal width exceeds this value, the segment will be hidden",
+			"description": "https://ohmyposh.dev/docs/configuration/segment#max_cols",
+			"default": 0
+		},
+		"min_cols": {
+			"type": "integer",
+			"title": "if the terminal width is inferior than this value, the segment will be hidden",
+			"description": "https://ohmyposh.dev/docs/configuration/segment#min_cols",
+			"default": 0
+		},
         "properties": {
           "type": "object",
           "title": "Segment Properties, used to change behavior/displaying",
diff --git a/website/docs/configuration/segment.mdx b/website/docs/configuration/segment.mdx
index 0e84133d..465331b4 100644
--- a/website/docs/configuration/segment.mdx
+++ b/website/docs/configuration/segment.mdx
@@ -50,7 +50,9 @@ understand how to configure a segment.
 | `templates_logic`      | `string`     | <ul><li>`first_match`: return the first non-whitespace string and skip everything else</li><li>`join`:evaluate all templates and join all non-whitespace strings (**default**)</li></ul>                                                                                                                                   |
 | `properties`           | `[]Property` | see [Properties][properties] below                                                                                                                                                                                                                                                                                         |
 | `interactive`          | `boolean`    | when is true, the segment text is not escaped to allow the use of interactive prompt escape sequences - defaults to `false`                                                                                                                                                                                                |
-| `alias`                | `string`     | for use with [cross segment template properties][cstp]                                                                                                                                                                                                                                                                            |
+| `alias`                | `string`     | for use with [cross segment template properties][cstp]                                                                                                                                                                                                                                                                     |
+| `min_width`            | `int`        | if the terminal width exceeds this value, the segment will be hidden. For your terminal width, see `oh-my-posh get width`. Defaults to `0` (disable)                                                                                                                                                                       |
+| `max_width`            | `int`        | if the terminal width is smaller than this value, the segment will be hidden. For your terminal width, see `oh-my-posh get width`. Defaults to `0` (disable)                                                                                                                                                               |
 
 ## Style
 


Test patch:
diff --git a/src/engine/segment_test.go b/src/engine/segment_test.go
index f9efd14f..28bbd5d6 100644
--- a/src/engine/segment_test.go
+++ b/src/engine/segment_test.go
@@ -164,3 +164,34 @@ func TestGetColors(t *testing.T) {
 		assert.Equal(t, tc.ExpectedColor, color, tc.Case)
 	}
 }
+
+func TestShouldHideForCols(t *testing.T) {
+	cases := []struct {
+		Case     string
+		MinWidth int
+		MaxWidth int
+		Width    int
+		Error    error
+		Expected bool
+	}{
+		{Case: "No settings"},
+		{Case: "Min cols - hide", MinWidth: 10, Width: 9, Expected: true},
+		{Case: "Min cols - show", MinWidth: 10, Width: 20, Expected: false},
+		{Case: "Max cols - hide", MaxWidth: 10, Width: 11, Expected: true},
+		{Case: "Max cols - show", MaxWidth: 10, Width: 8, Expected: false},
+		{Case: "Min & Max cols - hide", MinWidth: 10, MaxWidth: 20, Width: 21, Expected: true},
+		{Case: "Min & Max cols - hide 2", MinWidth: 10, MaxWidth: 20, Width: 8, Expected: true},
+		{Case: "Min & Max cols - show", MinWidth: 10, MaxWidth: 20, Width: 11, Expected: false},
+	}
+	for _, tc := range cases {
+		env := new(mock.MockedEnvironment)
+		env.On("TerminalWidth").Return(tc.Width, tc.Error)
+		segment := &Segment{
+			env:      env,
+			MaxWidth: tc.MaxWidth,
+			MinWidth: tc.MinWidth,
+		}
+		got := segment.shouldHideForWidth()
+		assert.Equal(t, tc.Expected, got, tc.Case)
+	}
+}