refactor: move exclude/include folders to segment root

This commit is contained in:
Jan De Dobbeleer 2024-11-03 11:10:43 +01:00 committed by Jan De Dobbeleer
parent 404f4e0f31
commit 4ac1033706
19 changed files with 260 additions and 241 deletions

View file

@ -1,7 +1,6 @@
package cache
import (
"strconv"
"time"
)
@ -38,5 +37,6 @@ func ToDuration(seconds int) Duration {
return INFINITE
}
return Duration(strconv.Itoa(seconds) + "s")
duration := time.Duration(seconds) * time.Second
return Duration(duration.String())
}

2
src/cache/file.go vendored
View file

@ -67,9 +67,11 @@ func (fc *File) Get(key string) (string, bool) {
if !found {
return "", false
}
if co, ok := val.(*Entry); ok {
return co.Value, true
}
return "", false
}

View file

@ -2,6 +2,13 @@ package config
import (
"github.com/jandedobbeleer/oh-my-posh/src/cache"
"github.com/jandedobbeleer/oh-my-posh/src/properties"
)
const (
includeFolders = properties.Property("include_folders")
excludeFolders = properties.Property("exclude_folders")
cacheTimeout = properties.Property("cache_timeout")
)
func (cfg *Config) Migrate() {
@ -23,11 +30,46 @@ func (segment *Segment) migrate(version int) {
// Cache settings
delete(segment.Properties, "cache_version")
cacheTimeout := segment.Properties.GetInt("cache_timeout", 0)
if cacheTimeout != 0 {
segment.Cache = &cache.Config{
Duration: cache.ToDuration(cacheTimeout * 60),
Strategy: cache.Folder,
segment.Cache = segment.migrateCache()
segment.IncludeFolders = segment.migrateFolders(includeFolders)
segment.ExcludeFolders = segment.migrateFolders(excludeFolders)
}
func (segment *Segment) hasProperty(property properties.Property) bool {
for key := range segment.Properties {
if key == property {
return true
}
}
return false
}
func (segment *Segment) migrateCache() *cache.Config {
if !segment.hasProperty(cacheTimeout) {
return nil
}
timeout := segment.Properties.GetInt(cacheTimeout, 0)
delete(segment.Properties, cacheTimeout)
if timeout == 0 {
return nil
}
return &cache.Config{
Duration: cache.ToDuration(timeout * 60),
Strategy: cache.Folder,
}
}
func (segment *Segment) migrateFolders(property properties.Property) []string {
if !segment.hasProperty(property) {
return []string{}
}
array := segment.Properties.GetStringArray(property, []string{})
delete(segment.Properties, property)
return array
}

View file

@ -0,0 +1,55 @@
package config
import (
"testing"
"github.com/jandedobbeleer/oh-my-posh/src/cache"
"github.com/jandedobbeleer/oh-my-posh/src/properties"
"github.com/stretchr/testify/assert"
)
func TestMigrateCache(t *testing.T) {
cases := []struct {
Expected *cache.Config
Case string
Timeout int
}{
{Case: "No timeout set"},
{Case: "Timeout set to 0", Timeout: 0},
{Case: "Timeout set to 10", Timeout: 10, Expected: &cache.Config{Duration: "10m0s", Strategy: cache.Folder}},
}
for _, tc := range cases {
segment := &Segment{
Properties: properties.Map{
cacheTimeout: tc.Timeout,
},
}
got := segment.migrateCache()
assert.Equal(t, tc.Expected, got, tc.Case)
}
}
func TestMigrateFolders(t *testing.T) {
cases := []struct {
Case string
Folders []string
}{
{Case: "No folders set"},
{Case: "Empty folders", Folders: []string{}},
{Case: "Folders set", Folders: []string{"/super/secret/project"}},
}
for _, tc := range cases {
segment := &Segment{
Properties: properties.Map{
excludeFolders: tc.Folders,
},
}
got := segment.migrateFolders(excludeFolders)
assert.Equal(t, tc.Folders, got, tc.Case)
}
}

View file

@ -40,8 +40,8 @@ type Segment struct {
env runtime.Environment
Properties properties.Map `json:"properties,omitempty" toml:"properties,omitempty"`
Cache *cache.Config `json:"cache,omitempty" toml:"cache,omitempty"`
Alias string `json:"alias,omitempty" toml:"alias,omitempty"`
LeadingPowerlineSymbol string `json:"leading_powerline_symbol,omitempty" toml:"leading_powerline_symbol,omitempty"`
Style SegmentStyle `json:"style,omitempty" toml:"style,omitempty"`
styleCache SegmentStyle
name string
LeadingDiamond string `json:"leading_diamond,omitempty" toml:"leading_diamond,omitempty"`
TrailingDiamond string `json:"trailing_diamond,omitempty" toml:"trailing_diamond,omitempty"`
@ -52,20 +52,22 @@ type Segment struct {
Background color.Ansi `json:"background" toml:"background"`
Filler string `json:"filler,omitempty" toml:"filler,omitempty"`
Type SegmentType `json:"type,omitempty" toml:"type,omitempty"`
Style SegmentStyle `json:"style,omitempty" toml:"style,omitempty"`
styleCache SegmentStyle
ForegroundTemplates template.List `json:"foreground_templates,omitempty" toml:"foreground_templates,omitempty"`
Tips []string `json:"tips,omitempty" toml:"tips,omitempty"`
BackgroundTemplates template.List `json:"background_templates,omitempty" toml:"background_templates,omitempty"`
Templates template.List `json:"templates,omitempty" toml:"templates,omitempty"`
MinWidth int `json:"min_width,omitempty" toml:"min_width,omitempty"`
MaxWidth int `json:"max_width,omitempty" toml:"max_width,omitempty"`
Duration time.Duration `json:"-" toml:"-"`
NameLength int `json:"-" toml:"-"`
Interactive bool `json:"interactive,omitempty" toml:"interactive,omitempty"`
Enabled bool `json:"-" toml:"-"`
Newline bool `json:"newline,omitempty" toml:"newline,omitempty"`
InvertPowerline bool `json:"invert_powerline,omitempty" toml:"invert_powerline,omitempty"`
Alias string `json:"alias,omitempty" toml:"alias,omitempty"`
LeadingPowerlineSymbol string `json:"leading_powerline_symbol,omitempty" toml:"leading_powerline_symbol,omitempty"`
ForegroundTemplates template.List `json:"foreground_templates,omitempty" toml:"foreground_templates,omitempty"`
Tips []string `json:"tips,omitempty" toml:"tips,omitempty"`
BackgroundTemplates template.List `json:"background_templates,omitempty" toml:"background_templates,omitempty"`
Templates template.List `json:"templates,omitempty" toml:"templates,omitempty"`
ExcludeFolders []string `json:"exclude_folders,omitempty" toml:"exclude_folders,omitempty"`
IncludeFolders []string `json:"include_folders,omitempty" toml:"include_folders,omitempty"`
Duration time.Duration `json:"-" toml:"-"`
NameLength int `json:"-" toml:"-"`
MaxWidth int `json:"max_width,omitempty" toml:"max_width,omitempty"`
MinWidth int `json:"min_width,omitempty" toml:"min_width,omitempty"`
Interactive bool `json:"interactive,omitempty" toml:"interactive,omitempty"`
Enabled bool `json:"-" toml:"-"`
Newline bool `json:"newline,omitempty" toml:"newline,omitempty"`
InvertPowerline bool `json:"invert_powerline,omitempty" toml:"invert_powerline,omitempty"`
}
func (segment *Segment) Name() string {
@ -299,28 +301,13 @@ func (segment *Segment) shouldIncludeFolder() bool {
}
func (segment *Segment) cwdIncluded() bool {
value, ok := segment.Properties[properties.IncludeFolders]
if !ok {
// IncludeFolders isn't specified, everything is included
if len(segment.IncludeFolders) == 0 {
return true
}
list := properties.ParseStringArray(value)
if len(list) == 0 {
// IncludeFolders is an empty array, everything is included
return true
}
return segment.env.DirMatchesOneOf(segment.env.Pwd(), list)
return segment.env.DirMatchesOneOf(segment.env.Pwd(), segment.IncludeFolders)
}
func (segment *Segment) cwdExcluded() bool {
value, ok := segment.Properties[properties.ExcludeFolders]
if !ok {
return false
}
list := properties.ParseStringArray(value)
return segment.env.DirMatchesOneOf(segment.env.Pwd(), list)
return segment.env.DirMatchesOneOf(segment.env.Pwd(), segment.ExcludeFolders)
}

View file

@ -5,7 +5,6 @@ import (
"testing"
"github.com/jandedobbeleer/oh-my-posh/src/color"
"github.com/jandedobbeleer/oh-my-posh/src/properties"
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"
"github.com/jandedobbeleer/oh-my-posh/src/segments"
@ -46,11 +45,11 @@ func TestParseTestConfig(t *testing.T) {
"foreground": "#ffffff",
"background": "#61AFEF",
"properties": {
"style": "folder",
"exclude_folders": [
"/super/secret/project"
]
}
"style": "folder"
},
"exclude_folders": [
"/super/secret/project"
]
}
`
segment := &Segment{}
@ -78,11 +77,9 @@ func TestShouldIncludeFolder(t *testing.T) {
env.On("DirMatchesOneOf", cwd, []string{"Projects/oh-my-posh"}).Return(tc.Included)
env.On("DirMatchesOneOf", cwd, []string{"Projects/nope"}).Return(tc.Excluded)
segment := &Segment{
Properties: properties.Map{
properties.IncludeFolders: []string{"Projects/oh-my-posh"},
properties.ExcludeFolders: []string{"Projects/nope"},
},
env: env,
IncludeFolders: []string{"Projects/oh-my-posh"},
ExcludeFolders: []string{"Projects/nope"},
env: env,
}
got := segment.shouldIncludeFolder()
assert.Equal(t, tc.Expected, got, tc.Case)

View file

@ -25,10 +25,6 @@ type Property string
const (
// Style indicates the style to use
Style Property = "style"
// IncludeFolders indicates folders to be included for the segment logic
IncludeFolders Property = "include_folders"
// ExcludeFolders indicates folders to be excluded for the segment logic
ExcludeFolders Property = "exclude_folders"
// FetchVersion decides whether to fetch the version number or not
FetchVersion Property = "fetch_version"
// AlwaysEnabled decides whether or not to always display the info

View file

@ -338,10 +338,6 @@ func (g *Git) shouldDisplay() bool {
return false
}
if g.shouldIgnoreRootRepository(gitdir.ParentFolder) {
return false
}
g.setDir(gitdir.Path)
if !gitdir.IsDir {

View file

@ -80,10 +80,6 @@ func (hg *Mercurial) shouldDisplay() bool {
return false
}
if hg.shouldIgnoreRootRepository(hgdir.ParentFolder) {
return false
}
hg.setDir(hgdir.ParentFolder)
hg.workingDir = hgdir.Path

View file

@ -55,10 +55,6 @@ func (p *Plastic) Enabled() bool {
return false
}
if p.shouldIgnoreRootRepository(wkdir.ParentFolder) {
return false
}
if !wkdir.IsDir {
return false
}

View file

@ -81,10 +81,6 @@ func (sl *Sapling) shouldDisplay() bool {
return false
}
if sl.shouldIgnoreRootRepository(slDir.ParentFolder) {
return false
}
sl.workingDir = slDir.Path
sl.rootDir = slDir.Path
// convert the worktree file path to a windows one when in a WSL shared folder

View file

@ -125,7 +125,6 @@ func TestShouldDisplay(t *testing.T) {
HasSapling bool
InRepo bool
Expected bool
Excluded bool
}{
{
Case: "Sapling not installed",
@ -134,12 +133,6 @@ func TestShouldDisplay(t *testing.T) {
Case: "Sapling installed, not in repo",
HasSapling: true,
},
{
Case: "Sapling installed, in repo but ignored",
HasSapling: true,
InRepo: true,
Excluded: true,
},
{
Case: "Sapling installed, in repo",
HasSapling: true,
@ -158,19 +151,14 @@ func TestShouldDisplay(t *testing.T) {
env.On("InWSLSharedDrive").Return(false)
env.On("GOOS").Return(runtime.LINUX)
env.On("Home").Return("/usr/home/sapling")
env.On("DirMatchesOneOf", fileInfo.ParentFolder, []string{"/sapling/repo"}).Return(tc.Excluded)
if tc.InRepo {
env.On("HasParentFilePath", ".sl", false).Return(fileInfo, nil)
} else {
env.On("HasParentFilePath", ".sl", false).Return(&runtime.FileInfo{}, errors.New("error"))
}
props := &properties.Map{
properties.ExcludeFolders: []string{"/sapling/repo"},
}
sl := &Sapling{}
sl.Init(props, env)
sl.Init(&properties.Map{}, env)
got := sl.shouldDisplay()
assert.Equal(t, tc.Expected, got, tc.Case)

View file

@ -138,14 +138,6 @@ func (s *scm) formatBranch(branch string) string {
return string(runes[0:maxLength]) + truncateSymbol
}
func (s *scm) shouldIgnoreRootRepository(rootDir string) bool {
excludedFolders := s.props.GetStringArray(properties.ExcludeFolders, []string{})
if len(excludedFolders) == 0 {
return false
}
return s.env.DirMatchesOneOf(rootDir, excludedFolders)
}
func (s *scm) FileContents(folder, file string) string {
return strings.Trim(s.env.FileContent(folder+"/"+file), " \r\n")
}

View file

@ -78,10 +78,6 @@ func (s *Svn) shouldDisplay() bool {
return false
}
if s.shouldIgnoreRootRepository(Svndir.ParentFolder) {
return false
}
if Svndir.IsDir {
s.workingDir = Svndir.Path
s.rootDir = Svndir.Path

View file

@ -450,27 +450,7 @@
"type": "object",
"title": "Segment Properties, used to change behavior/displaying",
"description": "https://ohmyposh.dev/docs/configuration/segment#properties",
"default": {},
"properties": {
"include_folders": {
"type": "array",
"title": "If specified, segment will only render in these folders",
"description": "https://ohmyposh.dev/docs/configuration/segment#include--exclude-folders",
"default": [],
"items": {
"type": "string"
}
},
"exclude_folders": {
"type": "array",
"title": "Exclude rendering in these folders",
"description": "https://ohmyposh.dev/docs/configuration/segment#include--exclude-folders",
"default": [],
"items": {
"type": "string"
}
}
}
"default": {}
},
"interactive": {
"type": "boolean",
@ -484,6 +464,24 @@
"description": "https://ohmyposh.dev/docs/configuration/segment",
"default": ""
},
"include_folders": {
"type": "array",
"title": "If specified, segment will only render in these folders",
"description": "https://ohmyposh.dev/docs/configuration/segment#include--exclude-folders",
"default": [],
"items": {
"type": "string"
}
},
"exclude_folders": {
"type": "array",
"title": "Exclude rendering in these folders",
"description": "https://ohmyposh.dev/docs/configuration/segment#include--exclude-folders",
"default": [],
"items": {
"type": "string"
}
},
"cache": {
"type": "object",
"title": "Cache settings",

View file

@ -20,7 +20,7 @@ import Config from "@site/src/components/Config.js";
}}
/>
## Properties
## Settings
| Name | Type |
| ------------------ | --------- |

View file

@ -4,92 +4,91 @@ title: Sample
sidebar_label: Sample
---
import Config from '@site/src/components/Config.js';
import Config from "@site/src/components/Config.js";
<Config data={{
"$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json",
"blocks": [
{
"segments": [
{
"foreground": "#007ACC",
"template": " {{ .CurrentDate | date .Format }} ",
"properties": {
"time_format": "15:04:05"
<Config
data={{
$schema:
"https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json",
blocks: [
{
segments: [
{
foreground: "#007ACC",
template: " {{ .CurrentDate | date .Format }} ",
properties: {
time_format: "15:04:05",
},
style: "plain",
type: "time",
},
"style": "plain",
"type": "time"
}
],
"type": "rprompt",
},
{
"alignment": "left",
"newline": true,
"segments": [
{
"background": "#ffb300",
"foreground": "#ffffff",
"leading_diamond": "\ue0b6",
"template": " {{ .UserName }} ",
"style": "diamond",
"trailing_diamond": "\ue0b0",
"type": "session"
},
{
"background": "#61AFEF",
"foreground": "#ffffff",
"powerline_symbol": "\ue0b0",
"template": " {{ .Path }} ",
"properties": {
"exclude_folders": [
"/super/secret/project"
],
type: "rprompt",
},
{
alignment: "left",
newline: true,
segments: [
{
background: "#ffb300",
foreground: "#ffffff",
leading_diamond: "\ue0b6",
template: " {{ .UserName }} ",
style: "diamond",
trailing_diamond: "\ue0b0",
type: "session",
},
{
background: "#61AFEF",
foreground: "#ffffff",
powerline_symbol: "\ue0b0",
template: " {{ .Path }} ",
properties: {
style: "folder",
},
exclude_folders: ["/super/secret/project"],
style: "powerline",
type: "path",
},
{
background: "#2e9599",
background_templates: [
"{{ if or (.Working.Changed) (.Staging.Changed) }}#f36943{{ end }}",
"{{ if and (gt .Ahead 0) (gt .Behind 0) }}#a8216b{{ end }}",
"{{ if gt .Ahead 0 }}#35b5ff{{ end }}",
"{{ if gt .Behind 0 }}#f89cfa{{ end }}",
],
"style": "folder"
foreground: "#193549",
foreground_templates: [
"{{ if and (gt .Ahead 0) (gt .Behind 0) }}#ffffff{{ end }}",
],
powerline_symbol: "\ue0b0",
template:
" {{ .HEAD }}{{if .BranchStatus }} {{ .BranchStatus }}{{ end }} ",
properties: {
branch_max_length: 25,
fetch_status: true,
},
style: "powerline",
type: "git",
},
"style": "powerline",
"type": "path"
},
{
"background": "#2e9599",
"background_templates": [
"{{ if or (.Working.Changed) (.Staging.Changed) }}#f36943{{ end }}",
"{{ if and (gt .Ahead 0) (gt .Behind 0) }}#a8216b{{ end }}",
"{{ if gt .Ahead 0 }}#35b5ff{{ end }}",
"{{ if gt .Behind 0 }}#f89cfa{{ end }}"
],
"foreground": "#193549",
"foreground_templates": [
"{{ if and (gt .Ahead 0) (gt .Behind 0) }}#ffffff{{ end }}"
],
"powerline_symbol": "\ue0b0",
"template": " {{ .HEAD }}{{if .BranchStatus }} {{ .BranchStatus }}{{ end }} ",
"properties": {
"branch_max_length": 25,
"fetch_status": true
{
background: "#00897b",
background_templates: ["{{ if gt .Code 0 }}#e91e63{{ end }}"],
foreground: "#ffffff",
template: "<parentBackground>\ue0b0</> \ue23a ",
properties: {
always_enabled: true,
},
style: "diamond",
trailing_diamond: "\ue0b4",
type: "status",
},
"style": "powerline",
"type": "git"
},
{
"background": "#00897b",
"background_templates": [
"{{ if gt .Code 0 }}#e91e63{{ end }}"
],
"foreground": "#ffffff",
"template": "<parentBackground>\ue0b0</> \ue23a ",
"properties": {
"always_enabled": true
},
"style": "diamond",
"trailing_diamond": "\ue0b4",
"type": "status"
}
],
"type": "prompt"
}
],
"final_space": true,
"version": 2
}}/>
],
type: "prompt",
},
],
final_space: true,
version: 2,
}}
/>

View file

@ -12,7 +12,7 @@ A really simple configuration could look like this. The default format is `json`
There's a [schema][schema] available which is kept up-to-date and helps with autocomplete and validation of the configuration.
:::info
There are a few [themes][themes] available which are basically predefined configs. You can use these as they are, or as a
There are a few [themes][themes] available which are basically predefined configurations. You can use these as they are, or as a
starting point to create your own configuration.
:::
@ -107,7 +107,7 @@ escape characters to see the prompt as it would be shown inside a prompt functio
:::caution
The command below will not persist the configuration for your shell but print the prompt in your terminal.
If you want to use your own configuration permanently, adjust the prompt configuration to use your custom
theme.
configuration.
:::
```bash
@ -124,7 +124,7 @@ For example, the following is a valid `--config` flag:
`--config 'https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/jandedobbeleer.omp.json'`
:::
## General Settings
## Settings
| Name | Type | Default | Description |
| --------------------------- | ---------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@ -142,9 +142,9 @@ For example, the following is a valid `--config` flag:
### JSON Schema Validation
As mentioned above, Oh My Posh themes can utilize JSON Schema to validate their contents. Themes should include a link to
As mentioned above, Oh My Posh configurations can utilize JSON Schema to validate their contents. Configurations should include a link to
the [external schema document][schema] which prescribes the appropriate structure and contents for various elements. If
your code editor is configured to use JSON Schema, it will compare your custom theme to the external document, and issue
your code editor is configured to use JSON Schema, it will compare your configuration to the external document, and issue
warnings for discrepancies.
For example, given the following code:
@ -166,7 +166,7 @@ warnings, and ignore them at your peril.
### Accepted Formats
Oh My Posh supports three file formats for themes: `json`, `yaml`, and `toml`.
Oh My Posh supports three file formats for configurations: `json`, `yaml`, and `toml`.
Various converters exist to convert between these, although they aren't perfect and will require manual
adjustment. Notably, the schema implementation for json is as follows:

View file

@ -32,6 +32,8 @@ understand how to configure a segment.
}}
/>
## Settings
| Name | Type | Description |
| -------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type` | `string` | takes the `string` value referencing which segment logic it needs to run (see [segments][segments] for possible values) |
@ -53,7 +55,9 @@ understand how to configure a segment.
| `alias` | `string` | for use with [cross segment template properties][cstp] |
| `min_width` | `int` | if the terminal width is smaller than this value, the segment will be hidden. For your terminal width, see `oh-my-posh get width`. Defaults to `0` (disable) |
| `max_width` | `int` | if the terminal width exceeds this value, the segment will be hidden. For your terminal width, see `oh-my-posh get width`. Defaults to `0` (disable) |
| `cache` | `Cache` | how to cache the segment to avoid fetching information too much, see [Cache][cache] below |
| `cache` | `Cache` | how to cache the segment to avoid fetching information too much, see [below][cache] |
| `include_folders` | `[]string` | define which folders to include to enable the segment, see [below][include-exclude] |
| `exclude_folders` | `[]string` | define which folders to exclude to disable the segment, see [below][include-exclude] |
:::warning
In Bash/Zsh, when the property `interactive` is `true` for a segment, the prompt length calculation can be wrong
@ -142,22 +146,7 @@ regardless of the folder you're in.
The session strategy will cache the segment based on the current shell session. Use this for segments you want to display at all times
but don't want to refresh too often.
## Properties
An array of Properties with a value. This is used inside of the segment logic to tweak what the output of the segment will be.
Segments have the ability to define their own Properties, but there are some shared ones being used by the engine which allow
you to customize the output even more.
### Shared properties
You can use these on any segment, the engine is responsible for adding them correctly.
| Name | Type |
| ----------------- | ---------- |
| `include_folders` | `[]string` |
| `exclude_folders` | `[]string` |
#### Include / Exclude Folders
## Include / Exclude Folders
Sometimes you might want to have a segment only rendered in certain folders. If `include_folders` is specified,
the segment will only be rendered when in one of those locations. If `exclude_folders` is specified, the segment
@ -165,17 +154,13 @@ will not be rendered when in one of the excluded locations.
<Config
data={{
properties: {
include_folders: ["/Users/posh/Projects"],
},
include_folders: ["/Users/posh/Projects"],
}}
/>
<Config
data={{
properties: {
exclude_folders: ["/Users/posh/Projects"],
},
exclude_folders: ["/Users/posh/Projects"],
}}
/>
@ -185,9 +170,7 @@ name. The following will match `/Users/posh/Projects/Foo` but not `/home/Users/p
<Config
data={{
properties: {
include_folders: ["/Users/posh/Projects.*"],
},
include_folders: ["/Users/posh/Projects/.*"],
}}
/>
@ -195,15 +178,12 @@ You can also combine these properties:
<Config
data={{
properties: {
include_folders: ["/Users/posh/Projects.*"],
exclude_folders: ["/Users/posh/Projects/secret-project.*"],
},
include_folders: ["/Users/posh/Projects/.*"],
exclude_folders: ["/Users/posh/Projects/secret-project.*"],
}}
/>
#### Notes
:::info
- Oh My Posh will accept both `/` and `\` as path separators for a folder and will match regardless of which
is used by the current operating system.
- Because the strings are evaluated as regular expressions, if you want to use a backslash (`\`) in a Windows
@ -213,6 +193,7 @@ You can also combine these properties:
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.
:::
## Hiding segments
@ -255,3 +236,5 @@ To list the currently toggled segments, use `oh-my-posh get toggles`.
[templates]: templates.mdx
[color-templates]: /docs/configuration/colors#color-templates
[cstp]: templates.mdx#cross-segment-template-properties
[cache]: #cache
[include-exclude]: #include--exclude-folders