@@ -49,6 +49,12 @@ define abstract class <parse-node> (<object>)
49
49
init-keyword: repeat-marker:;
50
50
end class ;
51
51
52
+ define open generic node-help-symbol (node :: <parse-node>)
53
+ => (help-symbol :: <string> );
54
+
55
+ define open generic node-help-text (node :: <parse-node>)
56
+ => (help-text :: <string> );
57
+
52
58
/* Generate completions for the given node
53
59
*
54
60
* May or may not be provided a partial token.
@@ -69,6 +75,16 @@ define open generic node-accept ( node :: <parse-node>, parser :: <command-parse
69
75
=> ();
70
76
71
77
78
+ define method node-help-symbol (node :: <parse-node>)
79
+ => (help-symbol :: <string> );
80
+ "<...>" ;
81
+ end method ;
82
+
83
+ define method node-help-text (node :: <parse-node>)
84
+ => (help-symbol :: <string> );
85
+ "No help." ;
86
+ end method ;
87
+
72
88
/* Is the node acceptable as next node in given parser state?
73
89
*
74
90
* This prevents non-repeatable parameters from being added again.
@@ -148,6 +164,16 @@ define method print-object(object :: <symbol-node>, stream :: <stream>) => ();
148
164
format(stream, "%s" , node-symbol(object));
149
165
end method ;
150
166
167
+ define method node-help-symbol (node :: <symbol-node>)
168
+ => (help-symbol :: <string> );
169
+ as (<string> , node-symbol(node));
170
+ end method ;
171
+
172
+ define method node-help-text (node :: <symbol-node>)
173
+ => (help-symbol :: <string> );
174
+ "" ;
175
+ end method ;
176
+
151
177
define method node-match (node :: <symbol-node>, parser :: <command-parser>, token :: <command-token>)
152
178
=> (matched? :: <boolean> );
153
179
starts-with?(as (<string> , node-symbol(node)),
@@ -186,13 +212,25 @@ define method print-object(object :: <command-node>, stream :: <stream>) => ();
186
212
format(stream, "%s - %s" , node-symbol(object), command-help(object));
187
213
end method ;
188
214
215
+ define method node-help-text (node :: <command-node>)
216
+ => (help-text :: <string> );
217
+ command-help(node) | "Command" ;
218
+ end method ;
219
+
189
220
define method node-accept (node :: <command-node>, parser :: <command-parser>, token :: <command-token>)
190
221
=> ();
191
222
if (command-handler(node))
192
223
parser-push-command(parser, node);
193
224
end
194
225
end method ;
195
226
227
+ define method node-complete (node :: <command-node>, parser :: <command-parser>, token :: false-or (<command-token>))
228
+ => (completion :: <command-completion>);
229
+ make-completion(node, token,
230
+ exhaustive?: #t ,
231
+ complete-options: list (as (<string> , node-symbol(node))));
232
+ end method ;
233
+
196
234
define method command-add-parameter (node :: <command-node>, parameter :: <parameter-node>)
197
235
=> ();
198
236
command-parameters(node) := add! (command-parameters(node), parameter);
@@ -224,6 +262,32 @@ define method node-successors (node :: <wrapper-node>)
224
262
concatenate (node-successors(wrapper-root(node)), next-method ());
225
263
end method ;
226
264
265
+
266
+ /* A symbol that comes before a parameter
267
+ */
268
+ define class <parameter-symbol-node> (<symbol-node>)
269
+ constant slot symbol-parameter :: <parameter-node>,
270
+ init-keyword: parameter:;
271
+ end class ;
272
+
273
+ define method node-help-symbol (node :: <parameter-symbol-node>)
274
+ => (help-symbol :: <string> );
275
+ let parameter = symbol-parameter(node);
276
+ concatenate (as (<string> , node-symbol(node)),
277
+ " <" , as (<string> , parameter-name(parameter)),
278
+ if (node-repeatable?(parameter))
279
+ ">..."
280
+ else
281
+ ">"
282
+ end );
283
+ end method ;
284
+
285
+ define method node-help-text (node :: <parameter-symbol-node>)
286
+ => (help-text :: <string> );
287
+ node-help-text(symbol-parameter(node));
288
+ end method ;
289
+
290
+
227
291
/* Syntactical kinds of parameters
228
292
*/
229
293
define constant <parameter-kind> = one-of (# "simple" , # "named" , # "flag" );
@@ -245,6 +309,21 @@ define open abstract class <parameter-node> (<parse-node>)
245
309
init-keyword: value-type:;
246
310
end class ;
247
311
312
+ define method node-help-symbol (node :: <parameter-node>)
313
+ => (help-symbol :: <string> );
314
+ concatenate ("<" , as (<string> , parameter-name(node)),
315
+ if (node-repeatable?(node))
316
+ ">..."
317
+ else
318
+ ">"
319
+ end )
320
+ end method ;
321
+
322
+ define method node-help-text (node :: <parameter-node>)
323
+ => (help-symbol :: <string> );
324
+ parameter-help(node) | "Parameter" ;
325
+ end method ;
326
+
248
327
/* Parameters can be converted to values
249
328
*
250
329
* By default they convert to simple strings.
@@ -299,9 +378,19 @@ end class;
299
378
300
379
/* Flag parameters
301
380
*/
302
- define class <flag-node> (<parameter-node>, <symbol-node>)
381
+ define class <flag-node> (<parameter-node>, <parameter- symbol-node>)
303
382
end class ;
304
383
384
+ define method node-help-symbol (node :: <flag-node>)
385
+ => (help-symbol :: <string> );
386
+ as (<string> , parameter-name(node));
387
+ end method ;
388
+
389
+ define method node-help-text (node :: <flag-node>)
390
+ => (help-symbol :: <string> );
391
+ parameter-help(node) | "Flag" ;
392
+ end method ;
393
+
305
394
define method parameter-convert (parser :: <command-parser>, node :: <flag-node>, token :: <command-token>)
306
395
=> (value :: <boolean> );
307
396
#t ;
@@ -338,6 +427,15 @@ define class <oneof-node> (<parameter-node>)
338
427
required-init-keyword: alternatives:;
339
428
end class ;
340
429
430
+ define method node-help-text (node :: <oneof-node>)
431
+ => (help-symbol :: <string> );
432
+ let alternatives = oneof-alternatives(node);
433
+ unless (oneof-case-sensitive?(node))
434
+ alternatives := map (as-lowercase , alternatives);
435
+ end ;
436
+ parameter-help(node) | concatenate ("One of: " , join(alternatives, ", " ));
437
+ end method ;
438
+
341
439
define method node-match (node :: <oneof-node>, parser :: <command-parser>, token :: <command-token>)
342
440
=> (matched? :: <boolean> );
343
441
let string = token-string(token);
0 commit comments