From 63bb1b4729e7aae0218101b46183bdd51084c928 Mon Sep 17 00:00:00 2001 From: Jan De Dobbeleer Date: Thu, 17 Nov 2022 20:52:41 +0100 Subject: [PATCH] feat(cli): toggle segments on/off resolves #3086 --- .vscode/launch.json | 11 +++++ src/cli/font.go | 1 + src/cli/get.go | 22 +++++++++- src/cli/toggle.go | 53 ++++++++++++++++++++++++ src/engine/segment.go | 9 ++++ src/platform/shell.go | 4 +- website/docs/configuration/segment.mdx | 33 ++++++++++++++- website/docs/configuration/templates.mdx | 22 +--------- 8 files changed, 130 insertions(+), 25 deletions(-) create mode 100644 src/cli/toggle.go diff --git a/.vscode/launch.json b/.vscode/launch.json index 23ba8e32..75d26243 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -118,6 +118,17 @@ "accent" ] }, + { + "name": "Toggle segment", + "type": "go", + "request": "launch", + "mode": "debug", + "program": "${workspaceRoot}/src", + "args": [ + "toggle", + "git" + ] + }, { "type": "node", "request": "launch", diff --git a/src/cli/font.go b/src/cli/font.go index 3abae595..b4f65744 100644 --- a/src/cli/font.go +++ b/src/cli/font.go @@ -35,6 +35,7 @@ This command is used to install fonts and configure the font in your terminal. } env := &platform.Shell{} env.Init() + defer env.Close() needsAdmin := env.GOOS() == platform.WINDOWS && !env.Root() font.Run(fontName, needsAdmin) return diff --git a/src/cli/get.go b/src/cli/get.go index 786f04b9..9de27c54 100644 --- a/src/cli/get.go +++ b/src/cli/get.go @@ -4,6 +4,7 @@ import ( "fmt" "oh-my-posh/color" "oh-my-posh/platform" + "strings" "time" color2 "github.com/gookit/color" @@ -12,7 +13,7 @@ import ( // getCmd represents the get command var getCmd = &cobra.Command{ - Use: "get [shell|millis|accent]", + Use: "get [shell|millis|accent|toggles]", Short: "Get a value from oh-my-posh", Long: `Get a value from oh-my-posh. @@ -20,11 +21,13 @@ This command is used to get the value of the following variables: - shell - millis -- accent`, +- accent +- toggles`, ValidArgs: []string{ "millis", "shell", "accent", + "toggles", }, Args: NoArgsOrOneValidArg, Run: func(cmd *cobra.Command, args []string) { @@ -53,6 +56,21 @@ This command is used to get the value of the following variables: } accent := color2.RGB(rgb.R, rgb.G, rgb.B) fmt.Println("#" + accent.Hex()) + case "toggles": + cache := env.Cache() + togglesCache, _ := cache.Get(platform.TOGGLECACHE) + var toggles []string + if len(togglesCache) != 0 { + toggles = strings.Split(togglesCache, ",") + } + if len(toggles) == 0 { + fmt.Println("No segments are toggled off") + return + } + fmt.Println("Toggled off segments:") + for _, toggle := range toggles { + fmt.Println("- " + toggle) + } default: _ = cmd.Help() } diff --git a/src/cli/toggle.go b/src/cli/toggle.go new file mode 100644 index 00000000..abcc60e5 --- /dev/null +++ b/src/cli/toggle.go @@ -0,0 +1,53 @@ +package cli + +import ( + "oh-my-posh/platform" + "strings" + + "github.com/spf13/cobra" +) + +// versionCmd represents the version command +var toggleCmd = &cobra.Command{ + Use: "toggle", + Short: "Toggle a segment on/off", + Long: "Toggle a segment on/off on the fly.", + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + if len(args) == 0 { + _ = cmd.Help() + return + } + env := &platform.Shell{} + env.Init() + defer env.Close() + + cache := env.Cache() + togglesCache, _ := cache.Get(platform.TOGGLECACHE) + var toggles []string + if len(togglesCache) != 0 { + toggles = strings.Split(togglesCache, ",") + } + segment := args[0] + + newToggles := []string{} + var match bool + for _, toggle := range toggles { + if toggle == segment { + match = true + continue + } + newToggles = append(newToggles, toggle) + } + + if !match { + newToggles = append(newToggles, segment) + } + + cache.Set(platform.TOGGLECACHE, strings.Join(newToggles, ","), -1) + }, +} + +func init() { //nolint:gochecknoinits + RootCmd.AddCommand(toggleCmd) +} diff --git a/src/engine/segment.go b/src/engine/segment.go index 5e72c835..523605af 100644 --- a/src/engine/segment.go +++ b/src/engine/segment.go @@ -384,6 +384,15 @@ func (segment *Segment) SetEnabled(env platform.Environment) { if err != nil || !segment.shouldIncludeFolder() { return } + // validate toggles + if toggles, OK := segment.env.Cache().Get(platform.TOGGLECACHE); OK && len(toggles) > 0 { + list := strings.Split(toggles, ",") + for _, toggle := range list { + if SegmentType(toggle) == segment.Type { + return + } + } + } if segment.writer.Enabled() { segment.Enabled = true name := segment.Alias diff --git a/src/platform/shell.go b/src/platform/shell.go index 9ec7731f..01da8dc2 100644 --- a/src/platform/shell.go +++ b/src/platform/shell.go @@ -36,8 +36,10 @@ const ( ) var ( + pid = os.Getppid() lock = sync.RWMutex{} - TEMPLATECACHE = fmt.Sprintf("template_cache_%d", os.Getppid()) + TEMPLATECACHE = fmt.Sprintf("template_cache_%d", pid) + TOGGLECACHE = fmt.Sprintf("toggle_cache_%d", pid) ) type Flags struct { diff --git a/website/docs/configuration/segment.mdx b/website/docs/configuration/segment.mdx index 206a231b..6b20316a 100644 --- a/website/docs/configuration/segment.mdx +++ b/website/docs/configuration/segment.mdx @@ -146,6 +146,37 @@ You can also combine these properties: This means that for user Bill, who has a user account `Bill` on Windows and `bill` on Linux, `~/Foo` might match `C:\Users\Bill\Foo` or `C:\Users\Bill\foo` on Windows but only `/home/bill/Foo` on Linux. +## Hiding segments + +### Conditionally + +To hide a whole segment including the leading and trailing symbol based on a [template][templates], the template must +**evaluate to an empty string**. This can be achieved with conditional statements (`if`). The example below will render +a diamond segment, only if the environment variable `POSH_ENV` is not empty. + +Only spaces are excluded, meaning you can still add line breaks and tabs if that is something you're after. + +```json +{ + "type": "text", + "style": "diamond", + "leading_diamond": " \ue0b6", + "trailing_diamond": "\ue0b4", + "foreground": "#ffffff", + "background": "#d53c14", + "template": "{{ if .Env.POSH_ENV }} \uf8c5 {{ .Env.POSH_ENV }} {{ end }}" +} +``` + +### On the fly + +Sometimes run into a situation where you don't want to see a specific segment but the use-case does not justify +using a conditional template. In this case you can use the `oh-my-posh toggle ` command to toggle the +segment on or off. This works on a **per shell session basis**, meaning that if you toggle a segment off in one instance +of a shell, it will not disable in the others. + +To list the currently toggled segments, use `oh-my-posh get toggles`. + [segments]: /docs/segments/angular [properties]: #properties [style]: #style @@ -153,6 +184,6 @@ This means that for user Bill, who has a user account `Bill` on Windows and `bil [go-text-template]: https://golang.org/pkg/text/template/ [sprig]: https://masterminds.github.io/sprig/ [regex]: https://www.regular-expressions.info/tutorial.html -[templates]: /docs/configuration/templates +[templates]: templates.mdx [color-templates]: /docs/configuration/colors#color-templates [cstp]: templates.mdx#cross-segment-template-properties diff --git a/website/docs/configuration/templates.mdx b/website/docs/configuration/templates.mdx index 08eeb019..84a03bc2 100644 --- a/website/docs/configuration/templates.mdx +++ b/website/docs/configuration/templates.mdx @@ -206,30 +206,10 @@ You can make use of the following syntax to decorate text: This can be used in templates and icons/text inside your config. -## Hiding segments - -To hide a whole segment including the leading and trailing symbol based on a template, the template must render into -an empty string. This can be achieved with conditional statements (`if`). The example below will render a diamond -segment, only if the environment variable `POSH_ENV` is not empty. - -Only spaces are excluded, meaning you can still add line breaks and tabs if that is something you're after. - -```json -{ - "type": "text", - "style": "diamond", - "leading_diamond": " \ue0b6", - "trailing_diamond": "\ue0b4", - "foreground": "#ffffff", - "background": "#d53c14", - "template": "{{ if .Env.POSH_ENV }} \uf8c5 {{ .Env.POSH_ENV }} {{ end }}" -} -``` - [terminal-list-hyperlinks]: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda [path-segment]: /docs/path [git-segment]: /docs/git -[go-text-template]: https://golang.org/pkg/text/template/ +[go-text-template]: https://golang.org/pkg/text/template/eg [sprig]: https://masterminds.github.io/sprig/ [glob]: https://pkg.go.dev/path/filepath#Glob [git]: /docs/segments/git