diff --git a/client/trino-cli/src/main/java/io/trino/cli/ClientOptions.java b/client/trino-cli/src/main/java/io/trino/cli/ClientOptions.java index 5e79612f1ab5..dfac2b4dbf65 100644 --- a/client/trino-cli/src/main/java/io/trino/cli/ClientOptions.java +++ b/client/trino-cli/src/main/java/io/trino/cli/ClientOptions.java @@ -23,6 +23,7 @@ import io.trino.client.ClientSession; import io.trino.client.auth.external.ExternalRedirectStrategy; import okhttp3.logging.HttpLoggingInterceptor; +import org.jline.reader.LineReader; import java.net.URI; import java.net.URISyntaxException; @@ -175,6 +176,9 @@ public class ClientOptions @Option(names = "--disable-compression", description = "Disable compression of query results") public boolean disableCompression; + @Option(names = "--editing-mode", paramLabel = "", defaultValue = "EMACS", description = "Editing mode [${COMPLETION-CANDIDATES}] " + DEFAULT_VALUE) + public EditingMode editingMode; + public enum OutputFormat { ALIGNED, @@ -189,6 +193,24 @@ public enum OutputFormat NULL } + public enum EditingMode + { + EMACS(LineReader.EMACS), + VI(LineReader.VIINS); + + private final String keyMap; + + EditingMode(String keyMap) + { + this.keyMap = keyMap; + } + + public String getKeyMap() + { + return keyMap; + } + } + public ClientSession toClientSession() { return new ClientSession( diff --git a/client/trino-cli/src/main/java/io/trino/cli/Console.java b/client/trino-cli/src/main/java/io/trino/cli/Console.java index 0eb43e248dc4..789fde8ddcc5 100644 --- a/client/trino-cli/src/main/java/io/trino/cli/Console.java +++ b/client/trino-cli/src/main/java/io/trino/cli/Console.java @@ -190,7 +190,7 @@ public boolean run() clientOptions.progress); } - runConsole(queryRunner, exiting); + runConsole(queryRunner, exiting, clientOptions.editingMode); return true; } finally { @@ -220,10 +220,10 @@ private String getPassword() return reader.readLine("Password: ", (char) 0); } - private static void runConsole(QueryRunner queryRunner, AtomicBoolean exiting) + private static void runConsole(QueryRunner queryRunner, AtomicBoolean exiting, ClientOptions.EditingMode editingMode) { try (TableNameCompleter tableNameCompleter = new TableNameCompleter(queryRunner); - InputReader reader = new InputReader(getHistoryFile(), commandCompleter(), tableNameCompleter)) { + InputReader reader = new InputReader(editingMode, getHistoryFile(), commandCompleter(), tableNameCompleter)) { tableNameCompleter.populateCache(); String remaining = ""; while (!exiting.get()) { diff --git a/client/trino-cli/src/main/java/io/trino/cli/InputReader.java b/client/trino-cli/src/main/java/io/trino/cli/InputReader.java index 34e43b3ba790..f937f065f412 100644 --- a/client/trino-cli/src/main/java/io/trino/cli/InputReader.java +++ b/client/trino-cli/src/main/java/io/trino/cli/InputReader.java @@ -29,6 +29,7 @@ import static io.trino.cli.TerminalUtils.isRealTerminal; import static org.jline.reader.LineReader.BLINK_MATCHING_PAREN; import static org.jline.reader.LineReader.HISTORY_FILE; +import static org.jline.reader.LineReader.MAIN; import static org.jline.reader.LineReader.Option.HISTORY_TIMESTAMPED; import static org.jline.reader.LineReader.SECONDARY_PROMPT_PATTERN; import static org.jline.utils.AttributedStyle.BRIGHT; @@ -39,7 +40,7 @@ public class InputReader { private final LineReader reader; - public InputReader(Path historyFile, Completer... completers) + public InputReader(ClientOptions.EditingMode editingMode, Path historyFile, Completer... completers) throws IOException { reader = LineReaderBuilder.builder() @@ -52,6 +53,7 @@ public InputReader(Path historyFile, Completer... completers) .completer(new AggregateCompleter(completers)) .build(); + reader.getKeyMaps().put(MAIN, reader.getKeyMaps().get(editingMode.getKeyMap())); reader.unsetOpt(HISTORY_TIMESTAMPED); }