Merge: src/doc/commands: clean commands hierarchy
[nit.git] / src / doc / term / term.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 module term
16
17 import commands::commands_parser
18 import templates::term_model
19 import templates::md_commands
20
21 redef class CommandParser
22
23 fun execute(query: String, no_color: nullable Bool) do
24 var cmd = self.parse(query)
25 var error = self.error
26
27 # Translate links to doc commands
28 if cmd isa CmdEntityLink then
29 cmd = new CmdComment(model, mentity_name = query)
30 var opts = new CmdOptions
31 var status = cmd.parser_init(query, opts)
32 if not status isa CmdSuccess then error = status
33 end
34
35 if error isa CmdError or error isa CmdWarning then
36 error.print_message(no_color)
37 print ""
38 end
39 if cmd == null then return
40 cmd.execute(no_color)
41 end
42 end
43
44 redef class DocCommand
45 fun execute(no_color: nullable Bool) is abstract
46 end
47
48 redef class CmdMessage
49 fun print_message(no_color: nullable Bool) do print to_s
50 end
51
52 redef class CmdError
53 redef fun print_message(no_color) do
54 var res = "Error: {to_s}"
55 if no_color == null or not no_color then res = res.bold.red
56 print res
57 end
58 end
59
60 redef class CmdWarning
61 redef fun print_message(no_color) do
62 var res = "Warning: {to_s}"
63 if no_color == null or not no_color then res = res.bold.yellow
64 print res
65 end
66 end
67
68 # Model queries
69
70 redef class ErrorMEntityNotFound
71 redef fun print_message(no_color) do
72 if no_color == null or not no_color then
73 print "No result found for `{mentity_name.blue}`...".bold
74 else
75 print "No result found for `{mentity_name}`..."
76 end
77 print ""
78 if suggestions.not_empty then
79 print "Did you mean?"
80 print ""
81 for s in suggestions do
82 print s.cs_list_item(no_color)
83 print ""
84 end
85 end
86 end
87 end
88
89 redef class ErrorMEntityConflict
90 redef fun print_message(no_color) do
91 if no_color == null or not no_color then
92 print "Multiple results found for `{mentity_name.blue}`...".bold
93 else
94 print "Multiple results found for `{mentity_name}`..."
95 end
96 print ""
97 if conflicts.not_empty then
98 print "Did you mean?"
99 print ""
100 for s in conflicts do
101 print s.cs_list_item(no_color)
102 print ""
103 end
104 end
105 end
106 end
107
108 redef class CmdList
109 fun print_list(list_title: nullable String, list_items: nullable Array[MEntity], no_color: nullable Bool) do
110 if list_title != null then
111 if no_color == null or not no_color then
112 print list_title.bold
113 else
114 print list_title
115 end
116 print ""
117 end
118 if list_items != null and list_items.not_empty then
119 for mentity in list_items do
120 print mentity.cs_list_item(no_color)
121 print ""
122 end
123 else
124 print "None."
125 end
126 end
127 end
128
129 redef class CmdComment
130 redef fun execute(no_color) do
131 var mentity = self.mentity
132 if mentity == null then return
133
134 var full_name = mentity.cs_full_name(no_color)
135 if no_color == null or not no_color then
136 print "Documentation for `{full_name}`:".bold
137 else
138 print "Documentation for `{full_name}`:"
139 end
140 print ""
141 print " {mentity.cs_icon(no_color)} {mentity.cs_full_name(no_color)}"
142 print " {mentity.cs_declaration(no_color)}"
143 print " {mentity.cs_location(no_color)}"
144 print ""
145 var mdoc = self.mdoc
146 if mdoc == null then return
147 if full_doc then
148 print mdoc.cs_comment(no_color, 3)
149 else
150 print " {mdoc.cs_short_comment(no_color)}\n"
151 end
152 end
153 end
154
155 redef class CmdAncestors
156 redef fun execute(no_color) do
157 var full_name = mentity.as(not null).cs_full_name(no_color)
158 print_list("Ancestors for `{full_name}`:", results, no_color)
159 end
160 end
161
162 redef class CmdParents
163 redef fun execute(no_color) do
164 var full_name = mentity.as(not null).cs_full_name(no_color)
165 print_list("Parents for `{full_name}`:", results, no_color)
166 end
167 end
168
169 redef class CmdChildren
170 redef fun execute(no_color) do
171 var full_name = mentity.as(not null).cs_full_name(no_color)
172 print_list("Children for `{full_name}`:", results, no_color)
173 end
174 end
175
176 redef class CmdDescendants
177 redef fun execute(no_color) do
178 var full_name = mentity.as(not null).cs_full_name(no_color)
179 print_list("Descendants for `{full_name}`:", results, no_color)
180 end
181 end
182
183 redef class CmdLinearization
184 redef fun execute(no_color) do
185 var full_name = mentity.as(not null).cs_full_name(no_color)
186 print_list("Linearization for `{full_name}`:", results, no_color)
187 end
188 end
189
190 redef class CmdSearch
191 redef fun execute(no_color) do
192 print_list("Search results for `{query.as(not null)}`:", results, no_color)
193 end
194 end
195
196 redef class CmdModelEntities
197 redef fun execute(no_color) do
198 var kind = self.kind
199 if no_color != null and not no_color then kind = kind.blue
200 print_list("MEntities for kind `{kind}`:", results, no_color)
201 end
202 end
203
204 redef class CmdFeatures
205 redef fun execute(no_color) do
206 var full_name = mentity.as(not null).cs_full_name(no_color)
207 print_list("Features for `{full_name}`:", results, no_color)
208 end
209 end
210
211 redef class CmdEntityCode
212
213 redef var format = "ansi" is optional
214
215 redef fun execute(no_color) do
216 var mentity = self.mentity
217 if mentity == null then return
218
219 var title = "Code for `{mentity.cs_full_name(no_color)}`:"
220 if no_color == null or not no_color then
221 print title.bold
222 else
223 print title
224 end
225 var node = self.node
226 if (no_color == null or not no_color) and node != null then
227 var ansi = render_code(node)
228 print "~~~"
229 print ansi.write_to_string
230 print "~~~"
231 else
232 printn mentity.cs_source_code
233 end
234 end
235 end
236
237 redef class CmdGraph
238 redef fun execute(no_color) do
239 format = "dot"
240 var dot = self.render
241 if dot == null then return
242 var f = new ProcessWriter("dot", "-Txlib")
243 f.write dot.write_to_string
244 f.close
245 f.wait
246 end
247 end
248
249 # CmdUsage
250
251 redef class CmdCall
252 redef fun execute(no_color) do
253 var full_name = mentity.as(not null).cs_full_name(no_color)
254 print_list("Methods calling `{full_name}`:", results, no_color)
255 end
256 end
257
258 redef class CmdNew
259 redef fun execute(no_color) do
260 var full_name = mentity.as(not null).cs_full_name(no_color)
261 print_list("Methods intializing `{full_name}`:", results, no_color)
262 end
263 end
264
265 redef class CmdReturn
266 redef fun execute(no_color) do
267 var full_name = mentity.as(not null).cs_full_name(no_color)
268 print_list("Methods returning `{full_name}`:", results, no_color)
269 end
270 end
271
272 redef class CmdParam
273 redef fun execute(no_color) do
274 var full_name = mentity.as(not null).cs_full_name(no_color)
275 print_list("Methods accepting `{full_name}` as parameter:", results, no_color)
276 end
277 end
278
279 # CmdCatalog
280
281 redef class CmdCatalogPackages
282 redef fun execute(no_color) do
283 print_list("Packages from catalog:", results, no_color)
284 end
285 end
286
287 redef class CmdCatalogStats
288 redef fun execute(no_color) do
289 if no_color == null or not no_color then
290 print "Catalog statistics:".bold
291 else
292 print "Catalog statistics:"
293 end
294
295 var stats = self.stats.as(not null)
296 print " * {stats.packages} packages"
297 print " * {stats.modules} modules"
298 print " * {stats.methods} methods"
299 print " * {stats.classes} classes"
300 print " * {stats.loc} lines of code"
301 print " * {stats.contributors} contributors"
302 print " * {stats.maintainers} maintainers"
303 print " * {stats.tags} tags"
304 end
305 end
306
307 redef class CmdCatalogTags
308 redef fun execute(no_color) do
309 if no_color == null or not no_color then
310 print "Tags from catalog:".bold
311 else
312 print "Tags from catalog:"
313 end
314
315 print ""
316 var counts = self.packages_count_by_tags.as(not null)
317 for tag, count in counts do
318 if no_color == null or not no_color then
319 print " * {tag.blue.bold}: {count} packages"
320 else
321 print " * {tag}: {count} packages"
322 end
323 end
324 end
325 end
326
327 redef class CmdCatalogTag
328 redef fun execute(no_color) do
329 var tag = self.tag.as(not null)
330 if no_color == null or not no_color then tag = tag.blue.bold
331 print_list("Packages tagged with `{tag}`:", results, no_color)
332 end
333 end
334
335 redef class CmdCatalogMaintaining
336 redef fun execute(no_color) do
337 var name = self.person_name.as(not null)
338 if no_color == null or not no_color then name = name.blue.bold
339 print_list("Packages maintained by `{name}`:", results, no_color)
340 end
341 end
342
343 redef class CmdCatalogContributing
344 redef fun execute(no_color) do
345 var name = self.person_name.as(not null)
346 if no_color == null or not no_color then name = name.blue.bold
347 print_list("Packages contributed by `{name}`:", results, no_color)
348 end
349 end
350
351 # CmdIni
352
353 redef class CmdIni
354 # Print ini data
355 fun print_ini(title: String, data: nullable String, no_color: nullable Bool) do
356 if data == null then return
357 if no_color == null or not no_color then
358 print title.bold
359 else
360 print title
361 end
362 print ""
363 print data
364 end
365 end
366
367 redef class CmdIniDescription
368 redef fun execute(no_color) do
369 var title = "Description from ini file:"
370 print_ini(title, desc, no_color)
371 end
372 end
373
374 redef class CmdIniGitUrl
375 redef fun execute(no_color) do
376 var title = "Git URL from ini file:"
377 print_ini(title, url, no_color)
378 end
379 end
380
381 redef class CmdIniCloneCommand
382 redef fun execute(no_color) do
383 var title = "Git clone command from ini file:"
384 print_ini(title, command, no_color)
385 end
386 end
387
388 redef class CmdIniIssuesUrl
389 redef fun execute(no_color) do
390 var title = "Issues URL from ini file:"
391 print_ini(title, url, no_color)
392 end
393 end
394
395 redef class CmdIniMaintainer
396 redef fun execute(no_color) do
397 var title = "Maintainer from ini file:"
398 print_ini(title, maintainer, no_color)
399 end
400 end
401
402 redef class CmdIniContributors
403 redef fun execute(no_color) do
404 var contributors = self.contributors
405 if contributors == null then return
406 var title = "Contributors list from ini file:"
407 if no_color == null or not no_color then
408 print title.bold
409 else
410 print title
411 end
412 print ""
413 for contributor in contributors do
414 print " * {contributor}"
415 end
416 end
417 end
418
419 redef class CmdIniLicense
420 redef fun execute(no_color) do
421 var title = "License from ini file:"
422 print_ini(title, license, no_color)
423 end
424 end
425
426 redef class CmdEntityFile
427
428 # Print file
429 fun print_file(title: String, no_color: nullable Bool) do
430 var file = self.file
431 if file == null then return
432 title = "{title} `{file}`:"
433 if no_color == null or not no_color then
434 print title.bold
435 else
436 print title
437 end
438 print ""
439 print file.to_path.read_all
440 print ""
441 end
442 end
443
444 redef class CmdLicenseFile
445 redef fun execute(no_color) do
446 print_file("License from", no_color)
447 end
448 end
449
450 redef class CmdContribFile
451 redef fun execute(no_color) do
452 print_file("Contributing rules from", no_color)
453 end
454 end
455
456 # CmdMain
457
458 redef class CmdMains
459 redef fun execute(no_color) do
460 var mentity = self.mentity.as(not null).full_name
461 if no_color == null or not no_color then mentity = mentity.blue.bold
462 print_list("Mains in `{mentity}`:", results, no_color)
463 end
464 end
465
466 redef class CmdMainCompile
467 redef fun execute(no_color) do
468 var mentity = self.mentity.as(not null).full_name
469 if no_color == null or not no_color then mentity = mentity.blue.bold
470 var title = "Compiling `{mentity}`:"
471
472 if no_color == null or not no_color then
473 print title.bold
474 else
475 print title
476 end
477
478 print ""
479 var command = self.command
480 if command != null then print command
481 end
482 end
483
484 redef class CmdTesting
485 redef fun execute(no_color) do
486 var mentity = self.mentity.as(not null).full_name
487 if no_color == null or not no_color then mentity = mentity.blue.bold
488 var title = "Testing `{mentity}`:"
489
490 if no_color == null or not no_color then
491 print title.bold
492 else
493 print title
494 end
495
496 print ""
497 var command = self.command
498 if command != null then print command
499 end
500 end
501
502 redef class CmdManSynopsis
503 redef fun execute(no_color) do
504 var mentity = self.mentity.as(not null).full_name
505 if no_color == null or not no_color then mentity = mentity.blue.bold
506 var title = "Synopsis for `{mentity}`:"
507
508 if no_color == null or not no_color then
509 print title.bold
510 else
511 print title
512 end
513
514 print ""
515 var synopsis = self.synopsis
516 if synopsis != null then print synopsis
517 end
518 end
519
520 redef class CmdManOptions
521 redef fun execute(no_color) do
522 var mentity = self.mentity.as(not null).full_name
523 if no_color == null or not no_color then mentity = mentity.blue.bold
524 var title = "Options for `{mentity}`:"
525
526 if no_color == null or not no_color then
527 print title.bold
528 else
529 print title
530 end
531
532 print ""
533 var options = self.options.as(not null)
534 for opt, desc in options do
535 if no_color == null or not no_color then
536 print " * {opt.blue.bold}: {desc}"
537 else
538 print " * {opt}: {desc}"
539 end
540 end
541 end
542 end