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
|
mod sd {
include!("../../src/cli.rs");
}
use sd::Options;
use std::{fs, path::Path};
use clap::{CommandFactory, ValueEnum};
use clap_complete::{generate_to, Shell};
use roff::{bold, roman, Roff};
pub fn gen() {
let gen_dir = Path::new("gen");
gen_shell(gen_dir);
gen_man(gen_dir);
}
fn gen_shell(base_dir: &Path) {
let completions_dir = base_dir.join("completions");
fs::create_dir_all(&completions_dir).unwrap();
let mut cmd = Options::command();
for &shell in Shell::value_variants() {
generate_to(shell, &mut cmd, "sd", &completions_dir).unwrap();
}
}
fn gen_man(base_dir: &Path) {
let man_path = base_dir.join("sd.1");
let cmd = Options::command();
let mut buffer: Vec<u8> = Vec::new();
let man = clap_mangen::Man::new(cmd);
man.render_title(&mut buffer)
.expect("failed to render title section");
man.render_name_section(&mut buffer)
.expect("failed to render name section");
man.render_synopsis_section(&mut buffer)
.expect("failed to render synopsis section");
man.render_description_section(&mut buffer)
.expect("failed to render description section");
man.render_options_section(&mut buffer)
.expect("failed to render options section");
let statuses = [
("0", "Successful program execution."),
("1", "Unsuccessful program execution."),
("101", "The program panicked."),
];
let mut sect = Roff::new();
sect.control("SH", ["EXIT STATUS"]);
for (code, reason) in statuses {
sect.control("IP", [code]).text([roman(reason)]);
}
sect.to_writer(&mut buffer)
.expect("failed to render exit status section");
let examples = [
// (description, command, result), result can be empty
(
"String-literal mode",
"echo 'lots((([]))) of special chars' | sd -F '((([])))'",
"lots of special chars",
),
(
"Regex use. Let's trim some trailing whitespace",
"echo 'lorem ipsum 23 ' | sd '\\s+$' ''",
"lorem ipsum 23",
),
(
"Indexed capture groups",
r"echo 'cargo +nightly watch' | sd '(\w+)\s+\+(\w+)\s+(\w+)' 'cmd: $1, channel: $2, subcmd: $3'",
"123 dollars and 45 cents",
),
(
"Find & replace in file",
r#"sd 'window.fetch' 'fetch' http.js"#,
"",
),
(
"Find & replace from STDIN an emit to STDOUT",
r#"sd 'window.fetch' 'fetch' < http.js"#,
"",
),
];
let mut sect = Roff::new();
sect.control("SH", ["EXAMPLES"]);
for (desc, command, result) in examples {
sect.control("TP", [])
.text([roman(desc)])
.text([bold(format!("$ {}", command))])
.control("br", [])
.text([roman(result)]);
}
sect.to_writer(&mut buffer)
.expect("failed to render example section");
std::fs::write(man_path, buffer).expect("failed to write manpage");
}
|