Mercurial > hg > release > thermostat-2.0
changeset 2276:651386629cea
Shell handles user interrupt with exit prompt
Reviewed-by: neugens, jerboaa
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-April/018521.html
author | Andrew Azores <aazores@redhat.com> |
---|---|
date | Mon, 25 Apr 2016 17:13:31 -0400 |
parents | 135bd0d327cb |
children | a15a2233e4c7 |
files | launcher/src/main/java/com/redhat/thermostat/launcher/internal/LocaleResources.java launcher/src/main/java/com/redhat/thermostat/launcher/internal/ShellCommand.java launcher/src/main/resources/com/redhat/thermostat/launcher/internal/strings.properties |
diffstat | 3 files changed, 50 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/LocaleResources.java Thu Apr 21 18:22:45 2016 +0200 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/LocaleResources.java Mon Apr 25 17:13:31 2016 -0400 @@ -74,6 +74,10 @@ PARSE_ISSUES_CALLED_BEFORE_PARSE, PARSER_ERROR, PARSER_WARNING, + + QUIT_PROMPT, + QUIT_CONFIRM, + QUIT_DENY, ; static final String RESOURCE_BUNDLE = "com.redhat.thermostat.launcher.internal.strings";
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/ShellCommand.java Thu Apr 21 18:22:45 2016 +0200 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/ShellCommand.java Mon Apr 25 17:13:31 2016 -0400 @@ -38,6 +38,7 @@ import java.io.IOException; import java.util.Arrays; +import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; @@ -45,6 +46,7 @@ import jline.Terminal; import jline.TerminalFactory; import jline.console.ConsoleReader; +import jline.console.UserInterruptException; import jline.console.history.FileHistory; import jline.console.history.History; import jline.console.history.PersistentHistory; @@ -72,7 +74,7 @@ private static final Logger logger = LoggingUtils.getLogger(ShellCommand.class); private static final Translate<LocaleResources> t = LocaleResources.createLocalizer(); - private static final String[] exitKeywords = { "exit", "quit", "q" }; + private static final List<String> exitKeywords = Arrays.asList("exit", "quit", "q" ); private HistoryProvider historyProvider; private Version version; @@ -148,7 +150,7 @@ } } - private void closeTerminal(Terminal term) throws CommandException { + private void closeTerminal(Terminal term) { try { term.restore(); } catch (Exception e) { @@ -158,28 +160,39 @@ private void shellMainLoop(CommandContext ctx, History history, Terminal term) throws IOException, CommandException { ConsoleReader reader = new ConsoleReader(ctx.getConsole().getInput(), ctx.getConsole().getOutput(), term); + reader.setHandleUserInterrupt(true); + reader.setPrompt(shellPrompt.getPrompt()); if (reader.getCompleters().isEmpty() && commandInfoSource != null && tabCompletion != null) { tabCompletion.setupTabCompletion(reader, commandInfoSource, bundleContext, prefs); } if (history != null) { reader.setHistory(history); } - while (handleConsoleInput(reader, ctx.getConsole())) { /* no-op; the loop conditional performs the action */ } + try { + while (handleConsoleInput(reader, ctx.getConsole(), shellPrompt.getPrompt())) { /* no-op; the loop conditional performs the action */ } + } finally { + reader.shutdown(); + } } /** * @return true if the shell should continue accepting more input or false if the shell should quit */ - private boolean handleConsoleInput(ConsoleReader reader, Console console) throws IOException, CommandException { + private boolean handleConsoleInput(ConsoleReader reader, Console console, String prompt) throws IOException, CommandException { String line; - line = reader.readLine(shellPrompt.getPrompt()); + try { + line = reader.readLine(prompt); + } catch (UserInterruptException uie) { + return handleUserInterrupt(reader, console); + } if (line == null) { + // ex. Ctrl-D on empty line return false; } line = line.trim(); if (line.equals("")) { return true; - } else if (Arrays.asList(exitKeywords).contains(line)) { + } else if (exitKeywords.contains(line)) { return false; } else { launchCommand(line); @@ -187,6 +200,28 @@ } } + private boolean handleUserInterrupt(ConsoleReader reader, Console console) { + String prompt = reader.getPrompt(); + try { + console.getOutput().println(t.localize(LocaleResources.QUIT_PROMPT).getContents()); + + String confirmChars = t.localize(LocaleResources.QUIT_CONFIRM).getContents(); + String denyChars = t.localize(LocaleResources.QUIT_DENY).getContents(); + char[] expectedChars = (confirmChars + denyChars).toCharArray(); + + char val; + try { + val = (char) reader.readCharacter(expectedChars); + } catch (IOException ioe) { + return false; + } + + return confirmChars.indexOf(val) == -1; + } finally { + reader.setPrompt(prompt); + } + } + private void launchCommand(String line) throws CommandException { ShellArgsParser parser = new ShellArgsParser(line); String[] parsed = parser.parse();
--- a/launcher/src/main/resources/com/redhat/thermostat/launcher/internal/strings.properties Thu Apr 21 18:22:45 2016 +0200 +++ b/launcher/src/main/resources/com/redhat/thermostat/launcher/internal/strings.properties Mon Apr 25 17:13:31 2016 -0400 @@ -39,4 +39,8 @@ PARSE_ISSUES_CALLED_BEFORE_PARSE = ShellArgsParser#getParseIssues called before ShellArgsParser#parse PARSER_ERROR = Could not parse input:\n{0} -PARSER_WARNING = Malformed input, attempting to proceed anyway:\n{0} \ No newline at end of file +PARSER_WARNING = Malformed input, attempting to proceed anyway:\n{0} + +QUIT_PROMPT = Quit? (y/n) +QUIT_CONFIRM = yY +QUIT_DENY = nN \ No newline at end of file