on main help sign in
perf: make it a tad faster
a05b434Carlos Alexandro Becker
internal/fsext/ls.go+76−72
@@ -5,6 +5,7 @@ import (
5 "os"
5 "os"
6 "path/filepath"
6 "path/filepath"
7 "strings"
7 "strings"
8+ "sync"
8
9
9 "github.com/charlievieth/fastwalk"
10 "github.com/charlievieth/fastwalk"
10 "github.com/charmbracelet/crush/internal/config"
11 "github.com/charmbracelet/crush/internal/config"
@@ -13,62 +14,79 @@ import (
13)
14)
14
15
15// commonIgnorePatterns contains commonly ignored files and directories
16// commonIgnorePatterns contains commonly ignored files and directories
16−var commonIgnorePatterns = ignore.CompileIgnoreLines(
17+var commonIgnorePatterns = sync.OnceValue(func() ignore.IgnoreParser {
18+ return ignore.CompileIgnoreLines(
17− // Version control
19+ // Version control
18− ".git",
20+ ".git",
19− ".svn",
21+ ".svn",
20− ".hg",
22+ ".hg",
21− ".bzr",
23+ ".bzr",
22−
24+
23− // IDE and editor files
25+ // IDE and editor files
24− ".vscode",
26+ ".vscode",
25− ".idea",
27+ ".idea",
26− "*.swp",
28+ "*.swp",
27− "*.swo",
29+ "*.swo",
28− "*~",
30+ "*~",
29− ".DS_Store",
31+ ".DS_Store",
30− "Thumbs.db",
32+ "Thumbs.db",
31−
33+
32− // Build artifacts and dependencies
34+ // Build artifacts and dependencies
33− "node_modules",
35+ "node_modules",
34− "target",
36+ "target",
35− "build",
37+ "build",
36− "dist",
38+ "dist",
37− "out",
39+ "out",
38− "bin",
40+ "bin",
39− "obj",
41+ "obj",
40− "*.o",
42+ "*.o",
41− "*.so",
43+ "*.so",
42− "*.dylib",
44+ "*.dylib",
43− "*.dll",
45+ "*.dll",
44− "*.exe",
46+ "*.exe",
45−
47+
46− // Logs and temporary files
48+ // Logs and temporary files
47− "*.log",
49+ "*.log",
48− "*.tmp",
50+ "*.tmp",
49− "*.temp",
51+ "*.temp",
50− ".cache",
52+ ".cache",
51− ".tmp",
53+ ".tmp",
52−
54+
53− // Language-specific
55+ // Language-specific
54− "__pycache__",
56+ "__pycache__",
55− "*.pyc",
57+ "*.pyc",
56− "*.pyo",
58+ "*.pyo",
57− ".pytest_cache",
59+ ".pytest_cache",
58− "vendor",
60+ "vendor",
59− "Cargo.lock",
61+ "Cargo.lock",
60− "package-lock.json",
62+ "package-lock.json",
61− "yarn.lock",
63+ "yarn.lock",
62− "pnpm-lock.yaml",
64+ "pnpm-lock.yaml",
63−
65+
64− // OS generated files
66+ // OS generated files
65− ".Trash",
67+ ".Trash",
66− ".Spotlight-V100",
68+ ".Spotlight-V100",
67− ".fseventsd",
69+ ".fseventsd",
68−
70+
69− // Crush
71+ // Crush
70− ".crush",
72+ ".crush",
73+ )
74+})
75+
76+var homeIgnore = sync.OnceValue(func() ignore.IgnoreParser {
77+ home := config.HomeDir()
78+ var lines []string
79+ for _, name := range []string{
80+ filepath.Join(home, ".gitignore"),
81+ filepath.Join(home, ".config", "git", "ignore"),
82+ filepath.Join(home, ".config", "crush", "ignore"),
83+ } {
84+ if bts, err := os.ReadFile(name); err == nil {
85+ lines = append(lines, strings.Split(string(bts), "\n")...)
86+ }
87+ }
88+ return ignore.CompileIgnoreLines(lines...)
71−)
89+})
72
90
73type directoryLister struct {
91type directoryLister struct {
74 ignores *csync.Map[string, ignore.IgnoreParser]
92 ignores *csync.Map[string, ignore.IgnoreParser]
@@ -81,20 +99,6 @@ func NewDirectoryLister(rootPath string) *directoryLister {
81 ignores: csync.NewMap[string, ignore.IgnoreParser](),
99 ignores: csync.NewMap[string, ignore.IgnoreParser](),
82 }
100 }
83 dl.getIgnore(rootPath)
101 dl.getIgnore(rootPath)
84− dl.ignores.GetOrSet("~", func() ignore.IgnoreParser {
85− home := config.HomeDir()
86− var lines []string
87− for _, name := range []string{
88− filepath.Join(home, ".gitignore"),
89− filepath.Join(home, ".config", "git", "ignore"),
90− filepath.Join(home, ".config", "crush", "ignore"),
91− } {
92− if bts, err := os.ReadFile(name); err == nil {
93− lines = append(lines, strings.Split(string(bts), "\n")...)
94− }
95− }
96− return ignore.CompileIgnoreLines(lines...)
97− })
98 return dl
102 return dl
99}
103}
100
104
@@ -126,7 +130,7 @@ func (dl *directoryLister) shouldIgnore(path string, ignorePatterns []string) bo
126 relPath = path
130 relPath = path
127 }
131 }
128
132
129− if commonIgnorePatterns.MatchesPath(relPath) {
133+ if commonIgnorePatterns().MatchesPath(relPath) {
130 slog.Debug("ingoring common pattern", "path", relPath)
134 slog.Debug("ingoring common pattern", "path", relPath)
131 return true
135 return true
132 }
136 }
@@ -140,7 +144,7 @@ func (dl *directoryLister) shouldIgnore(path string, ignorePatterns []string) bo
140 return true
144 return true
141 }
145 }
142
146
143− if dl.getIgnore("~").MatchesPath(relPath) {
147+ if homeIgnore().MatchesPath(relPath) {
144 slog.Debug("ingoring home dir pattern", "path", relPath)
148 slog.Debug("ingoring home dir pattern", "path", relPath)
145 return true
149 return true
146 }
150 }