private CharSequence listCommands() {
Map<String, MethodTarget> commandsByName = commandRegistry.listCommands();
SortedMap<String, Map<String, MethodTarget>> commandsByGroupAndName = commandsByName.entrySet().stream()
.collect(groupingBy(e -> e.getValue().getGroup(), TreeMap::new,
toMap(Entry::getKey, Entry::getValue)));
AttributedStringBuilder result = new AttributedStringBuilder();
result.append("AVAILABLE COMMANDS\n\n", AttributedStyle.BOLD);
commandsByGroupAndName.forEach((group, commandsInGroup) -> {
result.append("".equals(group) ? "Default" : group, AttributedStyle.BOLD).append('\n');
Map<MethodTarget, SortedSet<String>> commandNamesByMethod = commandsInGroup.entrySet().stream()
.collect(groupingBy(Entry::getValue,
mapping(Entry::getKey, toCollection(TreeSet::new))));
commandNamesByMethod.entrySet().stream().sorted(sortByFirstCommandName()).forEach(e -> {
result
.append(isAvailable(e.getKey()) ? " " : " * ")
.append(String.join(", ", e.getValue()), AttributedStyle.BOLD)
.append(": ")
.append(e.getKey().getHelp())
.append('\n');
});
result.append('\n');
});
if (commandsByName.values().stream().distinct().anyMatch(m -> !isAvailable(m))) {
result.append("Commands marked with (*) are currently unavailable.\nType `help <command>` to learn more.\n\n");
}
return result;
}