diff options
Diffstat (limited to 'crates/ra_lsp_server/src/args.rs')
-rw-r--r-- | crates/ra_lsp_server/src/args.rs | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/crates/ra_lsp_server/src/args.rs b/crates/ra_lsp_server/src/args.rs new file mode 100644 index 000000000..41959797c --- /dev/null +++ b/crates/ra_lsp_server/src/args.rs | |||
@@ -0,0 +1,237 @@ | |||
1 | use anyhow::{bail, Result}; | ||
2 | use pico_args::Arguments; | ||
3 | use ra_lsp_server::cli::{BenchWhat, Position, Verbosity}; | ||
4 | |||
5 | use std::{fmt::Write, path::PathBuf}; | ||
6 | |||
7 | pub(crate) struct Args { | ||
8 | pub(crate) verbosity: Verbosity, | ||
9 | pub(crate) command: Command, | ||
10 | } | ||
11 | |||
12 | pub(crate) enum Command { | ||
13 | Parse { | ||
14 | no_dump: bool, | ||
15 | }, | ||
16 | Symbols, | ||
17 | Highlight { | ||
18 | rainbow: bool, | ||
19 | }, | ||
20 | Stats { | ||
21 | randomize: bool, | ||
22 | memory_usage: bool, | ||
23 | only: Option<String>, | ||
24 | with_deps: bool, | ||
25 | path: PathBuf, | ||
26 | }, | ||
27 | Bench { | ||
28 | path: PathBuf, | ||
29 | what: BenchWhat, | ||
30 | }, | ||
31 | RunServer, | ||
32 | Version, | ||
33 | } | ||
34 | |||
35 | impl Args { | ||
36 | pub(crate) fn parse() -> Result<Result<Args, HelpPrinted>> { | ||
37 | let mut matches = Arguments::from_env(); | ||
38 | |||
39 | if matches.contains("--version") { | ||
40 | matches.finish().or_else(handle_extra_flags)?; | ||
41 | return Ok(Ok(Args { verbosity: Verbosity::Normal, command: Command::Version })); | ||
42 | } | ||
43 | |||
44 | let verbosity = match ( | ||
45 | matches.contains(["-vv", "--spammy"]), | ||
46 | matches.contains(["-v", "--verbose"]), | ||
47 | matches.contains(["-q", "--quiet"]), | ||
48 | ) { | ||
49 | (true, _, true) => bail!("Invalid flags: -q conflicts with -vv"), | ||
50 | (true, _, false) => Verbosity::Spammy, | ||
51 | (false, false, false) => Verbosity::Normal, | ||
52 | (false, false, true) => Verbosity::Quiet, | ||
53 | (false, true, false) => Verbosity::Verbose, | ||
54 | (false, true, true) => bail!("Invalid flags: -q conflicts with -v"), | ||
55 | }; | ||
56 | |||
57 | let subcommand = match matches.subcommand()? { | ||
58 | Some(it) => it, | ||
59 | None => { | ||
60 | matches.finish().or_else(handle_extra_flags)?; | ||
61 | return Ok(Ok(Args { verbosity, command: Command::RunServer })); | ||
62 | } | ||
63 | }; | ||
64 | let command = match subcommand.as_str() { | ||
65 | "parse" => { | ||
66 | if matches.contains(["-h", "--help"]) { | ||
67 | eprintln!( | ||
68 | "\ | ||
69 | ra-cli-parse | ||
70 | |||
71 | USAGE: | ||
72 | ra_cli parse [FLAGS] | ||
73 | |||
74 | FLAGS: | ||
75 | -h, --help Prints help inforamtion | ||
76 | --no-dump" | ||
77 | ); | ||
78 | return Ok(Err(HelpPrinted)); | ||
79 | } | ||
80 | |||
81 | let no_dump = matches.contains("--no-dump"); | ||
82 | matches.finish().or_else(handle_extra_flags)?; | ||
83 | Command::Parse { no_dump } | ||
84 | } | ||
85 | "symbols" => { | ||
86 | if matches.contains(["-h", "--help"]) { | ||
87 | eprintln!( | ||
88 | "\ | ||
89 | ra-cli-symbols | ||
90 | |||
91 | USAGE: | ||
92 | ra_cli highlight [FLAGS] | ||
93 | |||
94 | FLAGS: | ||
95 | -h, --help Prints help inforamtion" | ||
96 | ); | ||
97 | return Ok(Err(HelpPrinted)); | ||
98 | } | ||
99 | |||
100 | matches.finish().or_else(handle_extra_flags)?; | ||
101 | |||
102 | Command::Symbols | ||
103 | } | ||
104 | "highlight" => { | ||
105 | if matches.contains(["-h", "--help"]) { | ||
106 | eprintln!( | ||
107 | "\ | ||
108 | ra-cli-highlight | ||
109 | |||
110 | USAGE: | ||
111 | ra_cli highlight [FLAGS] | ||
112 | |||
113 | FLAGS: | ||
114 | -h, --help Prints help information | ||
115 | -r, --rainbow" | ||
116 | ); | ||
117 | return Ok(Err(HelpPrinted)); | ||
118 | } | ||
119 | |||
120 | let rainbow = matches.contains(["-r", "--rainbow"]); | ||
121 | matches.finish().or_else(handle_extra_flags)?; | ||
122 | Command::Highlight { rainbow } | ||
123 | } | ||
124 | "analysis-stats" => { | ||
125 | if matches.contains(["-h", "--help"]) { | ||
126 | eprintln!( | ||
127 | "\ | ||
128 | ra-cli-analysis-stats | ||
129 | |||
130 | USAGE: | ||
131 | ra_cli analysis-stats [FLAGS] [OPTIONS] [PATH] | ||
132 | |||
133 | FLAGS: | ||
134 | -h, --help Prints help information | ||
135 | --memory-usage | ||
136 | -v, --verbose | ||
137 | -q, --quiet | ||
138 | |||
139 | OPTIONS: | ||
140 | -o <ONLY> | ||
141 | |||
142 | ARGS: | ||
143 | <PATH>" | ||
144 | ); | ||
145 | return Ok(Err(HelpPrinted)); | ||
146 | } | ||
147 | |||
148 | let randomize = matches.contains("--randomize"); | ||
149 | let memory_usage = matches.contains("--memory-usage"); | ||
150 | let only: Option<String> = matches.opt_value_from_str(["-o", "--only"])?; | ||
151 | let with_deps: bool = matches.contains("--with-deps"); | ||
152 | let path = { | ||
153 | let mut trailing = matches.free()?; | ||
154 | if trailing.len() != 1 { | ||
155 | bail!("Invalid flags"); | ||
156 | } | ||
157 | trailing.pop().unwrap().into() | ||
158 | }; | ||
159 | |||
160 | Command::Stats { randomize, memory_usage, only, with_deps, path } | ||
161 | } | ||
162 | "analysis-bench" => { | ||
163 | if matches.contains(["-h", "--help"]) { | ||
164 | eprintln!( | ||
165 | "\ | ||
166 | ra_cli-analysis-bench | ||
167 | |||
168 | USAGE: | ||
169 | ra_cli analysis-bench [FLAGS] [OPTIONS] [PATH] | ||
170 | |||
171 | FLAGS: | ||
172 | -h, --help Prints help information | ||
173 | -v, --verbose | ||
174 | |||
175 | OPTIONS: | ||
176 | --complete <PATH:LINE:COLUMN> Compute completions at this location | ||
177 | --highlight <PATH> Hightlight this file | ||
178 | |||
179 | ARGS: | ||
180 | <PATH> Project to analyse" | ||
181 | ); | ||
182 | return Ok(Err(HelpPrinted)); | ||
183 | } | ||
184 | |||
185 | let path: PathBuf = matches.opt_value_from_str("--path")?.unwrap_or_default(); | ||
186 | let highlight_path: Option<String> = matches.opt_value_from_str("--highlight")?; | ||
187 | let complete_path: Option<Position> = matches.opt_value_from_str("--complete")?; | ||
188 | let goto_def_path: Option<Position> = matches.opt_value_from_str("--goto-def")?; | ||
189 | let what = match (highlight_path, complete_path, goto_def_path) { | ||
190 | (Some(path), None, None) => BenchWhat::Highlight { path: path.into() }, | ||
191 | (None, Some(position), None) => BenchWhat::Complete(position), | ||
192 | (None, None, Some(position)) => BenchWhat::GotoDef(position), | ||
193 | _ => panic!( | ||
194 | "exactly one of `--highlight`, `--complete` or `--goto-def` must be set" | ||
195 | ), | ||
196 | }; | ||
197 | Command::Bench { path, what } | ||
198 | } | ||
199 | _ => { | ||
200 | eprintln!( | ||
201 | "\ | ||
202 | ra-cli | ||
203 | |||
204 | USAGE: | ||
205 | ra_cli <SUBCOMMAND> | ||
206 | |||
207 | FLAGS: | ||
208 | -h, --help Prints help information | ||
209 | |||
210 | SUBCOMMANDS: | ||
211 | analysis-bench | ||
212 | analysis-stats | ||
213 | highlight | ||
214 | parse | ||
215 | symbols" | ||
216 | ); | ||
217 | return Ok(Err(HelpPrinted)); | ||
218 | } | ||
219 | }; | ||
220 | Ok(Ok(Args { verbosity, command })) | ||
221 | } | ||
222 | } | ||
223 | |||
224 | pub(crate) struct HelpPrinted; | ||
225 | |||
226 | fn handle_extra_flags(e: pico_args::Error) -> Result<()> { | ||
227 | if let pico_args::Error::UnusedArgsLeft(flags) = e { | ||
228 | let mut invalid_flags = String::new(); | ||
229 | for flag in flags { | ||
230 | write!(&mut invalid_flags, "{}, ", flag)?; | ||
231 | } | ||
232 | let (invalid_flags, _) = invalid_flags.split_at(invalid_flags.len() - 2); | ||
233 | bail!("Invalid flags: {}", invalid_flags); | ||
234 | } else { | ||
235 | bail!(e); | ||
236 | } | ||
237 | } | ||