Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: disable completions #6122

Merged
merged 10 commits into from
Feb 27, 2025
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ updates:
target-branch: "main"
schedule:
interval: "daily"
groups:
all:
patterns:
- "*"
ignore:
- dependency-name: "softprops/action-gh-release"
# https://github.com/softprops/action-gh-release/issues/556
Expand All @@ -18,3 +22,10 @@ updates:
target-branch: "main"
schedule:
interval: "daily"
groups:
minor-patch:
patterns:
- "*"
update-types:
- "minor"
- "patch"
7 changes: 5 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@
"args": [
"prompt",
"print",
"primary",
"right",
"--shell=pwsh",
"--terminal-width=200"
]
],
"env": {
"POSH_THEME": "C:\\Users\\jande\\.posh.omp.jsonc"
}
},
{
"name": "Tooltip",
Expand Down
11 changes: 6 additions & 5 deletions src/cache/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,20 @@ type Template struct {
SegmentsCache maps.Simple
Segments *maps.Concurrent
Var maps.Simple
ShellVersion string
AbsolutePWD string
PWD string
Folder string
PSWD string
UserName string
HostName string
PWD string
ShellVersion string
Shell string
Folder string
AbsolutePWD string
OS string
Code int
Version string
PromptCount int
SHLVL int
Jobs int
Code int
WSL bool
Root bool
}
Expand Down
3 changes: 3 additions & 0 deletions src/cli/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,7 @@ func init() {

// Hide flags that are deprecated or for internal use only.
_ = RootCmd.PersistentFlags().MarkHidden("silent")

// Disable completions
RootCmd.CompletionOptions.DisableDefaultCmd = true
}
2 changes: 1 addition & 1 deletion src/config/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func Default(warning bool) *Config {
"{{ if gt .Ahead 0 }}p:white{{ end }}",
},
Properties: properties.Map{
segments.BranchMaxLength: 25,
segments.BranchTemplate: "{{ trunc 25 .Branch }}",
segments.FetchStatus: true,
segments.FetchUpstreamIcon: true,
},
Expand Down
28 changes: 23 additions & 5 deletions src/config/segment.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,18 @@ type Segment struct {
Type SegmentType `json:"type,omitempty" toml:"type,omitempty"`
Style SegmentStyle `json:"style,omitempty" toml:"style,omitempty"`
LeadingPowerlineSymbol string `json:"leading_powerline_symbol,omitempty" toml:"leading_powerline_symbol,omitempty"`
Tips []string `json:"tips,omitempty" toml:"tips,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"`
Needs []string `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"`
MaxWidth int `json:"max_width,omitempty" toml:"max_width,omitempty"`
Timeout time.Duration `json:"timeout,omitempty" toml:"timeout,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"`
Expand Down Expand Up @@ -121,8 +122,25 @@ func (segment *Segment) Execute(env runtime.Environment) {
return
}

if segment.writer.Enabled() {
segment.Enabled = true
if segment.Timeout == 0 {
segment.Enabled = segment.writer.Enabled()
} else {
done := make(chan bool)
go func() {
segment.Enabled = segment.writer.Enabled()
done <- true
}()

select {
case <-done:
// Completed before timeout
case <-time.After(segment.Timeout * time.Millisecond):
log.Debugf("timeout after %dms for segment: %s", segment.Timeout, segment.Name())
return
}
}

if segment.Enabled {
template.Cache.AddSegmentData(segment.Name(), segment.writer)
}
}
Expand Down
69 changes: 58 additions & 11 deletions src/regex/regex.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package regex
import (
"regexp"
"sync"

"github.com/jandedobbeleer/oh-my-posh/src/log"
)

var (
Expand All @@ -14,50 +16,67 @@ const (
LINK = `(?P<STR>\x1b]8;;(.+)\x1b\\(?P<TEXT>.+)\x1b]8;;\x1b\\)`
)

func GetCompiledRegex(pattern string) *regexp.Regexp {
func GetCompiledRegex(pattern string) (*regexp.Regexp, error) {
// try in cache first
regexCacheLock.RLock()
re := regexCache[pattern]
regexCacheLock.RUnlock()
if re != nil {
return re
return re, nil
}

// should we panic or return the error?
re = regexp.MustCompile(pattern)
re, err := regexp.Compile(pattern)
if err != nil {
log.Error(err)
return nil, err
}

// lock for concurrent access and save the compiled expression in cache
regexCacheLock.Lock()
regexCache[pattern] = re
regexCacheLock.Unlock()

return re
return re, nil
}

func FindNamedRegexMatch(pattern, text string) map[string]string {
// error ignored because mustCompile will cause a panic
re := GetCompiledRegex(pattern)
match := re.FindStringSubmatch(text)
result := make(map[string]string)

re, err := GetCompiledRegex(pattern)
if err != nil {
return result
}

match := re.FindStringSubmatch(text)
if len(match) == 0 {
return result
}

for i, name := range re.SubexpNames() {
if i == 0 {
continue
}
result[name] = match[i]
}

return result
}

func FindAllNamedRegexMatch(pattern, text string) []map[string]string {
re := GetCompiledRegex(pattern)
match := re.FindAllStringSubmatch(text, -1)
var results []map[string]string

re, err := GetCompiledRegex(pattern)
if err != nil {
return results
}

match := re.FindAllStringSubmatch(text, -1)

if len(match) == 0 {
return results
}

for _, set := range match {
result := make(map[string]string)
for i, name := range re.SubexpNames() {
Expand All @@ -69,15 +88,43 @@ func FindAllNamedRegexMatch(pattern, text string) []map[string]string {
}
results = append(results, result)
}

return results
}

func ReplaceAllString(pattern, text, replaceText string) string {
re := GetCompiledRegex(pattern)
re, err := GetCompiledRegex(pattern)
if err != nil {
return text
}

return re.ReplaceAllString(text, replaceText)
}

func MatchString(pattern, text string) bool {
re := GetCompiledRegex(pattern)
re, err := GetCompiledRegex(pattern)
if err != nil {
return false
}

return re.MatchString(text)
}

func FindStringMatch(pattern, text string, index int) string {
re, err := GetCompiledRegex(pattern)
if err != nil {
return text
}

matches := re.FindStringSubmatch(text)
if len(matches) <= index {
return text
}

match := matches[index]
if len(match) == 0 {
return text
}

return match
}
72 changes: 72 additions & 0 deletions src/regex/regex_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package regex

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestFindStringMatch(t *testing.T) {
cases := []struct {
Case string
Pattern string
Text string
Expected string
Index int
}{
{
Case: "Full match at index 0",
Pattern: `\w+`,
Text: "hello",
Index: 0,
Expected: "hello",
},
{
Case: "Capture group at index 1",
Pattern: `hello (\w+)`,
Text: "hello world",
Index: 1,
Expected: "world",
},
{
Case: "No matches returns original text",
Pattern: `\d+`,
Text: "hello",
Index: 0,
Expected: "hello",
},
{
Case: "Invalid pattern returns original text",
Pattern: `[invalid`,
Text: "hello",
Index: 0,
Expected: "hello",
},
{
Case: "Empty text returns empty string",
Pattern: `\w+`,
Text: "",
Index: 0,
Expected: "",
},
{
Case: "Index out of bounds returns original text",
Pattern: `(\w+)`,
Text: "hello",
Index: 2,
Expected: "hello",
},
{
Case: "Multiple capture groups",
Pattern: `(\w+)\s(\w+)`,
Text: "hello world",
Index: 2,
Expected: "world",
},
}

for _, tc := range cases {
got := FindStringMatch(tc.Pattern, tc.Text, tc.Index)
assert.Equal(t, tc.Expected, got, tc.Case)
}
}
6 changes: 4 additions & 2 deletions src/runtime/path/clean.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,10 @@ func Clean(input string) string {
}

// Always use an uppercase drive letter on Windows.
driveLetter := regex.GetCompiledRegex(`^[a-z]:`)
cleaned = driveLetter.ReplaceAllStringFunc(cleaned, strings.ToUpper)
driveLetter, err := regex.GetCompiledRegex(`^[a-z]:`)
if err == nil {
cleaned = driveLetter.ReplaceAllStringFunc(cleaned, strings.ToUpper)
}
}

sb := new(strings.Builder)
Expand Down
9 changes: 7 additions & 2 deletions src/runtime/terminal.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,14 @@ func (term *Terminal) setPwd() {
if term.GOOS() != WINDOWS {
return pwd
}

// on Windows, and being case sensitive and not consistent and all, this gives silly issues
driveLetter := regex.GetCompiledRegex(`^[a-z]:`)
return driveLetter.ReplaceAllStringFunc(pwd, strings.ToUpper)
driveLetter, err := regex.GetCompiledRegex(`^[a-z]:`)
if err == nil {
return driveLetter.ReplaceAllStringFunc(pwd, strings.ToUpper)
}

return pwd
}

if term.CmdFlags != nil && term.CmdFlags.PWD != "" {
Expand Down
10 changes: 5 additions & 5 deletions src/segments/battery.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ import (

type Battery struct {
base

*battery.Info
Error string
Icon string
battery.Info
}

const (
Expand All @@ -34,15 +33,16 @@ func (b *Battery) Enabled() bool {
return false
}

var err error
b.Info, err = b.env.BatteryState()
info, err := b.env.BatteryState()

if !b.enabledWhileError(err) {
return false
}

b.Info = *info

// case on computer without batteries(no error, empty array)
if err == nil && b.Info == nil {
if err == nil && b.Info.Percentage == 0 {
return false
}

Expand Down
Loading