getCommandUsage method
Returns a string representation of commands
fit for use in a usage
string.
isSubcommand
indicates whether the commands should be called "commands"
or "subcommands".
Implementation
String getCommandUsage(final Map<String, Command> commands, {
final bool isSubcommand = false,
final int? lineLength,
})
{
// Don't include aliases.
var names = commands.keys
.where((name) => !commands[name]!.aliases.contains(name));
// Filter out hidden ones, unless they are all hidden.
final visible = names.where((name) => !commands[name]!.hidden);
if (visible.isNotEmpty) names = visible;
// Show the commands alphabetically.
names = names.toList()..sort();
// Group the commands by category.
final commandsByCategory = SplayTreeMap<String, List<Command>>();
for (var name in names) {
var category = commands[name]!.category;
commandsByCategory.putIfAbsent(category, () => []).add(commands[name]!);
}
final categories = commandsByCategory.keys.toList();
final length = names.map((name) => name.length).reduce(max);
final buffer = StringBuffer(
'Available ${isSubcommand ? "sub" : ""}commands:'
);
final columnStart = length + 5;
for (final category in categories) {
if (category.isNotEmpty) {
buffer.writeln();
buffer.writeln();
buffer.write(category);
}
for (final command in commandsByCategory[category]!) {
final lines = wrapTextAsLines(command.summary,
start: columnStart,
length: lineLength,
);
buffer.writeln();
buffer.write(' ${padRight(command.name, length)} ${lines.first}');
for (final line in lines.skip(1)) {
buffer.writeln();
buffer.write(' ' * columnStart);
buffer.write(line);
}
}
}
return buffer.toString();
}