Repository: JanDeDobbeleer/oh-my-posh
Pull request #3043 (2022-11-04 19:58:15)

evening everyone
### Prerequisites

- [x] I have read and understood the [contributing guide][CONTRIBUTING.md]
- [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

- fix(fish): split single string
- feat(path): replace child locations

<!---

Tips:

If you're not comfortable with working with Git, we're working a guide (https://ohmyposh.dev/docs/contributing_git) to help you out.
Oh My Posh advises GitKraken (https://www.gitkraken.com/invite/nQmDPR9D) as your preferred cross platform Git GUI power tool.

-->

[CONTRIBUTING.md]: https://github.com/JanDeDobbeleer/oh-my-posh/blob/main/CONTRIBUTING.md
[cc]: https://www.conventionalcommits.org/en/v1.0.0/#summary



Patch:
diff --git a/src/segments/path.go b/src/segments/path.go
index 447bc38b..f3a708e4 100644
--- a/src/segments/path.go
+++ b/src/segments/path.go
@@ -415,6 +415,10 @@ func (pt *Path) replaceMappedLocations() (string, string) {
 
 	for _, key := range keys {
 		keyRoot, keyRelative := pt.parsePath(key)
+		matchSubFolders := strings.HasSuffix(keyRelative, "*")
+		if matchSubFolders && len(keyRelative) > 1 {
+			keyRelative = keyRelative[0 : len(keyRelative)-1] // remove trailing /* or \*
+		}
 		if keyRoot != rootN || !strings.HasPrefix(relativeN, keyRelative) {
 			continue
 		}
@@ -429,7 +433,7 @@ func (pt *Path) replaceMappedLocations() (string, string) {
 			return value, strings.Trim(relative, pathSeparator)
 		}
 		// match several prefix elements
-		if overflow[0:1] == pt.env.PathSeparator() {
+		if matchSubFolders || overflow[0:1] == pt.env.PathSeparator() {
 			return value, strings.Trim(overflow, pathSeparator)
 		}
 	}
diff --git a/src/shell/scripts/omp.fish b/src/shell/scripts/omp.fish
index 02b9a2c2..fc3e30d8 100644
--- a/src/shell/scripts/omp.fish
+++ b/src/shell/scripts/omp.fish
@@ -72,7 +72,7 @@ end
 
 function _render_tooltip
   commandline --function expand-abbr
-  set omp_tooltip_command (commandline --current-buffer | string split --allow-empty -f1 ' ')
+  set omp_tooltip_command (commandline --current-buffer | string collect | string split --allow-empty -f1 ' ')
   commandline --insert " "
   commandline --function repaint
 end
diff --git a/website/docs/segments/path.mdx b/website/docs/segments/path.mdx
index d727188b..b539ed7e 100644
--- a/website/docs/segments/path.mdx
+++ b/website/docs/segments/path.mdx
@@ -63,12 +63,13 @@ For example, to swap out `C:\Users\Leet\GitHub` with a GitHub icon, you can do t
 
 ### Notes
 
-- To make mapped Locations work cross-platform, you should use `/` as the path separator, Oh My Posh will
+- To make mapped locations work cross-platform, use `/` as the path separator, Oh My Posh will
 automatically match effective separators based on the running operating system.
+- If you want to match all child directories, you can use `*` as a wildcard, for example:
+`"C:/Users/Bill/*": "$"` will turn `C:/Users/Bill/Downloads` into `$/Downloads`.
 - The character `~` at the start of a mapped location will match the user's home directory.
-- The match is case-insensitive on Windows and macOS, but case-sensitive on other operating systems.
-
-This means that for user Bill, who has a user account `Bill` on Windows and `bill` on Linux, `~/Foo` might match
+- The match is case-insensitive on Windows and macOS, but case-sensitive on other operating systems. 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.
 
 ## Style


Test patch:
diff --git a/src/segments/path_test.go b/src/segments/path_test.go
index 420f3e94..70fdebcf 100644
--- a/src/segments/path_test.go
+++ b/src/segments/path_test.go
@@ -1335,3 +1335,36 @@ func TestNormalizePath(t *testing.T) {
 		assert.Equal(t, tc.Expected, got)
 	}
 }
+
+func TestReplaceMappedLocations(t *testing.T) {
+	cases := []struct {
+		Case     string
+		Pwd      string
+		Expected string
+	}{
+		{Pwd: "/f/g/h", Expected: "/f/g/h"},
+		{Pwd: "/f/g/h/e", Expected: "^/e"},
+		{Pwd: "/a/b/c/d", Expected: "#"},
+		{Pwd: "/a/b/c/d/e", Expected: "#/e"},
+	}
+
+	for _, tc := range cases {
+		env := new(mock.MockedEnvironment)
+		env.On("PathSeparator").Return("/")
+		env.On("Pwd").Return(tc.Pwd)
+		env.On("Shell").Return(shell.FISH)
+		env.On("GOOS").Return(environment.DARWIN)
+		path := &Path{
+			env: env,
+			props: properties.Map{
+				MappedLocationsEnabled: false,
+				MappedLocations: map[string]string{
+					"/a/b/c/d": "#",
+					"/f/g/h/*": "^",
+				},
+			},
+		}
+		path.setPaths()
+		assert.Equal(t, tc.Expected, path.pwd)
+	}
+}