getCommandUsage method

String getCommandUsage(
  1. Map<String, Command> commands, {
  2. bool isSubcommand = false,
  3. int? lineLength,
})

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();
}