feat: use regex for ignore folders

resolves #187
This commit is contained in:
Jan De Dobbeleer 2020-12-06 19:34:42 +01:00 committed by Jan De Dobbeleer
parent c266fdb3a0
commit e92061428b
4 changed files with 108 additions and 33 deletions

View file

@ -198,10 +198,30 @@ segment's configuration will not render it when in that location. The engine wil
] ]
``` ```
You can also specify a [regular expression][regex] to create wildcards to exclude certain folders.
In the sample below, folders inside the `/Users/posh/Projects` path will not show the segment.
```json
"ignore_folders": [
"/Users/posh/Projects/.*"
]
```
Want to only show the segment inside certain folders? Use the [negative lookahead][regex-nl] to only match folders
in a certain path. Everything else will be ignored. In the sample below, only folders inside the
`/Users/posh/Projects/` path will show the segment.
```json
"ignore_folders": [
"(?!/Users/posh/Projects/).*"
]
```
#### Colors #### Colors
You have the ability to override the foreground and/or background color for text in any property that accepts it. The syntax is custom but You have the ability to override the foreground and/or background color for text in any property that accepts it.
should be rather straighforward: `<#ffffff,#000000>this is white with black background</> <#FF479C>but this is pink</>`. Anything between the color start The syntax is custom but should be rather straighforward:
`<#ffffff,#000000>this is white with black background</> <#FF479C>but this is pink</>`. Anything between the color start
`<#FF479C>` and end `</>` will be colored accordingly. `<#FF479C>` and end `</>` will be colored accordingly.
For example, if you want `prefix` to print a colored bracket which isn't the same as the segment's `foreground`, you can For example, if you want `prefix` to print a colored bracket which isn't the same as the segment's `foreground`, you can
@ -224,12 +244,11 @@ To change *only* the background color, just omit the first color from the above
``` ```
Oh my Posh mainly supports three different color types being Oh my Posh mainly supports three different color types being
* Typical [hex colors][hexcolors] (for example `#CB4B16`).
* The `transparent` keyword which can be used to create either a transparent foreground override - Typical [hex colors][hexcolors] (for example `#CB4B16`).
- The `transparent` keyword which can be used to create either a transparent foreground override
or transparent background color using the segement's foreground property. or transparent background color using the segement's foreground property.
- 16 [ANSI color names][ansicolors].
* 16 [ANSI color names][ansicolors].
These include 8 basic ANSI colors and `default`: These include 8 basic ANSI colors and `default`:
@ -329,3 +348,5 @@ Oh my Posh mainly supports three different color types being
[hexcolors]: https://htmlcolorcodes.com/color-chart/material-design-color-chart/ [hexcolors]: https://htmlcolorcodes.com/color-chart/material-design-color-chart/
[ansicolors]: https://htmlcolorcodes.com/color-chart/material-design-color-chart/ [ansicolors]: https://htmlcolorcodes.com/color-chart/material-design-color-chart/
[fg]: /docs/configure#foreground [fg]: /docs/configure#foreground
[regex]: https://www.regular-expressions.info/tutorial.html
[regex-nl]: https://www.regular-expressions.info/lookaround.html

View file

@ -97,25 +97,28 @@ func (p *properties) getKeyValueMap(property Property, defaultValue map[string]s
return keyValues return keyValues
} }
func parseStringArray(value interface{}) []string { func parseStringArray(param interface{}) []string {
expectedValue, ok := value.([]interface{}) switch v := param.(type) {
if !ok { default:
return []string{} return []string{}
} case []interface{}:
list := make([]string, len(expectedValue)) list := make([]string, len(v))
for i, v := range expectedValue { for i, v := range v {
list[i] = fmt.Sprint(v) list[i] = fmt.Sprint(v)
} }
return list return list
case []string:
return v
}
} }
func parseKeyValueArray(value interface{}) map[string]string { func parseKeyValueArray(param interface{}) map[string]string {
locations, ok := value.([]interface{}) switch v := param.(type) {
if !ok { default:
return map[string]string{} return map[string]string{}
} case []interface{}:
keyValueArray := make(map[string]string) keyValueArray := make(map[string]string)
for _, s := range locations { for _, s := range v {
l := parseStringArray(s) l := parseStringArray(s)
if len(l) == 2 { if len(l) == 2 {
key := l[0] key := l[0]
@ -124,4 +127,7 @@ func parseKeyValueArray(value interface{}) map[string]string {
} }
} }
return keyValueArray return keyValueArray
case map[string]string:
return v
}
} }

View file

@ -2,6 +2,8 @@ package main
import ( import (
"errors" "errors"
"fmt"
"regexp"
"time" "time"
) )
@ -105,11 +107,13 @@ func (segment *Segment) getValue(property Property, defaultValue string) string
return defaultValue return defaultValue
} }
func (segment *Segment) hasValue(property Property, match string) bool { func (segment *Segment) shouldIgnoreFolder(cwd string) bool {
if value, ok := segment.Properties[property]; ok { if value, ok := segment.Properties[IgnoreFolders]; ok {
list := parseStringArray(value) list := parseStringArray(value)
for _, element := range list { for _, element := range list {
if element == match { pattern := fmt.Sprintf("^%s$", element)
matched, err := regexp.MatchString(pattern, cwd)
if err == nil && matched {
return true return true
} }
} }
@ -159,7 +163,7 @@ func (segment *Segment) mapSegmentWithWriter(env environmentInfo) error {
func (segment *Segment) setStringValue(env environmentInfo, cwd string, debug bool) { func (segment *Segment) setStringValue(env environmentInfo, cwd string, debug bool) {
err := segment.mapSegmentWithWriter(env) err := segment.mapSegmentWithWriter(env)
if err != nil || segment.hasValue(IgnoreFolders, cwd) { if err != nil || segment.shouldIgnoreFolder(cwd) {
return return
} }
// add timing only in debug // add timing only in debug

View file

@ -7,6 +7,10 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
const (
cwd = "Projects/oh-my-posh3"
)
func TestMapSegmentWriterCanMap(t *testing.T) { func TestMapSegmentWriterCanMap(t *testing.T) {
sc := &Segment{ sc := &Segment{
Type: Session, Type: Session,
@ -41,7 +45,7 @@ func TestParseTestSettings(t *testing.T) {
"prefix": " \uE5FF ", "prefix": " \uE5FF ",
"style": "folder", "style": "folder",
"ignore_folders": [ "ignore_folders": [
"go-my-psh" "/super/secret/project"
] ]
} }
} }
@ -49,7 +53,47 @@ func TestParseTestSettings(t *testing.T) {
segment := &Segment{} segment := &Segment{}
err := json.Unmarshal([]byte(segmentJSON), segment) err := json.Unmarshal([]byte(segmentJSON), segment)
assert.NoError(t, err) assert.NoError(t, err)
expected := "go-my-psh" cwd := "/super/secret/project"
got := segment.hasValue(IgnoreFolders, expected) got := segment.shouldIgnoreFolder(cwd)
assert.True(t, got) assert.True(t, got)
} }
func TestShouldIgnoreFolderRegex(t *testing.T) {
segment := &Segment{
Properties: map[Property]interface{}{
IgnoreFolders: []string{"Projects[\\/].*"},
},
}
got := segment.shouldIgnoreFolder(cwd)
assert.True(t, got)
}
func TestShouldIgnoreFolderRegexNonEscaped(t *testing.T) {
segment := &Segment{
Properties: map[Property]interface{}{
IgnoreFolders: []string{"Projects/.*"},
},
}
got := segment.shouldIgnoreFolder(cwd)
assert.True(t, got)
}
func TestShouldIgnoreFolderRegexInverted(t *testing.T) {
segment := &Segment{
Properties: map[Property]interface{}{
IgnoreFolders: []string{"(?!Projects[\\/]).*"},
},
}
got := segment.shouldIgnoreFolder(cwd)
assert.False(t, got)
}
func TestShouldIgnoreFolderRegexInvertedNonEscaped(t *testing.T) {
segment := &Segment{
Properties: map[Property]interface{}{
IgnoreFolders: []string{"(?!Projects/).*"},
},
}
got := segment.shouldIgnoreFolder(cwd)
assert.False(t, got)
}