1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.nashorn.tools.jjs; 27 28 import java.io.File; 29 import java.io.IOException; 30 import java.io.InputStream; 31 import java.io.PrintStream; 32 import java.util.ArrayList; 33 import java.util.Arrays; 34 import java.util.Collections; 35 import java.util.Iterator; 36 import java.util.List; 37 import jdk.internal.jline.NoInterruptUnixTerminal; 38 import jdk.internal.jline.Terminal; 39 import jdk.internal.jline.TerminalFactory; 40 import jdk.internal.jline.TerminalFactory.Flavor; 41 import jdk.internal.jline.WindowsTerminal; 42 import jdk.internal.jline.console.ConsoleReader; 43 import jdk.internal.jline.console.completer.Completer; 44 import jdk.internal.jline.console.history.FileHistory; 45 46 class Console implements AutoCloseable { 47 private final ConsoleReader in; 48 private final FileHistory history; 49 50 Console(final InputStream cmdin, final PrintStream cmdout, final File historyFile, 51 final Completer completer) throws IOException { 52 TerminalFactory.registerFlavor(Flavor.WINDOWS, isCygwin()? JJSUnixTerminal::new : JJSWindowsTerminal::new); 53 TerminalFactory.registerFlavor(Flavor.UNIX, JJSUnixTerminal::new); 54 in = new ConsoleReader(cmdin, cmdout); 55 in.setExpandEvents(false); 56 in.setHandleUserInterrupt(true); 57 in.setBellEnabled(true); 58 in.setHistory(history = new FileHistory(historyFile)); 59 in.addCompleter(completer); 60 Runtime.getRuntime().addShutdownHook(new Thread((Runnable)this::saveHistory)); 61 } 62 63 String readLine(final String prompt) throws IOException { 64 return in.readLine(prompt); 65 } 66 67 @Override 68 public void close() { 69 saveHistory(); 70 } 71 72 private void saveHistory() { 73 try { 74 getHistory().flush(); 75 } catch (final IOException exp) {} 76 } 77 78 FileHistory getHistory() { 79 return (FileHistory) in.getHistory(); 80 } 81 82 boolean terminalEditorRunning() { 83 Terminal terminal = in.getTerminal(); 84 if (terminal instanceof JJSUnixTerminal) { 85 return ((JJSUnixTerminal) terminal).isRaw(); 86 } 87 return false; 88 } 89 90 void suspend() { 91 try { 92 in.getTerminal().restore(); 93 } catch (Exception ex) { 94 throw new IllegalStateException(ex); 95 } 96 } 97 98 void resume() { 99 try { 100 in.getTerminal().init(); 101 } catch (Exception ex) { 102 throw new IllegalStateException(ex); 103 } 104 } 105 106 static final class JJSUnixTerminal extends NoInterruptUnixTerminal { 107 JJSUnixTerminal() throws Exception { 108 } 109 110 boolean isRaw() { 111 try { 112 return getSettings().get("-a").contains("-icanon"); 113 } catch (IOException | InterruptedException ex) { 114 return false; 115 } 116 } 117 118 @Override 119 public void disableInterruptCharacter() { 120 } 121 122 @Override 123 public void enableInterruptCharacter() { 124 } 125 } 126 127 static final class JJSWindowsTerminal extends WindowsTerminal { 128 public JJSWindowsTerminal() throws Exception { 129 } 130 131 @Override 132 public void init() throws Exception { 133 super.init(); 134 setAnsiSupported(false); 135 } 136 } 137 138 private static boolean isCygwin() { 139 return System.getenv("SHELL") != null; 140 } 141 }