# Config Module
**Purpose**: Translate CLI arguments (and config files / env vars) into immutable runtime configuration with compiled pattern matchers.
## File Responsibilities
### patterns.rs
- **IgnorePatterns struct**: Container for all filtering rules
- **Glob integration**: Embeds `GlobMatcher` for complex pattern matching
- **Default patterns**: Hard-coded ignore rules (binary extensions, build artifacts)
- **should*ignore*\* methods**: Fast filtering predicates
### file.rs
- **ConfigFile struct**: YAML-backed configuration with serde support
- **CliOverride struct**: CLI-provided overrides (all optional)
- **ValidatedConfig struct**: Immutable, validated configuration
- **load_config_file()**: Secure file loading with TOCTOU mitigation
### mod.rs
- **Config struct**: Top-level runtime configuration wrapping `ValidatedConfig`
- **Config builder**: Converts Args → Config via layered Figment pipeline
- **EnvOverrides**: Custom Figment provider for `LUFF_*` env vars
- **Getters**: Read-only access via const fn where possible
- **printer_options()**: Constructs PrinterOptions for output formatters
## Critical Types
```rust
Config {
validated: ValidatedConfig, // All settings from config pipeline
root: PathBuf, // Base directory (absolute, from git or cwd)
skip_patterns: SkipPatterns, // Whether pattern filtering is active
}
ValidatedConfig {
include_dotfiles: bool, // Show hidden files/dirs
respect_gitignore: bool, // Honor .gitignore patterns
format: OutputFormat, // Markdown | Tree
max_depth: usize, // 0 = unlimited, max 100
max_files: usize, // 1–10_000_000
max_clipboard_mb: usize, // 0–1000
patterns: IgnorePatterns, // Compiled ignore rules
}
IgnorePatterns {
extensions: HashSet<String>, // Binary/non-text extensions
directories: HashSet<String>, // Build artifacts, caches
files: HashSet<String>, // Specific filenames (e.g., lock files)
globs: GlobMatcher, // Compiled glob patterns (e.g., src/**/*.test.rs)
}
```
## Precedence Order (highest → lowest)
1. CLI arguments (`CliOverride`)
2. Environment variables (`LUFF_*`, via `EnvOverrides`)
3. Config file (YAML, via `load_config_file`)
4. Built-in defaults (`ConfigFile::default`)
### Environment Variable Coverage
The following `LUFF_*` variables are supported:
- `LUFF_INCLUDE_DOTFILES` (bool)
- `LUFF_RESPECT_GITIGNORE` (bool)
- `LUFF_FORMAT` (string: "markdown" or "tree")
- `LUFF_MAX_DEPTH` (u64)
- `LUFF_MAX_FILES` (u64)
- `LUFF_MAX_CLIPBOARD_MB` (u64)
Pattern lists (`ignore_extensions`, `ignore_directories`, `ignore_files`,
`ignore_globs`) are intentionally **not** exposed as env vars because
comma-separated list parsing in env vars is error-prone and ambiguous.
Use a config file for custom patterns.
## Critical Methods
```rust
Config::from_args(args) -> Result<Config>
// Primary constructor, may call git::find_repository_root()
Config::from_args_with_env(args, env) -> Result<Config>
// Testable variant with injected EnvProvider
Config::root() -> &Path
Config::patterns() -> &IgnorePatterns
// Zero-cost getters (return references)
IgnorePatterns::should_ignore_extension(ext) -> bool
// O(1) HashSet lookup (case-insensitive)
IgnorePatterns::should_ignore_glob(path) -> bool
// O(m) GlobSet match
Config::printer_options() -> PrinterOptions
// Clones root + format + patterns for printer configuration
```
## Key Invariants
- Config is created once, shared via &Config (no Arc needed for single-threaded CLI)
- root is always absolute (validated during from_args)
- ValidatedConfig has private fields; only constructible through ConfigFile::validate()
- IgnorePatterns use lowercase strings for case-insensitive extension matching
- Glob patterns are compiled at config time, failing loudly if invalid
## Performance Notes
- HashSet lookups are O(1) average case
- Glob matching uses optimized DFAs from `globset`
- Patterns compiled once at Config creation
- Clone is cheap (small fields, HashSets/GlobSet are Arc-based internally)
- `max_clipboard_bytes()` is computed on access (no cached field to drift)