feat(path): unique letters style

resolves #1663
This commit is contained in:
Jan De Dobbeleer 2022-02-09 10:06:28 +01:00 committed by Jan De Dobbeleer
parent 08dae53acd
commit d1bd686674
4 changed files with 53 additions and 12 deletions

View file

@ -78,6 +78,7 @@ Style sets the way the path is displayed. Based on previous experience and popul
- folder - folder
- mixed - mixed
- letter - letter
- unique
### Agnoster ### Agnoster
@ -121,6 +122,10 @@ starts with a symbol or icon.
- `__pycache__` will be shortened to `__p` - `__pycache__` will be shortened to `__p`
- `➼ folder` will be shortened to `➼ f` - `➼ folder` will be shortened to `➼ f`
### Unique
Works like `Letter`, but will make sure every folder name is the shortest unique value.
## Template ([info][templates]) ## Template ([info][templates])
:::note default template :::note default template

View file

@ -44,6 +44,8 @@ const (
Mixed string = "mixed" Mixed string = "mixed"
// Letter like agnoster, but with the first letter of each folder name // Letter like agnoster, but with the first letter of each folder name
Letter string = "letter" Letter string = "letter"
// Unique like agnoster, but with the first unique letters of each folder name
Unique string = "unique"
// AgnosterLeft like agnoster, but keeps the left side of the path // AgnosterLeft like agnoster, but keeps the left side of the path
AgnosterLeft string = "agnoster_left" AgnosterLeft string = "agnoster_left"
// MixedThreshold the threshold of the length of the path Mixed will display // MixedThreshold the threshold of the length of the path Mixed will display
@ -73,6 +75,8 @@ func (pt *Path) Enabled() bool {
pt.Path = pt.getMixedPath() pt.Path = pt.getMixedPath()
case Letter: case Letter:
pt.Path = pt.getLetterPath() pt.Path = pt.getLetterPath()
case Unique:
pt.Path = pt.getUniqueLettersPath()
case AgnosterLeft: case AgnosterLeft:
pt.Path = pt.getAgnosterLeftPath() pt.Path = pt.getAgnosterLeftPath()
case Short: case Short:
@ -171,6 +175,19 @@ func (pt *Path) getAgnosterLeftPath() string {
return buffer.String() return buffer.String()
} }
func (pt *Path) getRelevantLetter(folder string) string {
// check if there is at least a letter we can use
matches := regex.FindNamedRegexMatch(`(?P<letter>[\p{L}0-9]).*`, folder)
if matches == nil || matches["letter"] == "" {
// no letter found, keep the folder unchanged
return folder
}
letter := matches["letter"]
// handle non-letter characters before the first found letter
letter = folder[0:strings.Index(folder, letter)] + letter
return letter
}
func (pt *Path) getLetterPath() string { func (pt *Path) getLetterPath() string {
var buffer strings.Builder var buffer strings.Builder
pwd := pt.getPwd() pwd := pt.getPwd()
@ -181,20 +198,34 @@ func (pt *Path) getLetterPath() string {
if len(folder) == 0 { if len(folder) == 0 {
continue continue
} }
letter := pt.getRelevantLetter(folder)
buffer.WriteString(fmt.Sprintf("%s%s", letter, separator))
}
if len(splitted) > 0 {
buffer.WriteString(splitted[len(splitted)-1])
}
return buffer.String()
}
// check if there is at least a letter we can use func (pt *Path) getUniqueLettersPath() string {
matches := regex.FindNamedRegexMatch(`(?P<letter>[\p{L}0-9]).*`, folder) var buffer strings.Builder
pwd := pt.getPwd()
if matches == nil || matches["letter"] == "" { splitted := strings.Split(pwd, pt.env.PathSeperator())
// no letter found, keep the folder unchanged separator := pt.props.GetString(FolderSeparatorIcon, pt.env.PathSeperator())
buffer.WriteString(fmt.Sprintf("%s%s", folder, separator)) letters := make(map[string]bool, len(splitted))
for i := 0; i < len(splitted)-1; i++ {
folder := splitted[i]
if len(folder) == 0 {
continue continue
} }
letter := pt.getRelevantLetter(folder)
letter := matches["letter"] for letters[letter] {
// handle non-letter characters before the first found letter if letter == folder {
letter = folder[0:strings.Index(folder, letter)] + letter break
}
letter += folder[len(letter) : len(letter)+1]
}
letters[letter] = true
buffer.WriteString(fmt.Sprintf("%s%s", letter, separator)) buffer.WriteString(fmt.Sprintf("%s%s", letter, separator))
} }
if len(splitted) > 0 { if len(splitted) > 0 {

View file

@ -238,6 +238,10 @@ func TestAgnosterPathStyles(t *testing.T) {
{Style: Letter, Expected: "u > .b > __p > .w > man", HomePath: "/usr/home", Pwd: "/usr/.burp/__pycache__/.whatever/man", PathSeperator: "/", FolderSeparatorIcon: " > "}, {Style: Letter, Expected: "u > .b > __p > .w > man", HomePath: "/usr/home", Pwd: "/usr/.burp/__pycache__/.whatever/man", PathSeperator: "/", FolderSeparatorIcon: " > "},
{Style: Letter, Expected: "➼ > .w > man", HomePath: "/usr/home", Pwd: "➼/.whatever/man", PathSeperator: "/", FolderSeparatorIcon: " > "}, {Style: Letter, Expected: "➼ > .w > man", HomePath: "/usr/home", Pwd: "➼/.whatever/man", PathSeperator: "/", FolderSeparatorIcon: " > "},
{Style: Letter, Expected: "➼ s > .w > man", HomePath: "/usr/home", Pwd: "➼ something/.whatever/man", PathSeperator: "/", FolderSeparatorIcon: " > "}, {Style: Letter, Expected: "➼ s > .w > man", HomePath: "/usr/home", Pwd: "➼ something/.whatever/man", PathSeperator: "/", FolderSeparatorIcon: " > "},
{Style: Unique, Expected: "~ > a > ab > abcd", HomePath: "/usr/home", Pwd: "/usr/home/ab/abc/abcd", PathSeperator: "/", FolderSeparatorIcon: " > "},
{Style: Unique, Expected: "~ > a > .a > abcd", HomePath: "/usr/home", Pwd: "/usr/home/ab/.abc/abcd", PathSeperator: "/", FolderSeparatorIcon: " > "},
{Style: Unique, Expected: "~ > a > ab > abcd", HomePath: "/usr/home", Pwd: "/usr/home/ab/ab/abcd", PathSeperator: "/", FolderSeparatorIcon: " > "},
} }
for _, tc := range cases { for _, tc := range cases {
env := new(mock.MockedEnvironment) env := new(mock.MockedEnvironment)

View file

@ -1114,7 +1114,8 @@
"full", "full",
"folder", "folder",
"mixed", "mixed",
"letter" "letter",
"unique"
], ],
"default": "folder" "default": "folder"
}, },