1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use std::path::PathBuf;
use clap::builder::Styles;
use clap::builder::styling::{AnsiColor, Effects};
use clap::{Parser, Subcommand};
const STYLES: Styles = Styles::styled()
.header(AnsiColor::Green.on_default().effects(Effects::BOLD))
.usage(AnsiColor::Green.on_default().effects(Effects::BOLD))
.literal(AnsiColor::Cyan.on_default().effects(Effects::BOLD))
.placeholder(AnsiColor::Cyan.on_default());
#[derive(Parser)]
#[command(name = "fatou")]
#[command(author, version)]
#[command(about = "Fatou: a language server, formatter, and linter for Julia")]
#[command(styles = STYLES)]
#[command(arg_required_else_help = true)]
pub struct Cli {
/// Path to an explicit `fatou.toml` (skips discovery).
#[arg(long, value_name = "PATH", global = true, conflicts_with = "no_config")]
pub config: Option<PathBuf>,
/// Ignore any discovered `fatou.toml` and use built-in defaults.
#[arg(long, global = true)]
pub no_config: bool,
#[command(subcommand)]
pub command: Commands,
}
#[derive(Subcommand)]
pub enum Commands {
/// Parse and display the CST for debugging.
Parse {
/// Input file (stdin if not provided).
file: Option<PathBuf>,
/// Suppress CST output to stdout.
#[arg(long)]
quiet: bool,
/// Verify parser losslessness (`reconstruct(text) == text`).
#[arg(long)]
verify: bool,
/// Output representation: the lossless CST (default) or the JuliaSyntax
/// s-expression projection (the parser oracle).
#[arg(long, value_enum, default_value_t = ParseFormat::Cst)]
to: ParseFormat,
},
/// Format `.jl` files.
Format {
/// Input file(s) or path(s) (stdin if omitted).
#[arg(value_name = "PATH")]
paths: Vec<PathBuf>,
/// Check formatting without writing; prints a diff and exits non-zero if
/// any file would change.
#[arg(long)]
check: bool,
/// Override the target line width.
#[arg(long, value_name = "N")]
line_width: Option<u32>,
/// Override the indent width.
#[arg(long, value_name = "N")]
indent_width: Option<u32>,
},
/// Lint `.jl` files.
Lint {
/// Input file(s) or path(s).
#[arg(value_name = "PATH")]
paths: Vec<PathBuf>,
/// Required in the groundwork phase: lint reports findings without
/// writing fixes.
#[arg(long)]
check: bool,
/// Output format.
#[arg(long, value_enum, default_value_t = LintOutput::Pretty)]
output: LintOutput,
},
/// Run the language server on stdio.
Lsp,
}
#[derive(clap::ValueEnum, Clone, Copy, Debug, PartialEq, Eq)]
pub enum LintOutput {
Pretty,
Concise,
Json,
}
#[derive(clap::ValueEnum, Clone, Copy, Debug, PartialEq, Eq)]
pub enum ParseFormat {
/// The lossless `rowan` concrete syntax tree.
Cst,
/// The JuliaSyntax-native s-expression projection.
Sexpr,
}