Skip to content

Commit

Permalink
feat: use regex for ignore folders
Browse files Browse the repository at this point in the history
resolves #187
  • Loading branch information
JanDeDobbeleer committed Dec 6, 2020
1 parent c266fdb commit e920614
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 33 deletions.
33 changes: 27 additions & 6 deletions docs/docs/configuration.md
Expand Up @@ -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

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
should be rather straighforward: `<#ffffff,#000000>this is white with black background</> <#FF479C>but this is pink</>`. Anything between the color start
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 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.

For example, if you want `prefix` to print a colored bracket which isn't the same as the segment's `foreground`, you can
Expand All @@ -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
* 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.

* 16 [ANSI color names][ansicolors].
- 16 [ANSI color names][ansicolors].

These include 8 basic ANSI colors and `default`:

Expand Down Expand Up @@ -329,3 +348,5 @@ Oh my Posh mainly supports three different color types being
[hexcolors]: https://htmlcolorcodes.com/color-chart/material-design-color-chart/
[ansicolors]: https://htmlcolorcodes.com/color-chart/material-design-color-chart/
[fg]: /docs/configure#foreground
[regex]: https://www.regular-expressions.info/tutorial.html
[regex-nl]: https://www.regular-expressions.info/lookaround.html
46 changes: 26 additions & 20 deletions properties.go
Expand Up @@ -97,31 +97,37 @@ func (p *properties) getKeyValueMap(property Property, defaultValue map[string]s
return keyValues
}

func parseStringArray(value interface{}) []string {
expectedValue, ok := value.([]interface{})
if !ok {
func parseStringArray(param interface{}) []string {
switch v := param.(type) {
default:
return []string{}
case []interface{}:
list := make([]string, len(v))
for i, v := range v {
list[i] = fmt.Sprint(v)
}
return list
case []string:
return v
}
list := make([]string, len(expectedValue))
for i, v := range expectedValue {
list[i] = fmt.Sprint(v)
}
return list
}

func parseKeyValueArray(value interface{}) map[string]string {
locations, ok := value.([]interface{})
if !ok {
func parseKeyValueArray(param interface{}) map[string]string {
switch v := param.(type) {
default:
return map[string]string{}
}
keyValueArray := make(map[string]string)
for _, s := range locations {
l := parseStringArray(s)
if len(l) == 2 {
key := l[0]
val := l[1]
keyValueArray[key] = val
case []interface{}:
keyValueArray := make(map[string]string)
for _, s := range v {
l := parseStringArray(s)
if len(l) == 2 {
key := l[0]
val := l[1]
keyValueArray[key] = val
}
}
return keyValueArray
case map[string]string:
return v
}
return keyValueArray
}
12 changes: 8 additions & 4 deletions segment.go
Expand Up @@ -2,6 +2,8 @@ package main

import (
"errors"
"fmt"
"regexp"
"time"
)

Expand Down Expand Up @@ -105,11 +107,13 @@ func (segment *Segment) getValue(property Property, defaultValue string) string
return defaultValue
}

func (segment *Segment) hasValue(property Property, match string) bool {
if value, ok := segment.Properties[property]; ok {
func (segment *Segment) shouldIgnoreFolder(cwd string) bool {
if value, ok := segment.Properties[IgnoreFolders]; ok {
list := parseStringArray(value)
for _, element := range list {
if element == match {
pattern := fmt.Sprintf("^%s$", element)
matched, err := regexp.MatchString(pattern, cwd)
if err == nil && matched {
return true
}
}
Expand Down Expand Up @@ -159,7 +163,7 @@ func (segment *Segment) mapSegmentWithWriter(env environmentInfo) error {

func (segment *Segment) setStringValue(env environmentInfo, cwd string, debug bool) {
err := segment.mapSegmentWithWriter(env)
if err != nil || segment.hasValue(IgnoreFolders, cwd) {
if err != nil || segment.shouldIgnoreFolder(cwd) {
return
}
// add timing only in debug
Expand Down
50 changes: 47 additions & 3 deletions segment_test.go
Expand Up @@ -7,6 +7,10 @@ import (
"github.com/stretchr/testify/assert"
)

const (
cwd = "Projects/oh-my-posh3"
)

func TestMapSegmentWriterCanMap(t *testing.T) {
sc := &Segment{
Type: Session,
Expand Down Expand Up @@ -41,15 +45,55 @@ func TestParseTestSettings(t *testing.T) {
"prefix": " \uE5FF ",
"style": "folder",
"ignore_folders": [
"go-my-psh"
"/super/secret/project"
]
}
}
`
segment := &Segment{}
err := json.Unmarshal([]byte(segmentJSON), segment)
assert.NoError(t, err)
expected := "go-my-psh"
got := segment.hasValue(IgnoreFolders, expected)
cwd := "/super/secret/project"
got := segment.shouldIgnoreFolder(cwd)
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)
}

0 comments on commit e920614

Please sign in to comment.