Repository: JanDeDobbeleer/oh-my-posh
Pull request #1846 (2022-03-01 06:09:13)

feat: add hide root to agnoster short
### Prerequisites

- [x] I have read and understood 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

Adds the `hide_root_location` toggle to Agnoster Short preventing it from displaying the root directory if it exceeds the `max_depth`. 

With `hide_root_location` true and `max_depth` of 2:
![image](https://user-images.githubusercontent.com/85419773/156113600-8775e115-7f63-4d07-8cb1-7d4fac7fe671.png)


Kind Regards,
Jed

[cc]: https://www.conventionalcommits.org/en/v1.0.0/#summary


jedwillick: I fixed the repeated logic but now im kinda thinking that maybe there should just be an option in agnoster_short to remove always showing the root folder. What are your thoughts?
JanDeDobbeleer: @jedwillick I would try it 😃
jedwillick: Updated PR. Added an `hide_root` option to `agnoster_short` instead of chagning `folder`.
jedwillick: Made requested changes.

- [x] Fixed typo (`boolen` -> `boolean`)
- [x] Changed `Agnoster Short` -> `agnoster_short`
- [x] Changed `hide_root` -> `hide_root_location`
- [x] Added comment to the magic part and flipped logic to hopefully make it more clear aswell
- [x] Also added a few more tests
JanDeDobbeleer: @jedwillick on a roll :-) Awesome tbh.

Patch:
diff --git a/docs/docs/segment-path.md b/docs/docs/segment-path.md
index 06e12209..a3c30904 100644
--- a/docs/docs/segment-path.md
+++ b/docs/docs/segment-path.md
@@ -35,7 +35,9 @@ Display the current path.
 - style: `enum` - how to display the current path
 - mixed_threshold: `number` - the maximum length of a path segment that will be displayed when using `Mixed` -
   defaults to `4`
-- max_depth: `number` - maximum path depth to display before shortening when using `Agnoster Short` - defaults to `1`
+- max_depth: `number` - maximum path depth to display before shortening when using `agnoster_short` - defaults to `1`
+- hide_root_location: `boolean` -  hides the root location if it doesn't fit in the last `max_depth` folders, when using
+  `agnoster_short` - defaults to `false`
 
 ## Mapped Locations
 
@@ -91,8 +93,8 @@ Renders each folder name separated by the `folder_separator_icon`.
 
 ### Agnoster Short
 
-When more than `max_depth` levels deep, it renders one `folder_icon` followed by the names of the last `max_depth` folders,
-separated by the `folder_separator_icon`.
+When more than `max_depth` levels deep, it renders one `folder_icon` (if `hide_root_location` is `false`) followed by
+the names of the last `max_depth` folders, separated by the `folder_separator_icon`.
 
 ### Agnoster Left
 
diff --git a/src/segments/path.go b/src/segments/path.go
index 7f4bb426..ada7d03e 100644
--- a/src/segments/path.go
+++ b/src/segments/path.go
@@ -56,6 +56,8 @@ const (
 	MappedLocationsEnabled properties.Property = "mapped_locations_enabled"
 	// MaxDepth Maximum path depth to display whithout shortening
 	MaxDepth properties.Property = "max_depth"
+	// Hides the root location if it doesn't fit in max_depth. Used in Agnoster Short
+	HideRootLocation properties.Property = "hide_root_location"
 )
 
 func (pt *Path) Template() string {
@@ -249,18 +251,28 @@ func (pt *Path) getAgnosterShortPath() string {
 	if maxDepth < 1 {
 		maxDepth = 1
 	}
+	hideRootLocation := pt.props.GetBool(HideRootLocation, false)
+	if hideRootLocation {
+		// 1-indexing to avoid showing the root location when exceeding the max depth
+		pathDepth++
+	}
 	if pathDepth <= maxDepth {
 		return pt.getAgnosterFullPath()
 	}
 	pathSeparator := pt.env.PathSeparator()
 	folderSeparator := pt.props.GetString(FolderSeparatorIcon, pathSeparator)
-	folderIcon := pt.props.GetString(FolderIcon, "..")
-	root := pt.rootLocation()
 	splitted := strings.Split(pwd, pathSeparator)
 	fullPathDepth := len(splitted)
 	splitPos := fullPathDepth - maxDepth
 	var buffer strings.Builder
-	buffer.WriteString(fmt.Sprintf("%s%s%s", root, folderSeparator, folderIcon))
+	if hideRootLocation {
+		buffer.WriteString(splitted[splitPos])
+		splitPos++
+	} else {
+		folderIcon := pt.props.GetString(FolderIcon, "..")
+		root := pt.rootLocation()
+		buffer.WriteString(fmt.Sprintf("%s%s%s", root, folderSeparator, folderIcon))
+	}
 	for i := splitPos; i < fullPathDepth; i++ {
 		buffer.WriteString(fmt.Sprintf("%s%s", folderSeparator, splitted[i]))
 	}
diff --git a/themes/schema.json b/themes/schema.json
index e8ee56fa..457a93ce 100644
--- a/themes/schema.json
+++ b/themes/schema.json
@@ -1157,6 +1157,12 @@
                     "title": "Mixed threshold",
                     "description": "The maximum length of a path segment that will be displayed when using mixed style.",
                     "default": 4
+                  },
+                  "hide_root_location": {
+                    "type": "boolean",
+                    "title": "Hide the root location",
+                    "description": "Hides the root location, when using agnoster_short style, if it doesn't fit in the last max_depth folders.",
+                    "default": false
                   }
                 }
               }


Test patch:
diff --git a/src/segments/path_test.go b/src/segments/path_test.go
index f0cb0276..0ebe43c1 100644
--- a/src/segments/path_test.go
+++ b/src/segments/path_test.go
@@ -170,6 +170,7 @@ func TestAgnosterPathStyles(t *testing.T) {
 		Style               string
 		GOOS                string
 		MaxDepth            int
+		HideRootLocation    bool
 	}{
 		{Style: AgnosterFull, Expected: "usr > location > whatever", HomePath: "/usr/home", Pwd: "/usr/location/whatever", PathSeparator: "/", FolderSeparatorIcon: " > "},
 		{Style: AgnosterShort, Expected: "usr > .. > man", HomePath: "/usr/home", Pwd: "/usr/location/whatever/man", PathSeparator: "/", FolderSeparatorIcon: " > "},
@@ -224,6 +225,30 @@ func TestAgnosterPathStyles(t *testing.T) {
 		{Style: AgnosterFull, Expected: "PSDRIVE: | src", HomePath: homeBillWindows, Pwd: "/foo", Pswd: "PSDRIVE:/src", PathSeparator: "/", FolderSeparatorIcon: " | "},
 		{Style: AgnosterShort, Expected: "PSDRIVE: | .. | init", HomePath: homeBillWindows, Pwd: "/foo", Pswd: "PSDRIVE:/src/init", PathSeparator: "/", FolderSeparatorIcon: " | "},
 
+		{Style: AgnosterShort, Expected: "src | init", HomePath: homeBillWindows, Pwd: "/foo", Pswd: "PSDRIVE:/src/init", PathSeparator: "/", FolderSeparatorIcon: " | ", MaxDepth: 2,
+			HideRootLocation: true},
+		{Style: AgnosterShort, Expected: "PSDRIVE: | src", HomePath: homeBillWindows, Pwd: "/foo", Pswd: "PSDRIVE:/src", PathSeparator: "/", FolderSeparatorIcon: " | ", MaxDepth: 2,
+			HideRootLocation: true},
+		{Style: AgnosterShort, Expected: "~", HomePath: homeBillWindows, Pwd: homeBillWindows, PathSeparator: "\\", FolderSeparatorIcon: " > ", MaxDepth: 1, HideRootLocation: true},
+		{Style: AgnosterShort, Expected: "foo", HomePath: homeBillWindows, Pwd: homeBillWindows + "\\foo", PathSeparator: "\\", FolderSeparatorIcon: "\\", MaxDepth: 1,
+			HideRootLocation: true},
+		{Style: AgnosterShort, Expected: "~\\foo", HomePath: homeBillWindows, Pwd: homeBillWindows + "\\foo", PathSeparator: "\\", FolderSeparatorIcon: "\\", MaxDepth: 2,
+			HideRootLocation: true},
+		{Style: AgnosterShort, Expected: "~", HomePath: "/usr/home", Pwd: "/usr/home", PathSeparator: "/", FolderSeparatorIcon: " > ", MaxDepth: 1, HideRootLocation: true},
+		{Style: AgnosterShort, Expected: "foo", HomePath: "/usr/home", Pwd: "/usr/home/foo", PathSeparator: "/", FolderSeparatorIcon: "/", MaxDepth: 1, HideRootLocation: true},
+		{Style: AgnosterShort, Expected: "bar > man", HomePath: "/usr/home", Pwd: "/usr/foo/bar/man", PathSeparator: "/", FolderSeparatorIcon: " > ", MaxDepth: 2,
+			HideRootLocation: true},
+		{Style: AgnosterShort, Expected: "foo > bar > man", HomePath: "/usr/home", Pwd: "/usr/foo/bar/man", PathSeparator: "/", FolderSeparatorIcon: " > ", MaxDepth: 3,
+			HideRootLocation: true},
+		{Style: AgnosterShort, Expected: "~ > foo", HomePath: "/usr/home", Pwd: "/usr/home/foo", PathSeparator: "/", FolderSeparatorIcon: " > ", MaxDepth: 2, HideRootLocation: true},
+		{Style: AgnosterShort, Expected: "~ > foo > bar > man", HomePath: "/usr/home", Pwd: "/usr/home/foo/bar/man", PathSeparator: "/", FolderSeparatorIcon: " > ", MaxDepth: 4,
+			HideRootLocation: true},
+		{Style: AgnosterShort, Expected: "C:", HomePath: "/usr/home", Pwd: "/mnt/c", Pswd: "C:", PathSeparator: "/", FolderSeparatorIcon: " | ", MaxDepth: 2, HideRootLocation: true},
+		{Style: AgnosterShort, Expected: "~ | space foo", HomePath: "/usr/home", Pwd: "/usr/home/space foo", PathSeparator: "/", FolderSeparatorIcon: " | ", MaxDepth: 2,
+			HideRootLocation: true},
+		{Style: AgnosterShort, Expected: "space foo", HomePath: "/usr/home", Pwd: "/usr/home/space foo", PathSeparator: "/", FolderSeparatorIcon: " | ", MaxDepth: 1,
+			HideRootLocation: true},
+
 		{Style: Mixed, Expected: "~ > .. > man", HomePath: "/usr/home", Pwd: "/usr/home/whatever/man", PathSeparator: "/", FolderSeparatorIcon: " > "},
 		{Style: Mixed, Expected: "~ > ab > .. > man", HomePath: "/usr/home", Pwd: "/usr/home/ab/whatever/man", PathSeparator: "/", FolderSeparatorIcon: " > "},
 
@@ -261,6 +286,7 @@ func TestAgnosterPathStyles(t *testing.T) {
 				FolderSeparatorIcon: tc.FolderSeparatorIcon,
 				properties.Style:    tc.Style,
 				MaxDepth:            tc.MaxDepth,
+				HideRootLocation:    tc.HideRootLocation,
 			},
 		}
 		_ = path.Enabled()