From 93f6576da04c3d7b168b13814133bbeac1c1d17a Mon Sep 17 00:00:00 2001 From: mirsella Date: Thu, 1 Dec 2022 17:20:24 +0100 Subject: [PATCH] feat: allow segments to hide based on terminal width --- src/cli/get.go | 13 +++++++++-- src/engine/segment.go | 25 +++++++++++++++++++++ src/engine/segment_test.go | 31 ++++++++++++++++++++++++++ themes/schema.json | 12 ++++++++++ website/docs/configuration/segment.mdx | 4 +++- 5 files changed, 82 insertions(+), 3 deletions(-) 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/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) + } +} 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` | | | `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