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:
return 1, fmt.Errorf("Can only specify one directory to search in")
}
default_cwd = utils.Expanduser(default_cwd)
lp.OnInitialize = handler.OnInitialize
lp.OnResize = func(old, new_size loop.ScreenSize) (err error) {
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', '/__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
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"
"strings"
"sync"
"unicode"
"github.com/kovidgoyal/kitty/tools/tui/subseq"
"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 {
return s{strings.ToLower(x.text), strings.Count(x.text, "/"), x.dir_entry.IsDir(), hidden_pat.MatchString(x.abspath), &x}
}, items)
sort.Slice(d, func(i, j int) bool {
sort.SliceStable(d, func(i, j int) bool {
a, b := d[i], d[j]
if a.num_of_slashes == b.num_of_slashes {
if a.is_dir == b.is_dir {
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 b.is_hidden
@@ -131,6 +135,16 @@ func get_modified_score(r *ResultItem, score float64, score_patterns []ScorePatt
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) {
seen := make(map[string]bool, 1024)
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
return s{x, get_modified_score(x, m.Score, score_patterns)}
}, 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)
}
@@ -175,7 +198,7 @@ func (h *Handler) get_results() (ans []*ResultItem, in_progress bool) {
search_text := h.state.SearchText()
sc.root_dir = root_dir
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() {
results := sc.scan(root_dir, search_text, md, ep, sp)
sc.mutex.Lock()