Prefer lowercase entries

Also recurse to depth 1 by default. This matches behavior of GUI file
select dialogs and prevents perf problems
This commit is contained in:
Kovid Goyal
2025-06-01 09:01:43 +05:30
parent cb477bfcfc
commit 4d77c8739e
3 changed files with 28 additions and 4 deletions

View File

@@ -249,6 +249,7 @@ func main(_ *cli.Command, opts *Options, args []string) (rc int, err error) {
default: default:
return 1, fmt.Errorf("Can only specify one directory to search in") return 1, fmt.Errorf("Can only specify one directory to search in")
} }
default_cwd = utils.Expanduser(default_cwd)
lp.OnInitialize = handler.OnInitialize lp.OnInitialize = handler.OnInitialize
lp.OnResize = func(old, new_size loop.ScreenSize) (err error) { lp.OnResize = func(old, new_size loop.ScreenSize) (err error) {
handler.init_sizes(new_size) handler.init_sizes(new_size)

View File

@@ -34,7 +34,7 @@ opt('+exclude_directory', '^/dev$', add_to_default=True)
opt('+exclude_directory', '^/sys$', add_to_default=True) opt('+exclude_directory', '^/sys$', add_to_default=True)
opt('+exclude_directory', '/__pycache__$', add_to_default=True) opt('+exclude_directory', '/__pycache__$', add_to_default=True)
opt('max_depth', '4', option_type='positive_int', long_text=''' opt('max_depth', '1', 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 The maximum depth to which to scan the filesystem for matches. Using large values will slow things down considerably. The better
approach is to use a small value and first change to the directory of interest then actually select the file of interest. approach is to use a small value and first change to the directory of interest then actually select the file of interest.
''') ''')

View File

@@ -10,6 +10,7 @@ import (
"sort" "sort"
"strings" "strings"
"sync" "sync"
"unicode"
"github.com/kovidgoyal/kitty/tools/tui/subseq" "github.com/kovidgoyal/kitty/tools/tui/subseq"
"github.com/kovidgoyal/kitty/tools/utils" "github.com/kovidgoyal/kitty/tools/utils"
@@ -106,11 +107,14 @@ func sort_items_without_search_text(items []ResultItem) (ans []*ResultItem) {
d := utils.Map(func(x ResultItem) s { d := utils.Map(func(x ResultItem) s {
return s{strings.ToLower(x.text), strings.Count(x.text, "/"), x.dir_entry.IsDir(), hidden_pat.MatchString(x.abspath), &x} return s{strings.ToLower(x.text), strings.Count(x.text, "/"), x.dir_entry.IsDir(), hidden_pat.MatchString(x.abspath), &x}
}, items) }, items)
sort.Slice(d, func(i, j int) bool { sort.SliceStable(d, func(i, j int) bool {
a, b := d[i], d[j] a, b := d[i], d[j]
if a.num_of_slashes == b.num_of_slashes { if a.num_of_slashes == b.num_of_slashes {
if a.is_dir == b.is_dir { if a.is_dir == b.is_dir {
if a.is_hidden == b.is_hidden { if a.is_hidden == b.is_hidden {
if a.ltext == b.ltext {
return count_uppercase(a.r.text) < count_uppercase(b.r.text)
}
return a.ltext < b.ltext return a.ltext < b.ltext
} }
return b.is_hidden return b.is_hidden
@@ -131,6 +135,16 @@ func get_modified_score(r *ResultItem, score float64, score_patterns []ScorePatt
return score return score
} }
func count_uppercase(s string) int {
count := 0
for _, r := range s {
if unicode.IsUpper(r) {
count++
}
}
return count
}
func (sc *ScanCache) scan(root_dir, search_text string, max_depth int, exclude_patterns []*regexp.Regexp, score_patterns []ScorePattern) (ans []*ResultItem) { func (sc *ScanCache) scan(root_dir, search_text string, max_depth int, exclude_patterns []*regexp.Regexp, score_patterns []ScorePattern) (ans []*ResultItem) {
seen := make(map[string]bool, 1024) seen := make(map[string]bool, 1024)
matches := sc.fs_scan(root_dir, root_dir, max_depth, exclude_patterns, seen) matches := sc.fs_scan(root_dir, root_dir, max_depth, exclude_patterns, seen)
@@ -155,7 +169,16 @@ func (sc *ScanCache) scan(root_dir, search_text string, max_depth int, exclude_p
x.positions = m.Positions x.positions = m.Positions
return s{x, get_modified_score(x, m.Score, score_patterns)} return s{x, get_modified_score(x, m.Score, score_patterns)}
}, matches2) }, matches2)
slices.SortFunc(ss, func(a, b s) int { return cmp.Compare(b.score, a.score) }) slices.SortStableFunc(ss, func(a, b s) int {
ans := cmp.Compare(b.score, a.score)
if ans == 0 {
ans = cmp.Compare(len(a.r.text), len(b.r.text))
if ans == 0 {
ans = cmp.Compare(count_uppercase(a.r.text), count_uppercase(b.r.text))
}
}
return ans
})
return utils.Map(func(s s) *ResultItem { return s.r }, ss) return utils.Map(func(s s) *ResultItem { return s.r }, ss)
} }
@@ -175,7 +198,7 @@ func (h *Handler) get_results() (ans []*ResultItem, in_progress bool) {
search_text := h.state.SearchText() search_text := h.state.SearchText()
sc.root_dir = root_dir sc.root_dir = root_dir
sc.search_text = search_text sc.search_text = search_text
md, ep, sp := h.state.MaxDepth(), h.state.ExcludePatterns(), h.state.ScorePatterns() md, ep, sp := max(0, h.state.MaxDepth()-1), h.state.ExcludePatterns(), h.state.ScorePatterns()
go func() { go func() {
results := sc.scan(root_dir, search_text, md, ep, sp) results := sc.scan(root_dir, search_text, md, ep, sp)
sc.mutex.Lock() sc.mutex.Lock()