A simple Completer for MinestomTerminal & Fix LineReader visual issue (#1091)

This commit is contained in:
Huynh Tien 2022-05-24 02:59:34 +07:00 committed by GitHub
parent 8ce43ca40c
commit 025cdab7e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 93 additions and 9 deletions

View File

@ -2,6 +2,7 @@ package net.minestom.server.listener;
import net.minestom.server.MinecraftServer;
import net.minestom.server.command.CommandManager;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.CommandSyntax;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.parser.ArgumentQueryResult;
@ -13,6 +14,7 @@ import net.minestom.server.entity.Player;
import net.minestom.server.network.packet.client.play.ClientTabCompletePacket;
import net.minestom.server.network.packet.server.play.TabCompletePacket;
import net.minestom.server.utils.StringUtils;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.regex.Pattern;
@ -21,7 +23,20 @@ public class TabCompleteListener {
public static void listener(ClientTabCompletePacket packet, Player player) {
final String text = packet.text();
final Suggestion suggestion = getSuggestion(player, text);
if (suggestion != null) {
player.sendPacket(new TabCompletePacket(
packet.transactionId(),
suggestion.getStart(),
suggestion.getLength(),
suggestion.getEntries().stream()
.map(suggestionEntry -> new TabCompletePacket.Match(suggestionEntry.getEntry(), suggestionEntry.getTooltip()))
.toList())
);
}
}
public static @Nullable Suggestion getSuggestion(CommandSender commandSender, String text) {
String commandString = text.replaceFirst(CommandManager.COMMAND_PREFIX, "");
String[] split = commandString.split(StringUtils.SPACE);
String commandName = split[0];
@ -30,7 +45,7 @@ public class TabCompleteListener {
final CommandQueryResult commandQueryResult = CommandParser.findCommand(MinecraftServer.getCommandManager().getDispatcher(), commandString);
if (commandQueryResult == null) {
// Command not found
return;
return null;
}
final ArgumentQueryResult queryResult = CommandParser.findEligibleArgument(commandQueryResult.command(),
@ -38,7 +53,7 @@ public class TabCompleteListener {
CommandSyntax::hasSuggestion, Argument::hasSuggestion);
if (queryResult == null) {
// Suggestible argument not found
return;
return null;
}
final Argument<?> argument = queryResult.argument();
@ -55,11 +70,10 @@ public class TabCompleteListener {
final int start = commandLength - inputLength + 1 - trailingSpaces;
Suggestion suggestion = new Suggestion(input, start, inputLength);
suggestionCallback.apply(player, queryResult.context(), suggestion);
suggestionCallback.apply(commandSender, queryResult.context(), suggestion);
player.sendPacket(new TabCompletePacket(packet.transactionId(), suggestion.getStart(), suggestion.getLength(),
suggestion.getEntries().stream()
.map(suggestionEntry -> new TabCompletePacket.Match(suggestionEntry.getEntry(), suggestionEntry.getTooltip())).toList()));
return suggestion;
}
return null;
}
}

View File

@ -0,0 +1,33 @@
package net.minestom.server.terminal;
import org.tinylog.core.LogEntry;
import org.tinylog.writers.AbstractFormatPatternWriter;
import java.util.Map;
import static net.minestom.server.terminal.MinestomTerminal.reader;
public final class MinestomConsoleWriter extends AbstractFormatPatternWriter {
public MinestomConsoleWriter(Map<String, String> properties) {
super(properties);
}
@Override
public void write(LogEntry logEntry) throws Exception {
if (reader != null) {
reader.printAbove(render(logEntry));
} else {
System.out.print(render(logEntry));
}
}
@Override
public void flush() {
// EMPTY
}
@Override
public void close() throws Exception {
// EMPTY
}
}

View File

@ -1,20 +1,28 @@
package net.minestom.server.terminal;
import net.minestom.server.MinecraftServer;
import net.minestom.server.command.builder.Command;
import net.minestom.server.command.builder.suggestion.Suggestion;
import net.minestom.server.command.builder.suggestion.SuggestionEntry;
import net.minestom.server.listener.TabCompleteListener;
import org.jetbrains.annotations.ApiStatus;
import org.jline.reader.Candidate;
import org.jline.reader.Completer;
import org.jline.reader.EndOfFileException;
import org.jline.reader.LineReader;
import org.jline.reader.LineReaderBuilder;
import org.jline.reader.ParsedLine;
import org.jline.reader.UserInterruptException;
import org.jline.terminal.Terminal;
import org.jline.terminal.TerminalBuilder;
import java.io.IOException;
import java.util.List;
public class MinestomTerminal {
private static final String PROMPT = "> ";
private static volatile Terminal terminal;
static volatile LineReader reader;
private static volatile boolean running = false;
@ApiStatus.Internal
@ -25,7 +33,8 @@ public class MinestomTerminal {
} catch (IOException e) {
e.printStackTrace();
}
LineReader reader = LineReaderBuilder.builder()
reader = LineReaderBuilder.builder()
.completer(new MinestomCompleter())
.terminal(terminal)
.build();
running = true;
@ -58,7 +67,34 @@ public class MinestomTerminal {
} catch (IOException e) {
e.printStackTrace();
}
reader = null;
}
}
private static final class MinestomCompleter implements Completer {
@Override
public void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) {
final var commandManager = MinecraftServer.getCommandManager();
final var consoleSender = commandManager.getConsoleSender();
if (line.wordIndex() == 0) {
final String commandString = line.word().toLowerCase();
candidates.addAll(
commandManager.getDispatcher().getCommands().stream()
.map(Command::getName)
.filter(name -> commandString.isBlank() || name.toLowerCase().startsWith(commandString))
.map(Candidate::new)
.toList()
);
} else {
final String text = line.line();
final Suggestion suggestion = TabCompleteListener.getSuggestion(consoleSender, text);
if (suggestion != null) {
suggestion.getEntries().stream()
.map(SuggestionEntry::getEntry)
.map(Candidate::new)
.forEach(candidates::add);
}
}
}
}
}

View File

@ -0,0 +1 @@
net.minestom.server.terminal.MinestomConsoleWriter

View File

@ -1,4 +1,4 @@
autoshutdown=true
writer=console
writer=minestom console
writer.level=info
writer.format=[{thread}] [{date: HH:mm:ss}] ({class-name}.{method}) - {level} - {message}