Merge branch 'main' into feature/yank

This commit is contained in:
T.v.Dein
2025-02-23 18:09:04 +01:00
committed by GitHub
18 changed files with 454 additions and 144 deletions

View File

@@ -1,5 +1,5 @@
/*
Copyright © 2022-2024 Thomas von Dein
Copyright © 2022-2025 Thomas von Dein
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -52,6 +52,17 @@ type Transposer struct {
Replace string
}
type Pattern struct {
Pattern string
PatternRe *regexp.Regexp
Negate bool
}
type Filter struct {
Regex *regexp.Regexp
Negate bool
}
// internal config
type Config struct {
Debug bool
@@ -64,8 +75,7 @@ type Config struct {
Separator string
OutputMode int
InvertMatch bool
Pattern string
PatternR *regexp.Regexp
Patterns []*Pattern
UseFuzzySearch bool
UseHighlight bool
@@ -97,7 +107,7 @@ type Config struct {
// used for field filtering
Rawfilters []string
Filters map[string]*regexp.Regexp
Filters map[string]Filter //map[string]*regexp.Regexp
// -r <file>
InputFile string
@@ -267,12 +277,20 @@ func (conf *Config) PrepareModeFlags(flag Modeflag) {
}
func (conf *Config) PrepareFilters() error {
conf.Filters = make(map[string]*regexp.Regexp, len(conf.Rawfilters))
conf.Filters = make(map[string]Filter, len(conf.Rawfilters))
for _, filter := range conf.Rawfilters {
parts := strings.Split(filter, "=")
for _, rawfilter := range conf.Rawfilters {
filter := Filter{}
parts := strings.Split(rawfilter, "!=")
if len(parts) != MAXPARTS {
return errors.New("filter field and value must be separated by =")
parts = strings.Split(rawfilter, "=")
if len(parts) != MAXPARTS {
return errors.New("filter field and value must be separated by '=' or '!='")
}
} else {
filter.Negate = true
}
reg, err := regexp.Compile(parts[1])
@@ -281,7 +299,8 @@ func (conf *Config) PrepareFilters() error {
parts[0], err)
}
conf.Filters[strings.ToLower(strings.ToLower(parts[0]))] = reg
filter.Regex = reg
conf.Filters[strings.ToLower(parts[0])] = filter
}
return nil
@@ -335,15 +354,37 @@ func (conf *Config) ApplyDefaults() {
}
}
func (conf *Config) PreparePattern(pattern string) error {
PatternR, err := regexp.Compile(pattern)
func (conf *Config) PreparePattern(patterns []*Pattern) error {
// regex checks if a pattern looks like /$pattern/[i!]
flagre := regexp.MustCompile(`^/(.*)/([i!]*)$`)
if err != nil {
return fmt.Errorf("regexp pattern %s is invalid: %w", conf.Pattern, err)
for _, pattern := range patterns {
matches := flagre.FindAllStringSubmatch(pattern.Pattern, -1)
// we have a regex with flags
for _, match := range matches {
pattern.Pattern = match[1] // the inner part is our actual pattern
flags := match[2] // the flags
for _, flag := range flags {
switch flag {
case 'i':
pattern.Pattern = `(?i)` + pattern.Pattern
case '!':
pattern.Negate = true
}
}
}
PatternRe, err := regexp.Compile(pattern.Pattern)
if err != nil {
return fmt.Errorf("regexp pattern %s is invalid: %w", pattern.Pattern, err)
}
pattern.PatternRe = PatternRe
}
conf.PatternR = PatternR
conf.Pattern = pattern
conf.Patterns = patterns
return nil
}