From 1ec9c98ab715ee1884239da6c0e3b4957235ed46 Mon Sep 17 00:00:00 2001 From: Mystiflow Date: Sun, 14 Feb 2016 15:54:40 +0000 Subject: [PATCH] Allow the console to tab complete commands diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java index 9d7a25ab..8a4b2283 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java @@ -210,6 +210,7 @@ public class BungeeCord extends ProxyServer AnsiConsole.systemInstall(); consoleReader = new ConsoleReader(); consoleReader.setExpandEvents( false ); + consoleReader.addCompleter( new ConsoleCommandCompleter( this ) ); logger = new BungeeLogger( "BungeeCord", System.getProperty("bungee.log-file", "proxy.log"), consoleReader ); System.setErr( new PrintStream( new LoggingOutputStream( logger, Level.SEVERE ), true ) ); diff --git a/proxy/src/main/java/net/md_5/bungee/ConsoleCommandCompleter.java b/proxy/src/main/java/net/md_5/bungee/ConsoleCommandCompleter.java new file mode 100644 index 00000000..455b0787 --- /dev/null +++ b/proxy/src/main/java/net/md_5/bungee/ConsoleCommandCompleter.java @@ -0,0 +1,72 @@ +package net.md_5.bungee; + +import com.google.common.collect.Iterables; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import jline.console.completer.Completer; +import net.md_5.bungee.api.ProxyServer; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.logging.Level; + +public class ConsoleCommandCompleter implements Completer +{ + + private final ExecutorService executor = Executors.newSingleThreadExecutor( + new ThreadFactoryBuilder().setNameFormat( "Console Command Completer Thread - %1$d" ).build() ); + + private final ProxyServer proxy; + + public ConsoleCommandCompleter( ProxyServer proxy ) + { + this.proxy = proxy; + } + + @Override + public int complete( String buffer, int cursor, List candidates ) + { + Future> future = executor.submit( new Callable>() + { + @Override + public Iterable call() throws Exception + { + List results = new ArrayList<>(); + proxy.getPluginManager().dispatchCommand( proxy.getConsole(), buffer, results ); + return results; + } + } ); + + try + { + Iterable offers = future.get(); + if ( offers == null ) + { + return cursor; + } + + Iterables.addAll( candidates, offers ); + + final int lastSpace = buffer.lastIndexOf( ' ' ); + if ( lastSpace == -1 ) + { + return cursor - buffer.length(); + } else + { + return cursor - ( buffer.length() - lastSpace - 1 ); + } + } catch ( ExecutionException ex ) + { + proxy.getLogger().log( Level.WARNING, "Unhandled exception when tab completing", ex ); + } catch ( InterruptedException ex ) + { + Thread.currentThread().interrupt(); + } + + return cursor; + } +} -- 2.12.0