mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-08 22:28:24 +02:00
Use a regular expression for exclusion
This commit is contained in:
@@ -3,6 +3,7 @@ package choose_files
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/cli"
|
||||
@@ -21,19 +22,17 @@ type State struct {
|
||||
select_dirs bool
|
||||
multiselect bool
|
||||
max_depth int
|
||||
exclude_patterns *utils.Set[string]
|
||||
exclude_patterns []*regexp.Regexp
|
||||
search_text string
|
||||
}
|
||||
|
||||
func (s State) BaseDir() string { return utils.IfElse(s.base_dir == "", default_cwd, s.base_dir) }
|
||||
func (s State) SelectDirs() bool { return s.select_dirs }
|
||||
func (s State) Multiselect() bool { return s.multiselect }
|
||||
func (s State) MaxDepth() int { return utils.IfElse(s.max_depth < 1, 4, s.max_depth) }
|
||||
func (s State) String() string { return utils.Repr(s) }
|
||||
func (s State) SearchText() string { return s.search_text }
|
||||
func (s State) ExcludePatterns() *utils.Set[string] {
|
||||
return utils.IfElse(s.exclude_patterns == nil, utils.NewSet[string](2), s.exclude_patterns)
|
||||
}
|
||||
func (s State) BaseDir() string { return utils.IfElse(s.base_dir == "", default_cwd, s.base_dir) }
|
||||
func (s State) SelectDirs() bool { return s.select_dirs }
|
||||
func (s State) Multiselect() bool { return s.multiselect }
|
||||
func (s State) MaxDepth() int { return utils.IfElse(s.max_depth < 1, 4, s.max_depth) }
|
||||
func (s State) String() string { return utils.Repr(s) }
|
||||
func (s State) SearchText() string { return s.search_text }
|
||||
func (s State) ExcludePatterns() []*regexp.Regexp { return s.exclude_patterns }
|
||||
func (s State) CurrentDir() string {
|
||||
return utils.IfElse(s.current_dir == "", s.BaseDir(), s.current_dir)
|
||||
}
|
||||
@@ -112,14 +111,20 @@ func (h *Handler) OnText(text string, from_key_event, in_bracketed_paste bool) (
|
||||
|
||||
func (h *Handler) set_state_from_config(conf *Config) (err error) {
|
||||
h.state.max_depth = int(conf.Max_depth)
|
||||
h.state.exclude_patterns = utils.NewSet[string](len(conf.Exclude_directory))
|
||||
h.state.exclude_patterns = make([]*regexp.Regexp, 0, len(conf.Exclude_directory))
|
||||
seen := map[string]*regexp.Regexp{}
|
||||
for _, x := range conf.Exclude_directory {
|
||||
if strings.HasPrefix(x, "!") {
|
||||
h.state.exclude_patterns.Discard(x[1:])
|
||||
} else {
|
||||
h.state.exclude_patterns.Add(x)
|
||||
delete(seen, x[1:])
|
||||
} else if seen[x] == nil {
|
||||
if pat, err := regexp.Compile(x); err == nil {
|
||||
seen[x] = pat
|
||||
} else {
|
||||
return fmt.Errorf("The exclude directory pattern %#v is invalid: %w", x, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
h.state.exclude_patterns = utils.Values(seen)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -18,13 +18,20 @@ map = definition.add_map
|
||||
mma = definition.add_mouse_map
|
||||
|
||||
agr('scan', 'Scanning the filesystem')
|
||||
opt('+exclude_directory', '/proc', add_to_default=True, long_text='''
|
||||
Pattern to exclude directories. Can be specified multiple times. Matches against the absolute path to the directory.
|
||||
If the pattern starts with :code:`!`, the :code:`!` is removed and the remaning pattern is removed from the list of patterns. This
|
||||
opt(
|
||||
'+exclude_directory',
|
||||
'^/proc$',
|
||||
add_to_default=True,
|
||||
long_text='''
|
||||
Regular expression to exclude directories. Matching directories will not be recursed into, but
|
||||
you can still or change into them to inspect their contents. Can be specified multiple times. Matches against the absolute path to the directory.
|
||||
If the pattern starts with :code:`!`, the :code:`!` is removed and the remaining pattern is removed from the list of patterns. This
|
||||
can be used to remove the default excluded directory patterns.
|
||||
''')
|
||||
opt('+exclude_directory', '/dev', add_to_default=True)
|
||||
opt('+exclude_directory', '/sys', add_to_default=True)
|
||||
''',
|
||||
)
|
||||
opt('+exclude_directory', '^/dev$', add_to_default=True)
|
||||
opt('+exclude_directory', '^/sys$', add_to_default=True)
|
||||
opt('+exclude_directory', '/__pycache__$', add_to_default=True)
|
||||
|
||||
opt('max_depth', '4', option_type='positive_int', long_text='''
|
||||
The maximum depth to which to scan the filesystem for matches. Using large values will slow things down considerably. The better
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -64,16 +65,16 @@ func scan_dir(path, root_dir string) []ResultItem {
|
||||
return []ResultItem{}
|
||||
}
|
||||
|
||||
func is_excluded(path string, exclude_patterns *utils.Set[string]) bool {
|
||||
for pattern := range exclude_patterns.Iterable() {
|
||||
if matched, _ := filepath.Match(pattern, path); matched {
|
||||
func is_excluded(path string, exclude_patterns []*regexp.Regexp) bool {
|
||||
for _, pattern := range exclude_patterns {
|
||||
if pattern.MatchString(path) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (sc *ScanCache) fs_scan(root_dir, current_dir string, max_depth int, exclude_patterns *utils.Set[string], seen map[string]bool) (ans []ResultItem) {
|
||||
func (sc *ScanCache) fs_scan(root_dir, current_dir string, max_depth int, exclude_patterns []*regexp.Regexp, seen map[string]bool) (ans []ResultItem) {
|
||||
var found bool
|
||||
if ans, found = sc.get_cached_entries(current_dir); !found {
|
||||
ans = scan_dir(current_dir, root_dir)
|
||||
@@ -92,7 +93,7 @@ func (sc *ScanCache) fs_scan(root_dir, current_dir string, max_depth int, exclud
|
||||
return
|
||||
}
|
||||
|
||||
func (sc *ScanCache) scan(root_dir, search_text string, max_depth int, exclude_patterns *utils.Set[string]) (ans []ResultItem) {
|
||||
func (sc *ScanCache) scan(root_dir, search_text string, max_depth int, exclude_patterns []*regexp.Regexp) (ans []ResultItem) {
|
||||
seen := make(map[string]bool, 1024)
|
||||
ans = sc.fs_scan(root_dir, root_dir, max_depth, exclude_patterns, seen)
|
||||
if search_text == "" {
|
||||
|
||||
Reference in New Issue
Block a user