feat: add ignore filtering to directory listing

- Add `list_directory_filtered` function with ignore logic
- Update `default_gitignore` with common VCS and build patterns
- Integrate ignore filtering into `Workspace.list_dir`
- Rename project to HeroPrompt in README
- Update README features and usage descriptions
This commit is contained in:
Mahmoud-Emad
2025-08-24 13:57:25 +03:00
parent d6ea18e6db
commit cd512813e3
4 changed files with 71 additions and 22 deletions

View File

@@ -8,7 +8,7 @@ module codewalker
// - Lines starting with '#' are comments; empty lines ignored
// No negation support for simplicity
const default_gitignore = '__pycache__/\n*.py[cod]\n*.so\n.Python\nbuild/\ndevelop-eggs/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\n*.egg-info/\n.installed.cfg\n*.egg\n.env\n.venv\nvenv/\n.tox/\n.nox/\n.coverage\n.coveragerc\ncoverage.xml\n*.cover\n*.gem\n*.pyc\n.cache\n.pytest_cache/\n.mypy_cache/\n.hypothesis/\n'
const default_gitignore = '.git/\n.svn/\n.hg/\n.bzr/\nnode_modules/\n__pycache__/\n*.py[cod]\n*.so\n.Python\nbuild/\ndevelop-eggs/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\n*.egg-info/\n.installed.cfg\n*.egg\n.env\n.venv\nvenv/\n.tox/\n.nox/\n.coverage\n.coveragerc\ncoverage.xml\n*.cover\n*.gem\n*.pyc\n.cache\n.pytest_cache/\n.mypy_cache/\n.hypothesis/\n.DS_Store\nThumbs.db\n*.tmp\n*.temp\n*.log\n'
struct IgnoreRule {
base string // relative dir from source root where the ignore file lives ('' means global)

View File

@@ -110,6 +110,56 @@ pub fn list_directory(base_path string, rel_path string) ![]DirItem {
return out
}
// list_directory_filtered lists the contents of a directory with ignore filtering applied.
// - base_path: workspace base path
// - rel_path: relative path from base (or absolute path)
// - ignore_matcher: IgnoreMatcher to filter out ignored files/directories
// Returns a list of DirItem with name and type (file/directory), filtered by ignore patterns.
pub fn list_directory_filtered(base_path string, rel_path string, ignore_matcher &IgnoreMatcher) ![]DirItem {
dir := resolve_path(base_path, rel_path)
if dir.len == 0 {
return error('base_path not set')
}
entries := os.ls(dir) or { return error('cannot list directory') }
mut out := []DirItem{}
for e in entries {
full := os.join_path(dir, e)
// Calculate relative path from base_path for ignore checking
mut check_path := if rel_path.len > 0 {
if rel_path.ends_with('/') { rel_path + e } else { rel_path + '/' + e }
} else {
e
}
// For directories, also check with trailing slash
is_directory := os.is_dir(full)
mut should_ignore := ignore_matcher.is_ignored(check_path)
if is_directory && !should_ignore {
// Also check directory pattern with trailing slash
should_ignore = ignore_matcher.is_ignored(check_path + '/')
}
// Check if this entry should be ignored
if should_ignore {
continue
}
if is_directory {
out << DirItem{
name: e
typ: 'directory'
}
} else if os.is_file(full) {
out << DirItem{
name: e
typ: 'file'
}
}
}
return out
}
// list_files_recursive recursively lists all files in a directory
pub fn list_files_recursive(root string) []string {
mut out := []string{}

View File

@@ -222,7 +222,9 @@ pub:
}
pub fn (wsp &Workspace) list_dir(rel_path string) ![]ListItem {
items := codewalker.list_directory(wsp.base_path, rel_path)!
// Create an ignore matcher with default patterns
ignore_matcher := codewalker.gitignore_matcher_new()
items := codewalker.list_directory_filtered(wsp.base_path, rel_path, &ignore_matcher)!
mut out := []ListItem{}
for item in items {
out << ListItem{