mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2024-11-10 13:04:04 -08:00
feat: flexible matching for include/exclude folders
This commit is contained in:
parent
b2515650c1
commit
7e4865779a
|
@ -293,8 +293,9 @@ will not be rendered when in one of the excluded locations.
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also specify a [regular expression][regex] to create folder wildcards.
|
The strings specified in these properties are evaluated as [regular expressions][regex]. You
|
||||||
In the sample below, any folders inside the `/Users/posh/Projects` path will be matched.
|
can use any valid regular expression construct, but the regular expression must match the entire directory
|
||||||
|
name. The following will match `/Users/posh/Projects/Foo` but not `/home/Users/posh/Projects/Foo`.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
"include_folders": [
|
"include_folders": [
|
||||||
|
@ -313,16 +314,17 @@ You can also combine these properties:
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
Note for Windows users: Windows directory separators should be specified as 4 backslashes.
|
##### Notes
|
||||||
|
|
||||||
```json
|
- Oh My Posh will accept both `/` and `\` as path separators for a folder and will match regardless of which
|
||||||
"include_folders": [
|
is used by the current operating system.
|
||||||
"C:\\\\Projects.*"
|
- Because the strings are evaluated as regular expressions, if you want to use a `\` in a Windows
|
||||||
],
|
directory name, you need to specify it as `\\\\`.
|
||||||
"exclude_folders": [
|
- The character `~` at the start of a specified folder will match the user's home directory.
|
||||||
"C:\\\\Projects\\\\secret-project.*"
|
- The comparison 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.
|
||||||
|
|
||||||
### Colors
|
### Colors
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -176,9 +177,20 @@ func (segment *Segment) cwdExcluded(cwd string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (segment *Segment) cwdMatchesOneOf(cwd string, regexes []string) bool {
|
func (segment *Segment) cwdMatchesOneOf(cwd string, regexes []string) bool {
|
||||||
|
normalizedCwd := strings.ReplaceAll(cwd, "\\", "/")
|
||||||
|
normalizedHomeDir := strings.ReplaceAll(segment.env.homeDir(), "\\", "/")
|
||||||
|
|
||||||
for _, element := range regexes {
|
for _, element := range regexes {
|
||||||
pattern := fmt.Sprintf("^%s$", element)
|
normalizedElement := strings.ReplaceAll(element, "\\\\", "/")
|
||||||
matched := matchString(pattern, cwd)
|
if strings.HasPrefix(normalizedElement, "~") {
|
||||||
|
normalizedElement = normalizedHomeDir + normalizedElement[1:]
|
||||||
|
}
|
||||||
|
pattern := fmt.Sprintf("^%s$", normalizedElement)
|
||||||
|
goos := segment.env.getRuntimeGOOS()
|
||||||
|
if goos == windowsPlatform || goos == darwinPlatform {
|
||||||
|
pattern = "(?i)" + pattern
|
||||||
|
}
|
||||||
|
matched := matchString(pattern, normalizedCwd)
|
||||||
if matched {
|
if matched {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,11 +81,15 @@ func TestShouldIncludeFolder(t *testing.T) {
|
||||||
{Case: "Include Mismatch / Exclude Mismatch", IncludeFolders: []string{"zProjects.*"}, ExcludeFolders: []string{"Projects/nope"}, Expected: false},
|
{Case: "Include Mismatch / Exclude Mismatch", IncludeFolders: []string{"zProjects.*"}, ExcludeFolders: []string{"Projects/nope"}, Expected: false},
|
||||||
}
|
}
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
|
env := new(MockedEnvironment)
|
||||||
|
env.On("getRuntimeGOOS", nil).Return(linuxPlatform)
|
||||||
|
env.On("homeDir", nil).Return("")
|
||||||
segment := &Segment{
|
segment := &Segment{
|
||||||
Properties: map[Property]interface{}{
|
Properties: map[Property]interface{}{
|
||||||
IncludeFolders: tc.IncludeFolders,
|
IncludeFolders: tc.IncludeFolders,
|
||||||
ExcludeFolders: tc.ExcludeFolders,
|
ExcludeFolders: tc.ExcludeFolders,
|
||||||
},
|
},
|
||||||
|
env: env,
|
||||||
}
|
}
|
||||||
got := segment.shouldIncludeFolder(cwd)
|
got := segment.shouldIncludeFolder(cwd)
|
||||||
assert.Equal(t, tc.Expected, got, tc.Case)
|
assert.Equal(t, tc.Expected, got, tc.Case)
|
||||||
|
@ -93,10 +97,14 @@ func TestShouldIncludeFolder(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShouldIncludeFolderRegexInverted(t *testing.T) {
|
func TestShouldIncludeFolderRegexInverted(t *testing.T) {
|
||||||
|
env := new(MockedEnvironment)
|
||||||
|
env.On("getRuntimeGOOS", nil).Return(linuxPlatform)
|
||||||
|
env.On("homeDir", nil).Return("")
|
||||||
segment := &Segment{
|
segment := &Segment{
|
||||||
Properties: map[Property]interface{}{
|
Properties: map[Property]interface{}{
|
||||||
ExcludeFolders: []string{"(?!Projects[\\/]).*"},
|
ExcludeFolders: []string{"(?!Projects[\\/]).*"},
|
||||||
},
|
},
|
||||||
|
env: env,
|
||||||
}
|
}
|
||||||
// detect panic(thrown by MustCompile)
|
// detect panic(thrown by MustCompile)
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -109,10 +117,14 @@ func TestShouldIncludeFolderRegexInverted(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShouldIncludeFolderRegexInvertedNonEscaped(t *testing.T) {
|
func TestShouldIncludeFolderRegexInvertedNonEscaped(t *testing.T) {
|
||||||
|
env := new(MockedEnvironment)
|
||||||
|
env.On("getRuntimeGOOS", nil).Return(linuxPlatform)
|
||||||
|
env.On("homeDir", nil).Return("")
|
||||||
segment := &Segment{
|
segment := &Segment{
|
||||||
Properties: map[Property]interface{}{
|
Properties: map[Property]interface{}{
|
||||||
ExcludeFolders: []string{"(?!Projects/).*"},
|
ExcludeFolders: []string{"(?!Projects/).*"},
|
||||||
},
|
},
|
||||||
|
env: env,
|
||||||
}
|
}
|
||||||
// detect panic(thrown by MustCompile)
|
// detect panic(thrown by MustCompile)
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -196,3 +208,39 @@ func TestGetColors(t *testing.T) {
|
||||||
assert.Equal(t, tc.ExpectedColor, color, tc.Case)
|
assert.Equal(t, tc.ExpectedColor, color, tc.Case)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCwdMatchesOneOf(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
GOOS string
|
||||||
|
HomeDir string
|
||||||
|
Cwd string
|
||||||
|
Pattern string
|
||||||
|
Expected bool
|
||||||
|
}{
|
||||||
|
{GOOS: linuxPlatform, HomeDir: "/home/bill", Cwd: "/home/bill", Pattern: "/home/bill", Expected: true},
|
||||||
|
{GOOS: linuxPlatform, HomeDir: "/home/bill", Cwd: "/home/bill/foo", Pattern: "~/foo", Expected: true},
|
||||||
|
{GOOS: linuxPlatform, HomeDir: "/home/bill", Cwd: "/home/bill/foo", Pattern: "~/Foo", Expected: false},
|
||||||
|
{GOOS: linuxPlatform, HomeDir: "/home/bill", Cwd: "/home/bill/foo", Pattern: "~\\\\foo", Expected: true},
|
||||||
|
{GOOS: linuxPlatform, HomeDir: "/home/bill", Cwd: "/home/bill/foo/bar", Pattern: "~/fo.*", Expected: true},
|
||||||
|
{GOOS: linuxPlatform, HomeDir: "/home/bill", Cwd: "/home/bill/foo", Pattern: "~/fo\\w", Expected: true},
|
||||||
|
{GOOS: windowsPlatform, HomeDir: "C:\\Users\\Bill", Cwd: "C:\\Users\\Bill", Pattern: "C:\\\\Users\\\\Bill", Expected: true},
|
||||||
|
{GOOS: windowsPlatform, HomeDir: "C:\\Users\\Bill", Cwd: "C:\\Users\\Bill", Pattern: "C:/Users/Bill", Expected: true},
|
||||||
|
{GOOS: windowsPlatform, HomeDir: "C:\\Users\\Bill", Cwd: "C:\\Users\\Bill", Pattern: "c:/users/bill", Expected: true},
|
||||||
|
{GOOS: windowsPlatform, HomeDir: "C:\\Users\\Bill", Cwd: "C:\\Users\\Bill", Pattern: "~", Expected: true},
|
||||||
|
{GOOS: windowsPlatform, HomeDir: "C:\\Users\\Bill", Cwd: "C:\\Users\\Bill\\Foo", Pattern: "~/Foo", Expected: true},
|
||||||
|
{GOOS: windowsPlatform, HomeDir: "C:\\Users\\Bill", Cwd: "C:\\Users\\Bill\\Foo", Pattern: "~/foo", Expected: true},
|
||||||
|
{GOOS: windowsPlatform, HomeDir: "C:\\Users\\Bill", Cwd: "C:\\Users\\Bill\\Foo\\Bar", Pattern: "~/fo.*", Expected: true},
|
||||||
|
{GOOS: windowsPlatform, HomeDir: "C:\\Users\\Bill", Cwd: "C:\\Users\\Bill\\Foo", Pattern: "~/fo\\w", Expected: true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
env := new(MockedEnvironment)
|
||||||
|
env.On("getRuntimeGOOS", nil).Return(tc.GOOS)
|
||||||
|
env.On("homeDir", nil).Return(tc.HomeDir)
|
||||||
|
segment := &Segment{
|
||||||
|
env: env,
|
||||||
|
}
|
||||||
|
got := segment.cwdMatchesOneOf(tc.Cwd, []string{tc.Pattern})
|
||||||
|
assert.Equal(t, tc.Expected, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue