Repository: JanDeDobbeleer/oh-my-posh
Pull request #539 (2021-03-17 11:49:44)

feat(path): correct drive root on Windows
### Prerequisites

- [x] I have read and understand the `CONTRIBUTING` guide
- [x] The commit message follows the [conventional commits][cc] guidelines
- [x] Tests for the changes have been added (for bug fixes / features)
- [x] Docs have been added / updated (for bug fixes / features)

### Description

[Description of the change]

[cc]: https://www.conventionalcommits.org/en/v1.0.0/#summary



Patch:
diff --git a/src/segment_path.go b/src/segment_path.go
index 28bca623..43c7526d 100644
--- a/src/segment_path.go
+++ b/src/segment_path.go
@@ -69,7 +69,7 @@ func (pt *path) string() string {
 	default:
 		return fmt.Sprintf("Path style: %s is not available", style)
 	}
-
+	formattedPath = pt.formatWindowsDrive(formattedPath)
 	if pt.props.getBool(EnableHyperlink, false) {
 		// wsl check
 		if pt.env.isWsl() {
@@ -77,10 +77,16 @@ func (pt *path) string() string {
 		}
 		return fmt.Sprintf("[%s](file://%s)", formattedPath, cwd)
 	}
-
 	return formattedPath
 }
 
+func (pt *path) formatWindowsDrive(pwd string) string {
+	if pt.env.getRuntimeGOOS() != windowsPlatform || !strings.HasSuffix(pwd, ":") {
+		return pwd
+	}
+	return pwd + "\\"
+}
+
 func (pt *path) init(props *properties, env environmentInfo) {
 	pt.props = props
 	pt.env = env
@@ -210,6 +216,9 @@ func (pt *path) replaceMappedLocations(pwd string) string {
 
 func (pt *path) replaceFolderSeparators(pwd string) string {
 	defaultSeparator := pt.env.getPathSeperator()
+	if pwd == defaultSeparator {
+		return pwd
+	}
 	folderSeparator := pt.props.getString(FolderSeparatorIcon, defaultSeparator)
 	if folderSeparator == defaultSeparator {
 		return pwd
@@ -244,16 +253,19 @@ func (pt *path) pathDepth(pwd string) int {
 
 // Base returns the last element of path.
 // Trailing path separators are removed before extracting the last element.
-// If the path is empty, Base returns ".".
 // If the path consists entirely of separators, Base returns a single separator.
 func base(path string, env environmentInfo) string {
-	if path == "" {
-		return "."
+	if path == "/" {
+		return path
 	}
+	volumeName := filepath.VolumeName(path)
 	// Strip trailing slashes.
 	for len(path) > 0 && string(path[len(path)-1]) == env.getPathSeperator() {
 		path = path[0 : len(path)-1]
 	}
+	if volumeName == path {
+		return path
+	}
 	// Throw away volume name
 	path = path[len(filepath.VolumeName(path)):]
 	// Find the last element


Test patch:
diff --git a/src/segment_command_test.go b/src/segment_command_test.go
index fd5f3a62..ebe8be4e 100644
--- a/src/segment_command_test.go
+++ b/src/segment_command_test.go
@@ -1,3 +1,5 @@
+// +build !windows
+
 package main
 
 import (
diff --git a/src/segment_path_test.go b/src/segment_path_test.go
index 4294ebce..2b3d18cf 100644
--- a/src/segment_path_test.go
+++ b/src/segment_path_test.go
@@ -269,6 +269,7 @@ func TestAgnosterPathStyles(t *testing.T) {
 		HomeIcon            string
 		FolderSeparatorIcon string
 		Style               string
+		GOOS                string
 	}{
 		{Style: AgnosterFull, Expected: "usr > location > whatever", HomePath: "/usr/home", Pwd: "/usr/location/whatever", PathSeperator: "/", FolderSeparatorIcon: " > "},
 		{Style: AgnosterShort, Expected: "usr > .. > man", HomePath: "/usr/home", Pwd: "/usr/location/whatever/man", PathSeperator: "/", FolderSeparatorIcon: " > "},
@@ -289,6 +290,7 @@ func TestAgnosterPathStyles(t *testing.T) {
 		env.On("getPathSeperator", nil).Return(tc.PathSeperator)
 		env.On("homeDir", nil).Return(tc.HomePath)
 		env.On("getcwd", nil).Return(tc.Pwd)
+		env.On("getRuntimeGOOS", nil).Return(tc.GOOS)
 		args := &args{
 			PSWD: &tc.Pswd,
 		}
@@ -315,7 +317,10 @@ func TestGetFullPath(t *testing.T) {
 		Pswd                   string
 		Expected               string
 		DisableMappedLocations bool
+		GOOS                   string
+		PathSeparator          string
 	}{
+		{Style: Full, FolderSeparatorIcon: "|", Pwd: "/", Expected: "/"},
 		{Style: Full, Pwd: "", Expected: ""},
 		{Style: Full, Pwd: "/", Expected: "/"},
 		{Style: Full, Pwd: "/usr/home", Expected: "~"},
@@ -324,32 +329,38 @@ func TestGetFullPath(t *testing.T) {
 		{Style: Full, Pwd: "/a/b/c/d", Expected: "/a/b/c/d"},
 
 		{Style: Full, FolderSeparatorIcon: "|", Pwd: "", Expected: ""},
-		{Style: Full, FolderSeparatorIcon: "|", Pwd: "/", Expected: "|"},
 		{Style: Full, FolderSeparatorIcon: "|", Pwd: "/usr/home", Expected: "~"},
 		{Style: Full, FolderSeparatorIcon: "|", Pwd: "/usr/home", Expected: "|usr|home", DisableMappedLocations: true},
 		{Style: Full, FolderSeparatorIcon: "|", Pwd: "/usr/home/abc", Expected: "~|abc"},
 		{Style: Full, FolderSeparatorIcon: "|", Pwd: "/a/b/c/d", Expected: "|a|b|c|d"},
 
-		{Style: Folder, Pwd: "", Expected: "."},
+		{Style: Folder, Pwd: "", Expected: ""},
 		{Style: Folder, Pwd: "/", Expected: "/"},
 		{Style: Folder, Pwd: "/usr/home", Expected: "~"},
 		{Style: Folder, Pwd: "/usr/home", Expected: "home", DisableMappedLocations: true},
 		{Style: Folder, Pwd: "/usr/home/abc", Expected: "abc"},
 		{Style: Folder, Pwd: "/a/b/c/d", Expected: "d"},
 
-		{Style: Folder, FolderSeparatorIcon: "|", Pwd: "", Expected: "."},
-		{Style: Folder, FolderSeparatorIcon: "|", Pwd: "/", Expected: "|"},
+		{Style: Folder, FolderSeparatorIcon: "|", Pwd: "", Expected: ""},
+		{Style: Folder, FolderSeparatorIcon: "|", Pwd: "/", Expected: "/"},
 		{Style: Folder, FolderSeparatorIcon: "|", Pwd: "/usr/home", Expected: "~"},
 		{Style: Folder, FolderSeparatorIcon: "|", Pwd: "/usr/home", Expected: "home", DisableMappedLocations: true},
 		{Style: Folder, FolderSeparatorIcon: "|", Pwd: "/usr/home/abc", Expected: "abc"},
 		{Style: Folder, FolderSeparatorIcon: "|", Pwd: "/a/b/c/d", Expected: "d"},
+
+		{Style: Folder, FolderSeparatorIcon: "\\", Pwd: "C:\\", Expected: "C:\\", PathSeparator: "\\", GOOS: windowsPlatform},
+		{Style: Full, FolderSeparatorIcon: "\\", Pwd: "C:\\Users\\Jan", Expected: "C:\\Users\\Jan", PathSeparator: "\\", GOOS: windowsPlatform},
 	}
 
 	for _, tc := range cases {
 		env := new(MockedEnvironment)
-		env.On("getPathSeperator", nil).Return("/")
+		if len(tc.PathSeparator) == 0 {
+			tc.PathSeparator = "/"
+		}
+		env.On("getPathSeperator", nil).Return(tc.PathSeparator)
 		env.On("homeDir", nil).Return("/usr/home")
 		env.On("getcwd", nil).Return(tc.Pwd)
+		env.On("getRuntimeGOOS", nil).Return(tc.GOOS)
 		args := &args{
 			PSWD: &tc.Pswd,
 		}