use clap::{Parser, ValueEnum};
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub enum OutputFormat {
Human,
Agent,
Json,
Quiet,
}
#[derive(Parser, Debug)]
#[command(
name = "loc",
version = env!("CARGO_PKG_VERSION"),
author = "kelexine <https://github.com/kelexine>",
about = "Advanced LOC counter — functions, git dates, parallel scan, multi-format output",
after_help = "\
EXAMPLES:
loc Count LOC in current directory
loc src/ Scan a specific directory
loc -d Show per-language breakdown table
loc -f Extract and list functions/methods
loc -f --func-analysis Full function complexity report
loc -t rust python Only scan Rust and Python files
loc -e results.json Export to JSON
loc -e stats.csv -f Export CSV with function data
loc -e report.html Export interactive HTML dashboard
loc --warn-size 500 Warn about files > 500 lines
loc --git-dates Use git log for last-modified dates
loc --tree Show directory tree (flat TSV in agent mode)
loc --format agent Force machine-readable TSV output
loc --format agent -d -f Full TSV output with breakdown + functions
loc -q One path per line (pipe-friendly)
loc -q | head -20 First 20 matched paths
loc src/ -d -t rust -f -e out.json
OUTPUT MODES:
human Colored terminal output, truncated tables, hints at end [default]
agent TSV, no ANSI, nothing truncated — auto-detected from env vars
json JSON summary to stdout (same as --json)
quiet One matched path per line
AGENT AUTO-DETECTION:
loc detects coding agents from environment variables and switches to agent
mode automatically: CLAUDECODE, CLAUDE_CODE (Claude Code), CODEX_SANDBOX
(Codex), CURSOR_TRACE_ID (Cursor), AI_AGENT (any agent), and more.
Override with --format human to force terminal output.
SUPPORTED LANGUAGES:
python, javascript, typescript, rust, go, java, kotlin, swift,
c, cpp, csharp, ruby, php, html, css, shell, sql, markdown,
json, yaml, xml, jsx, vue, svelte, toml, scala, haskell, elixir, lua, zig, nim
FUNCTION EXTRACTION:
Rust, Python, JavaScript/TypeScript, Go, C/C++, Java/Kotlin/C#, PHP, Swift, Ruby"
)]
pub struct Args {
#[arg(default_value = ".")]
pub directory: String,
#[arg(short = 'd', long = "detailed")]
pub detailed: bool,
#[arg(short = 'b', long = "binary")]
pub binary: bool,
#[arg(short = 'f', long = "functions")]
pub functions: bool,
#[arg(long = "func-analysis")]
pub func_analysis: bool,
#[arg(short = 't', long = "type", value_name = "LANG", num_args = 1..)]
pub file_types: Vec<String>,
#[arg(short = 'e', long = "export", value_name = "FILE")]
pub export: Option<String>,
#[arg(long = "warn-size", value_name = "LINES")]
pub warn_size: Option<usize>,
#[arg(long = "git-dates")]
pub git_dates: bool,
#[arg(long = "no-parallel")]
pub no_parallel: bool,
#[arg(short = 'H', long = "include-hidden")]
pub include_hidden: bool,
#[arg(long = "tree")]
pub tree: bool,
#[arg(long = "json")]
pub json: bool,
#[arg(long = "format", value_name = "MODE")]
pub format: Option<OutputFormat>,
#[arg(short = 'q', long = "quiet")]
pub quiet: bool,
}