diff --git a/src/config/segment_types.go b/src/config/segment_types.go index 63df09bdc91c..e73ea08e7409 100644 --- a/src/config/segment_types.go +++ b/src/config/segment_types.go @@ -227,6 +227,8 @@ const ( YTM SegmentType = "ytm" // ZIG writes the active zig version ZIG SegmentType = "zig" + // ZVM writes the active zig version used in the zvm environment + ZVM SegmentType = "zvm" ) // Segments contains all available prompt segment writers. @@ -331,6 +333,7 @@ var Segments = map[SegmentType]func() SegmentWriter{ YARN: func() SegmentWriter { return &segments.Yarn{} }, YTM: func() SegmentWriter { return &segments.Ytm{} }, ZIG: func() SegmentWriter { return &segments.Zig{} }, + ZVM: func() SegmentWriter { return &segments.Zvm{} }, } func (segment *Segment) MapSegmentWithWriter(env runtime.Environment) error { diff --git a/src/segments/zvm.go b/src/segments/zvm.go new file mode 100644 index 000000000000..eb6af1040659 --- /dev/null +++ b/src/segments/zvm.go @@ -0,0 +1,74 @@ +package segments + +import ( + "strings" + + "github.com/jandedobbeleer/oh-my-posh/src/properties" + "github.com/jandedobbeleer/oh-my-posh/src/runtime" +) + +type Zvm struct { + props properties.Properties + env runtime.Environment + + Version string + ZigIcon string +} + +func (z *Zvm) SetText(text string) { + z.Version = text +} + +func (z *Zvm) Text() string { + return z.Version +} + +const ( + ZvmIcon properties.Property = "zigicon" +) + +func (z *Zvm) Enabled() bool { + if !z.env.HasCommand("zvm") { + return false + } + version := z.getZvmVersion() + return version != "" +} + +func (z *Zvm) Template() string { + return " {{ if .ZigIcon }}{{ .ZigIcon }} {{ end }}{{ .Version }} " +} + +func (z *Zvm) Init(props properties.Properties, env runtime.Environment) { + z.props = props + z.env = env + + // Initialize the icon from properties + z.ZigIcon = z.props.GetString(ZvmIcon, "ZVM") + z.Version = z.getZvmVersion() +} + +func (z *Zvm) getZvmVersion() string { + output, err := z.env.RunCommand("zvm", "list") + if err != nil { + return "" + } + + // Split output into lines + lines := strings.Split(output, "\n") + + // Look for line containing green color code which indicates active version + // ANSI color code for green is typically \033[32m or \x1b[32m + for _, line := range lines { + if strings.Contains(line, "\x1b[32m") || strings.Contains(line, "\033[32m") { + // Clean ANSI color codes and whitespace + cleaned := strings.ReplaceAll(line, "\x1b[32m", "") + cleaned = strings.ReplaceAll(cleaned, "\033[32m", "") + cleaned = strings.ReplaceAll(cleaned, "\x1b[0m", "") + cleaned = strings.TrimSpace(cleaned) + + return cleaned + } + } + return "" +} diff --git a/src/segments/zvm_test.go b/src/segments/zvm_test.go new file mode 100644 index 000000000000..d9ec2a14c815 --- /dev/null +++ b/src/segments/zvm_test.go @@ -0,0 +1,80 @@ +package segments + +import ( + "testing" + + "github.com/jandedobbeleer/oh-my-posh/src/runtime/mock" + + "github.com/jandedobbeleer/oh-my-posh/src/properties" + "github.com/stretchr/testify/assert" +) + +func TestZvm(t *testing.T) { + cases := []struct { + Case string + ExpectedString string + HasCommand bool + ListOutput string + Properties properties.Map + Template string + }{ + { + Case: "no zvm command", + ExpectedString: "", + HasCommand: false, + ListOutput: "", + Properties: properties.Map{}, + Template: " {{ if .ZigIcon }}{{ .ZigIcon }} {{ end }}{{ .Version }} ", + }, + { + Case: "version 0.13.0 active", + ExpectedString: "0.13.0", + HasCommand: true, + ListOutput: "0.11.0\n\x1b[32m0.13.0\x1b[0m\n0.12.0", + Properties: properties.Map{}, + Template: " {{ if .ZigIcon }}{{ .ZigIcon }} {{ end }}{{ .Version }} ", + }, + { + Case: "version 0.13.0 active with icon", + ExpectedString: "0.13.0", + HasCommand: true, + ListOutput: "0.11.0\n\x1b[32m0.13.0\x1b[0m\n0.12.0", + Properties: properties.Map{ + ZvmIcon: "⚡", + }, + Template: " {{ if .ZigIcon }}{{ .ZigIcon }} {{ end }}{{ .Version }} ", + }, + { + Case: "version 0.12.0-dev active", + ExpectedString: "0.12.0-dev.1234+abcdef", + HasCommand: true, + ListOutput: "0.11.0\n\x1b[32m0.12.0-dev.1234+abcdef\x1b[0m\n0.12.0", + Properties: properties.Map{}, + // Change all test cases to expect the actual template + Template: " {{ if .ZigIcon }}{{ .ZigIcon }} {{ end }}{{ .Version }} ", + }, + } + + for _, tc := range cases { + t.Run(tc.Case, func(t *testing.T) { + env := new(mock.Environment) + env.On("HasCommand", "zvm").Return(tc.HasCommand) + env.On("RunCommand", "zvm", []string{"list"}).Return(tc.ListOutput, nil) + + zvm := &Zvm{} + zvm.Init(tc.Properties, env) + + assert.Equal(t, tc.Template, zvm.Template()) + + if tc.HasCommand { + assert.True(t, zvm.Enabled()) + assert.Equal(t, tc.ExpectedString, zvm.Version) + if icon, ok := tc.Properties[ZvmIcon]; ok { + assert.Equal(t, icon, zvm.ZigIcon) + } + } else { + assert.False(t, zvm.Enabled()) + } + }) + } +} diff --git a/themes/schema.json b/themes/schema.json index 1318b394b056..856de43f96d0 100644 --- a/themes/schema.json +++ b/themes/schema.json @@ -405,7 +405,8 @@ "xmake", "yarn", "ytm", - "zig" + "zig", + "zvm" ] }, "style": { @@ -4916,6 +4917,29 @@ } } }, + { + "if": { + "properties": { + "type": { "const": "zvm" } + } + }, + "then": { + "title": "ZVM Segment", + "description": "https://ohmyposh.dev/docs/zvm", + "properties": { + "properties": { + "properties": { + "zigicon": { + "type": "string", + "title": "Zig Icon", + "description": "icon to display before the version", + "default": "ZVM - " + } + } + } + } + } + }, { "if": { "properties": { diff --git a/website/docs/segments/cli/zvm.mdx b/website/docs/segments/cli/zvm.mdx new file mode 100644 index 000000000000..5a0219d4f4ab --- /dev/null +++ b/website/docs/segments/cli/zvm.mdx @@ -0,0 +1,35 @@ +--- +id: zvm +title: ZVM +sidebar_label: ZVM +--- + +## What + +Display the current Zig version being used by zvm (Zig Version Manager). + +## Sample Configuration + + +import Config from '@site/src/components/Config.js'; + + + + +## Properties + +| Name | Type | Description | +| --------- | -------- | -------------------------------------- | +| `zigicon` | `string` | The icon to display before the version | + + +[ZVM](https://github.com/tristanisham/zvm) diff --git a/website/sidebars.js b/website/sidebars.js index d3326e30ea8b..ef4893947d2e 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -91,6 +91,7 @@ module.exports = { "segments/cli/unity", "segments/cli/xmake", "segments/cli/yarn", + "segments/cli/zvm", ] }, {