diff --git a/docs/docs/segment-node.md b/docs/docs/segment-node.md index be998cbf..5b481ee6 100644 --- a/docs/docs/segment-node.md +++ b/docs/docs/segment-node.md @@ -26,18 +26,11 @@ Display the currently active node version. ## Properties - home_enabled: `boolean` - display the segment in the HOME folder or not - defaults to `false` -- display_version: `boolean` - display the node version - defaults to `true` -- display_error: `boolean` - show the error context when failing to retrieve the version information - defaults to `true` - missing_command_text: `string` - text to display when the command is missing - defaults to empty - display_mode: `string` - determines when the segment is displayed - `always`: The segment is always displayed - `files`: The segment is only displayed when `*.js`, `*.ts`, or `package.json` files are present (default) -- enable_version_mismatch: `boolean` - color the segment when the version in `.nvmrc` doesn't match the -returned node version -- color_background: `boolean` - color the background or foreground for `version_mismatch_color` - defaults to `false` -- version_mismatch_color: `string` [color][colors] - the color to use for `enable_version_mismatch` - defaults to -segment's background or foreground color -- display_package_manager: `boolean` - show whether the current project uses Yarn or NPM - defaults to `false` +- fetch_package_manager: `boolean` - define if the current project uses Yarn or NPM - defaults to `false` - yarn_icon: `string` - the icon/text to display when using Yarn - defaults to ` \uF61A` - npm_icon: `string` - the icon/text to display when using NPM - defaults to ` \uE71E` - template: `string` - A go [text/template][go-text-template] template extended with [sprig][sprig] utilizing the @@ -52,6 +45,8 @@ properties below. Defaults to `{{ .Full }}` - `.Prerelease`: `string` - prerelease info text - `.BuildMetadata`: `string` - build metadata - `.Error`: `string` - when fetching the version string errors +- `.PackageManagerIcon`: `string` - the Yarn on NPM icon when setting `fetch_package_manager` to `true` +- `.Mismatch`: `boolean` - if the version in `.nvmrc` matches with `.Full` [go-text-template]: https://golang.org/pkg/text/template/ [sprig]: https://masterminds.github.io/sprig/ diff --git a/src/config.go b/src/config.go index 273c66c9..8a48c93c 100644 --- a/src/config.go +++ b/src/config.go @@ -225,8 +225,8 @@ func getDefaultConfig(info string) *Config { Background: "#6CA35E", Foreground: "#ffffff", Properties: map[Property]interface{}{ - Prefix: " \uE718", - DisplayVersion: false, + Prefix: " \uE718", + FetchVersion: false, }, }, { diff --git a/src/segment_deprecated.go b/src/segment_deprecated.go index e993af5f..6436799c 100644 --- a/src/segment_deprecated.go +++ b/src/segment_deprecated.go @@ -312,10 +312,14 @@ func (s *session) getFormattedText() string { const ( // DisplayVersion show the version number or not DisplayVersion Property = "display_version" + // VersionMismatchColor displays empty string by default + VersionMismatchColor Property = "version_mismatch_color" + // EnableVersionMismatch displays empty string by default + EnableVersionMismatch Property = "enable_version_mismatch" ) func (l *language) string() string { - if !l.props.getBool(DisplayVersion, true) { + if !l.props.getOneOfBool(FetchVersion, DisplayVersion, true) { return "" } @@ -367,6 +371,14 @@ func (l *language) string() string { return text } +func (l *language) colorMismatch() { + if l.props.getBool(ColorBackground, false) { + l.props[BackgroundOverride] = l.props.getColor(VersionMismatchColor, l.props.getColor(BackgroundOverride, "")) + return + } + l.props[ForegroundOverride] = l.props.getColor(VersionMismatchColor, l.props.getColor(ForegroundOverride, "")) +} + // Python const ( @@ -384,3 +396,10 @@ func (p *python) legacyString() string { } return fmt.Sprintf("%s %s", p.Venv, version) } + +// Node + +const ( + // DisplayPackageManager shows if NPM or Yarn is used + DisplayPackageManager Property = "display_package_manager" +) diff --git a/src/segment_deprecated_test.go b/src/segment_deprecated_test.go index b6f889ba..5f230048 100644 --- a/src/segment_deprecated_test.go +++ b/src/segment_deprecated_test.go @@ -597,6 +597,64 @@ func TestPropertySessionSegment(t *testing.T) { } } +// Language + +func TestLanguageVersionMismatch(t *testing.T) { + cases := []struct { + Case string + Enabled bool + Mismatch bool + ExpectedColor string + ColorBackground bool + }{ + {Case: "Mismatch - Foreground color", Enabled: true, Mismatch: true, ExpectedColor: "#566777"}, + {Case: "Mismatch - Background color", Enabled: true, Mismatch: true, ExpectedColor: "#566777", ColorBackground: true}, + {Case: "Disabled", Enabled: false}, + {Case: "No mismatch", Enabled: true, Mismatch: false}, + } + for _, tc := range cases { + props := map[Property]interface{}{ + EnableVersionMismatch: tc.Enabled, + VersionMismatchColor: tc.ExpectedColor, + ColorBackground: tc.ColorBackground, + } + var matchesVersionFile func() bool + switch tc.Mismatch { + case true: + matchesVersionFile = func() bool { + return false + } + default: + matchesVersionFile = func() bool { + return true + } + } + args := &languageArgs{ + commands: []*cmd{ + { + executable: "unicorn", + args: []string{"--version"}, + regex: "(?P.*)", + }, + }, + extensions: []string{uni, corn}, + enabledExtensions: []string{uni, corn}, + enabledCommands: []string{"unicorn"}, + version: universion, + properties: props, + matchesVersionFile: matchesVersionFile, + } + lang := bootStrapLanguageTest(args) + assert.True(t, lang.enabled(), tc.Case) + assert.Equal(t, universion, lang.string(), tc.Case) + if tc.ColorBackground { + assert.Equal(t, tc.ExpectedColor, lang.props[BackgroundOverride], tc.Case) + return + } + assert.Equal(t, tc.ExpectedColor, lang.props.getColor(ForegroundOverride, ""), tc.Case) + } +} + // Python func TestPythonVirtualEnv(t *testing.T) { @@ -608,7 +666,7 @@ func TestPythonVirtualEnv(t *testing.T) { CondaEnvName string CondaDefaultEnvName string PyEnvName string - DisplayVersion bool + FetchVersion bool DisplayDefault bool }{ {Case: "VENV", Expected: "VENV", VirtualEnvName: "VENV"}, @@ -617,7 +675,7 @@ func TestPythonVirtualEnv(t *testing.T) { {Case: "Display Base", Expected: "base", CondaDefaultEnvName: "base", DisplayDefault: true}, {Case: "Hide base", Expected: "", CondaDefaultEnvName: "base", ExpectedDisabled: true}, {Case: "PYENV", Expected: "PYENV", PyEnvName: "PYENV"}, - {Case: "PYENV Version", Expected: "PYENV 3.8.4", PyEnvName: "PYENV", DisplayVersion: true}, + {Case: "PYENV Version", Expected: "PYENV 3.8.4", PyEnvName: "PYENV", FetchVersion: true}, } for _, tc := range cases { @@ -633,7 +691,7 @@ func TestPythonVirtualEnv(t *testing.T) { env.On("getcwd", nil).Return("/usr/home/project") env.On("homeDir", nil).Return("/usr/home") var props properties = map[Property]interface{}{ - DisplayVersion: tc.DisplayVersion, + FetchVersion: tc.FetchVersion, DisplayVirtualEnv: true, DisplayDefault: tc.DisplayDefault, } diff --git a/src/segment_dotnet_test.go b/src/segment_dotnet_test.go index 37d89bbb..e862b1e1 100644 --- a/src/segment_dotnet_test.go +++ b/src/segment_dotnet_test.go @@ -29,7 +29,7 @@ func bootStrapDotnetTest(args *dotnetArgs) *dotnet { env.On("getcwd", nil).Return("/usr/home/project") env.On("homeDir", nil).Return("/usr/home") var props properties = map[Property]interface{}{ - DisplayVersion: args.displayVersion, + FetchVersion: args.displayVersion, UnsupportedDotnetVersionIcon: args.unsupportedIcon, } dotnet := &dotnet{} diff --git a/src/segment_golang_test.go b/src/segment_golang_test.go index 5391a915..e95976dd 100644 --- a/src/segment_golang_test.go +++ b/src/segment_golang_test.go @@ -22,7 +22,7 @@ func getMockedLanguageEnv(params *mockedLanguageParams) (*MockedEnvironment, pro env.On("getcwd", nil).Return("/usr/home/project") env.On("homeDir", nil).Return("/usr/home") var props properties = map[Property]interface{}{ - DisplayVersion: true, + FetchVersion: true, } return env, props } diff --git a/src/segment_java_test.go b/src/segment_java_test.go index f3829153..590ba032 100644 --- a/src/segment_java_test.go +++ b/src/segment_java_test.go @@ -67,7 +67,7 @@ func TestJava(t *testing.T) { env.On("getenv", "JAVA_HOME").Return("") } var props properties = map[Property]interface{}{ - DisplayVersion: true, + FetchVersion: true, } j := &java{} j.init(props, env) diff --git a/src/segment_language.go b/src/segment_language.go index ce256377..998c13e7 100644 --- a/src/segment_language.go +++ b/src/segment_language.go @@ -58,7 +58,8 @@ type language struct { displayMode string version - Error string + Error string + Mismatch bool } const ( @@ -74,10 +75,6 @@ const ( DisplayModeContext string = "context" // MissingCommandText sets the text to display when the command is not present in the system MissingCommandText Property = "missing_command_text" - // VersionMismatchColor displays empty string by default - VersionMismatchColor Property = "version_mismatch_color" - // EnableVersionMismatch displays empty string by default - EnableVersionMismatch Property = "enable_version_mismatch" // HomeEnabled displays the segment in the HOME folder or not HomeEnabled Property = "home_enabled" // LanguageExtensions the list of extensions to validate @@ -205,14 +202,14 @@ func (l *language) inLanguageContext() bool { } func (l *language) setVersionFileMismatch() { - if l.matchesVersionFile == nil || l.matchesVersionFile() { + if l.matchesVersionFile == nil { return } - if l.props.getBool(ColorBackground, false) { - l.props[BackgroundOverride] = l.props.getColor(VersionMismatchColor, l.props.getColor(BackgroundOverride, "")) + l.Mismatch = !l.matchesVersionFile() + if !l.Mismatch { return } - l.props[ForegroundOverride] = l.props.getColor(VersionMismatchColor, l.props.getColor(ForegroundOverride, "")) + l.colorMismatch() } func (l *language) buildVersionURL(text string) string { diff --git a/src/segment_language_test.go b/src/segment_language_test.go index 529f2d04..d5c0f6a1 100644 --- a/src/segment_language_test.go +++ b/src/segment_language_test.go @@ -79,7 +79,7 @@ func TestLanguageFilesFoundButNoCommandAndVersionAndDisplayVersion(t *testing.T) func TestLanguageFilesFoundButNoCommandAndVersionAndDontDisplayVersion(t *testing.T) { props := map[Property]interface{}{ - DisplayVersion: false, + FetchVersion: false, } args := &languageArgs{ commands: []*cmd{ @@ -229,7 +229,7 @@ func TestLanguageEnabledAllExtensionsFound(t *testing.T) { func TestLanguageEnabledNoVersion(t *testing.T) { props := map[Property]interface{}{ - DisplayVersion: false, + FetchVersion: false, } args := &languageArgs{ commands: []*cmd{ @@ -252,7 +252,7 @@ func TestLanguageEnabledNoVersion(t *testing.T) { func TestLanguageEnabledMissingCommand(t *testing.T) { props := map[Property]interface{}{ - DisplayVersion: false, + FetchVersion: false, } args := &languageArgs{ commands: []*cmd{}, @@ -269,7 +269,7 @@ func TestLanguageEnabledMissingCommand(t *testing.T) { func TestLanguageEnabledNoVersionData(t *testing.T) { props := map[Property]interface{}{ - DisplayVersion: true, + FetchVersion: true, } args := &languageArgs{ commands: []*cmd{ @@ -496,59 +496,3 @@ func TestLanguageHyperlinkEnabledMoreParamInTemplate(t *testing.T) { assert.True(t, lang.enabled()) assert.Equal(t, "1.3.307", lang.string()) } - -func TestLanguageVersionMismatch(t *testing.T) { - cases := []struct { - Case string - Enabled bool - Mismatch bool - ExpectedColor string - ColorBackground bool - }{ - {Case: "Disabled", Enabled: false}, - {Case: "Mismatch - Foreground color", Enabled: true, Mismatch: true, ExpectedColor: "#566777"}, - {Case: "Mismatch - Background color", Enabled: true, Mismatch: true, ExpectedColor: "#566777", ColorBackground: true}, - {Case: "No mismatch", Enabled: true, Mismatch: false}, - } - for _, tc := range cases { - props := map[Property]interface{}{ - EnableVersionMismatch: tc.Enabled, - VersionMismatchColor: tc.ExpectedColor, - ColorBackground: tc.ColorBackground, - } - var matchesVersionFile func() bool - switch tc.Mismatch { - case true: - matchesVersionFile = func() bool { - return false - } - default: - matchesVersionFile = func() bool { - return true - } - } - args := &languageArgs{ - commands: []*cmd{ - { - executable: "unicorn", - args: []string{"--version"}, - regex: "(?P.*)", - }, - }, - extensions: []string{uni, corn}, - enabledExtensions: []string{uni, corn}, - enabledCommands: []string{"unicorn"}, - version: universion, - properties: props, - matchesVersionFile: matchesVersionFile, - } - lang := bootStrapLanguageTest(args) - assert.True(t, lang.enabled(), tc.Case) - assert.Equal(t, universion, lang.string(), tc.Case) - if tc.ColorBackground { - assert.Equal(t, tc.ExpectedColor, lang.props[BackgroundOverride], tc.Case) - return - } - assert.Equal(t, tc.ExpectedColor, lang.props.getColor(ForegroundOverride, ""), tc.Case) - } -} diff --git a/src/segment_node.go b/src/segment_node.go index 1a3fc1f1..6c7203bf 100644 --- a/src/segment_node.go +++ b/src/segment_node.go @@ -3,9 +3,9 @@ package main import "fmt" type node struct { - packageManagerIcon string - language + + PackageManagerIcon string } const ( @@ -13,13 +13,17 @@ const ( YarnIcon Property = "yarn_icon" // NPMIcon illustrates NPM is used NPMIcon Property = "npm_icon" - // DisplayPackageManager shows if NPM or Yarn is used - DisplayPackageManager Property = "display_package_manager" + // FetchPackageManager shows if NPM or Yarn is used + FetchPackageManager Property = "fetch_package_manager" ) func (n *node) string() string { - version := n.language.string() - return fmt.Sprintf("%s%s", version, n.packageManagerIcon) + segmentTemplate := n.language.props.getString(SegmentTemplate, "") + if len(segmentTemplate) == 0 { + version := n.language.string() + return fmt.Sprintf("%s%s", version, n.PackageManagerIcon) + } + return n.language.renderTemplate(segmentTemplate, n) } func (n *node) init(props properties, env environmentInfo) { @@ -45,15 +49,15 @@ func (n *node) enabled() bool { } func (n *node) loadContext() { - if !n.language.props.getBool(DisplayPackageManager, false) { + if !n.language.props.getOneOfBool(FetchPackageManager, DisplayPackageManager, false) { return } if n.language.env.hasFiles("yarn.lock") { - n.packageManagerIcon = n.language.props.getString(YarnIcon, " \uF61A") + n.PackageManagerIcon = n.language.props.getString(YarnIcon, " \uF61A") return } if n.language.env.hasFiles("package-lock.json") || n.language.env.hasFiles("package.json") { - n.packageManagerIcon = n.language.props.getString(NPMIcon, " \uE71E") + n.PackageManagerIcon = n.language.props.getString(NPMIcon, " \uE71E") } } diff --git a/src/segment_node_test.go b/src/segment_node_test.go index ecc183f3..239c509b 100644 --- a/src/segment_node_test.go +++ b/src/segment_node_test.go @@ -75,6 +75,6 @@ func TestNodeInContext(t *testing.T) { }, } node.loadContext() - assert.Equal(t, tc.ExpectedString, node.packageManagerIcon, tc.Case) + assert.Equal(t, tc.ExpectedString, node.PackageManagerIcon, tc.Case) } } diff --git a/src/segment_ruby_test.go b/src/segment_ruby_test.go index cdcabd0e..ebcd9043 100644 --- a/src/segment_ruby_test.go +++ b/src/segment_ruby_test.go @@ -21,19 +21,19 @@ func TestRuby(t *testing.T) { HasRubyFiles bool HasRakeFile bool HasGemFile bool - DisplayVersion bool + FetchVersion bool }{ {Case: "No files", ExpectedString: "", ExpectedEnabled: false}, - {Case: "Ruby files", ExpectedString: "", ExpectedEnabled: true, DisplayVersion: false, HasRubyFiles: true}, - {Case: "Rakefile", ExpectedString: "", ExpectedEnabled: true, DisplayVersion: false, HasRakeFile: true}, - {Case: "Gemfile", ExpectedString: "", ExpectedEnabled: true, DisplayVersion: false, HasGemFile: true}, - {Case: "Gemfile with version", ExpectedString: "", ExpectedEnabled: true, DisplayVersion: true, HasGemFile: true}, - {Case: "No files with version", ExpectedString: "", ExpectedEnabled: false, DisplayVersion: true}, + {Case: "Ruby files", ExpectedString: "", ExpectedEnabled: true, FetchVersion: false, HasRubyFiles: true}, + {Case: "Rakefile", ExpectedString: "", ExpectedEnabled: true, FetchVersion: false, HasRakeFile: true}, + {Case: "Gemfile", ExpectedString: "", ExpectedEnabled: true, FetchVersion: false, HasGemFile: true}, + {Case: "Gemfile with version", ExpectedString: "", ExpectedEnabled: true, FetchVersion: true, HasGemFile: true}, + {Case: "No files with version", ExpectedString: "", ExpectedEnabled: false, FetchVersion: true}, { Case: "Version with chruby", ExpectedString: "ruby-2.6.3", ExpectedEnabled: true, - DisplayVersion: true, + FetchVersion: true, HasRubyFiles: true, HasChruby: true, Version: ` * ruby-2.6.3 @@ -45,7 +45,7 @@ func TestRuby(t *testing.T) { Case: "Version with chruby line 2", ExpectedString: "ruby-1.9.3-p392", ExpectedEnabled: true, - DisplayVersion: true, + FetchVersion: true, HasRubyFiles: true, HasChruby: true, Version: ` ruby-2.6.3 @@ -57,7 +57,7 @@ func TestRuby(t *testing.T) { Case: "Version with asdf", ExpectedString: "2.6.3", ExpectedEnabled: true, - DisplayVersion: true, + FetchVersion: true, HasRubyFiles: true, HasAsdf: true, Version: "ruby 2.6.3 /Users/jan/Projects/oh-my-posh/.tool-versions", @@ -66,7 +66,7 @@ func TestRuby(t *testing.T) { Case: "Version with asdf not set", ExpectedString: "", ExpectedEnabled: true, - DisplayVersion: true, + FetchVersion: true, HasRubyFiles: true, HasAsdf: true, Version: "ruby ______ No version set. Run \"asdf ruby \"", @@ -75,7 +75,7 @@ func TestRuby(t *testing.T) { Case: "Version with ruby", ExpectedString: "2.6.3", ExpectedEnabled: true, - DisplayVersion: true, + FetchVersion: true, HasRubyFiles: true, HasRuby: true, Version: "ruby 2.6.3 (2019-04-16 revision 67580) [universal.x86_64-darwin20]", @@ -99,7 +99,7 @@ func TestRuby(t *testing.T) { env.On("getcwd", nil).Return("/usr/home/project") env.On("homeDir", nil).Return("/usr/home") var props properties = map[Property]interface{}{ - DisplayVersion: tc.DisplayVersion, + FetchVersion: tc.FetchVersion, } ruby := &ruby{} ruby.init(props, env) diff --git a/themes/schema.json b/themes/schema.json index 7eaefc57..bc08243d 100644 --- a/themes/schema.json +++ b/themes/schema.json @@ -33,10 +33,10 @@ "type": "string" } }, - "display_version": { + "fetch_version": { "type": "boolean", - "title": "Display Version", - "description": "Show or hide the version number", + "title": "Fetch Version", + "description": "Fetch the version number", "default": true }, "enable_hyperlink": { @@ -402,8 +402,8 @@ "description": "Text/icon that is displayed when the active .NET SDK version (e.g., one specified by global.json) is not installed/supported", "default": " \uE77F " }, - "display_version": { - "$ref": "#/definitions/display_version" + "fetch_version": { + "$ref": "#/definitions/fetch_version" }, "display_mode": { "$ref": "#/definitions/display_mode" @@ -635,8 +635,8 @@ "properties": { "properties": { "properties": { - "display_version": { - "$ref": "#/definitions/display_version" + "fetch_version": { + "$ref": "#/definitions/fetch_version" }, "display_mode": { "$ref": "#/definitions/display_mode" @@ -664,8 +664,8 @@ "properties": { "properties": { "properties": { - "display_version": { - "$ref": "#/definitions/display_version" + "fetch_version": { + "$ref": "#/definitions/fetch_version" }, "display_mode": { "$ref": "#/definitions/display_mode" @@ -693,8 +693,8 @@ "properties": { "properties": { "properties": { - "display_version": { - "$ref": "#/definitions/display_version" + "fetch_version": { + "$ref": "#/definitions/fetch_version" }, "display_mode": { "$ref": "#/definitions/display_mode" @@ -722,8 +722,8 @@ "properties": { "properties": { "properties": { - "display_version": { - "$ref": "#/definitions/display_version" + "fetch_version": { + "$ref": "#/definitions/fetch_version" }, "display_mode": { "$ref": "#/definitions/display_mode" @@ -751,8 +751,8 @@ "properties": { "properties": { "properties": { - "display_version": { - "$ref": "#/definitions/display_version" + "fetch_version": { + "$ref": "#/definitions/fetch_version" }, "display_mode": { "$ref": "#/definitions/display_mode" @@ -780,8 +780,8 @@ "properties": { "properties": { "properties": { - "display_version": { - "$ref": "#/definitions/display_version" + "fetch_version": { + "$ref": "#/definitions/fetch_version" }, "display_mode": { "$ref": "#/definitions/display_mode" @@ -806,8 +806,8 @@ "properties": { "properties": { "properties": { - "display_version": { - "$ref": "#/definitions/display_version" + "fetch_version": { + "$ref": "#/definitions/fetch_version" }, "display_mode": { "$ref": "#/definitions/display_mode" @@ -832,8 +832,8 @@ "properties": { "properties": { "properties": { - "display_version": { - "$ref": "#/definitions/display_version" + "fetch_version": { + "$ref": "#/definitions/fetch_version" }, "display_mode": { "$ref": "#/definitions/display_mode" @@ -916,8 +916,11 @@ "properties": { "properties": { "properties": { - "display_version": { - "$ref": "#/definitions/display_version" + "template": { + "$ref": "#/definitions/template" + }, + "fetch_version": { + "$ref": "#/definitions/fetch_version" }, "display_mode": { "$ref": "#/definitions/display_mode" @@ -925,10 +928,10 @@ "missing_command_text": { "$ref": "#/definitions/missing_command_text" }, - "display_package_manager": { + "fetch_package_manager": { "type": "boolean", - "title": "Display Package Manager", - "description": "Show whether the current project uses Yarn or NPM", + "title": "Fetch Display Package Manager", + "description": "Assigns the Yarn or NPM icon to .PackageManagerIcon", "default": false }, "yarn_icon": { @@ -963,8 +966,8 @@ "properties": { "properties": { "properties": { - "display_version": { - "$ref": "#/definitions/display_version" + "fetch_version": { + "$ref": "#/definitions/fetch_version" }, "display_mode": { "$ref": "#/definitions/display_mode" @@ -1633,8 +1636,8 @@ "properties": { "properties": { "properties": { - "display_version": { - "$ref": "#/definitions/display_version" + "fetch_version": { + "$ref": "#/definitions/fetch_version" }, "display_mode": { "$ref": "#/definitions/display_mode"