From 456c1317ad44558aaf4b9c767d38264741c17b36 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Mon, 12 Dec 2016 19:07:33 +0100 Subject: [PATCH] Improve support for dumb terminals (see #42, FELIX-5388) --- .../org/jline/reader/impl/LineReaderImpl.java | 56 ++++++++++--------- .../org/jline/terminal/TerminalBuilder.java | 13 ++++- .../jline/terminal/impl/PosixSysTerminal.java | 1 + src/main/java/org/jline/utils/Display.java | 7 +++ src/main/java/org/jline/utils/Log.java | 9 +++ 5 files changed, 58 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/jline/reader/impl/LineReaderImpl.java b/src/main/java/org/jline/reader/impl/LineReaderImpl.java index 007d40ce4..3a6871857 100644 --- a/src/main/java/org/jline/reader/impl/LineReaderImpl.java +++ b/src/main/java/org/jline/reader/impl/LineReaderImpl.java @@ -430,21 +430,13 @@ public String readLine(String prompt, String rightPrompt, Character mask, String SignalHandler previousWinchHandler = null; SignalHandler previousContHandler = null; Attributes originalAttributes = null; + boolean dumb = Terminal.TYPE_DUMB.equals(terminal.getType()); try { if (reading) { throw new IllegalStateException(); } reading = true; - if (history != null) { - history.attach(this); - } - - previousIntrHandler = terminal.handle(Signal.INT, signal -> readLineThread.interrupt()); - previousWinchHandler = terminal.handle(Signal.WINCH, this::handleSignal); - previousContHandler = terminal.handle(Signal.CONT, this::handleSignal); - originalAttributes = terminal.enterRawMode(); - this.mask = mask; /* @@ -461,12 +453,28 @@ public String readLine(String prompt, String rightPrompt, Character mask, String modifiedHistory.clear(); + setPrompt(prompt); + setRightPrompt(rightPrompt); + buf.clear(); + if (buffer != null) { + buf.write(buffer); + } + undo.clear(); + parsedLine = null; + keyMap = MAIN; + + if (history != null) { + history.attach(this); + } + + previousIntrHandler = terminal.handle(Signal.INT, signal -> readLineThread.interrupt()); + previousWinchHandler = terminal.handle(Signal.WINCH, this::handleSignal); + previousContHandler = terminal.handle(Signal.CONT, this::handleSignal); + originalAttributes = terminal.enterRawMode(); + // Cache terminal size for the duration of the call to readLine() // It will eventually be updated with WINCH signals size.copy(terminal.getSize()); -// if (size.getColumns() == 0 || size.getRows() == 0) { -// throw new IllegalStateException("Invalid terminal size: " + size); -// } display = new Display(terminal, false); if (size.getRows() == 0 || size.getColumns() == 0) { @@ -478,21 +486,13 @@ public String readLine(String prompt, String rightPrompt, Character mask, String display.setDelayLineWrap(true); // Move into application mode - terminal.puts(Capability.keypad_xmit); - if (isSet(Option.AUTO_FRESH_LINE)) - freshLine(); - if (isSet(Option.MOUSE)) - terminal.trackMouse(Terminal.MouseTracking.Normal); - - setPrompt(prompt); - setRightPrompt(rightPrompt); - buf.clear(); - if (buffer != null) { - buf.write(buffer); + if (!dumb) { + terminal.puts(Capability.keypad_xmit); + if (isSet(Option.AUTO_FRESH_LINE)) + freshLine(); + if (isSet(Option.MOUSE)) + terminal.trackMouse(Terminal.MouseTracking.Normal); } - undo.clear(); - parsedLine = null; - keyMap = MAIN; callWidget(CALLBACK_INIT); @@ -555,7 +555,9 @@ public String readLine(String prompt, String rightPrompt, Character mask, String mult = 1; } - redisplay(); + if (!dumb) { + redisplay(); + } } } catch (IOError e) { if (e.getCause() instanceof InterruptedIOException) { diff --git a/src/main/java/org/jline/terminal/TerminalBuilder.java b/src/main/java/org/jline/terminal/TerminalBuilder.java index 510605927..232a5bbf8 100644 --- a/src/main/java/org/jline/terminal/TerminalBuilder.java +++ b/src/main/java/org/jline/terminal/TerminalBuilder.java @@ -170,6 +170,13 @@ private Terminal doBuild() throws IOException { if (type == null) { type = System.getenv("TERM"); } + Boolean dumb = this.dumb; + if (dumb == null) { + String str = System.getProperty("org.jline.terminal.dumb"); + if (str != null) { + dumb = Boolean.parseBoolean(str); + } + } if ((system != null && system) || (system == null && in == null && out == null)) { if (attributes != null || size != null) { Log.warn("Attributes and size fields are ignored when creating a system terminal"); @@ -229,7 +236,11 @@ else if (OSUtils.IS_WINDOWS) { } if (dumb == null || dumb) { if (dumb == null) { - Log.warn("Creating a dumb terminal", exception); + if (Log.isDebugEnabled()) { + Log.warn("Creating a dumb terminal", exception); + } else { + Log.warn("Unable to create a system terminal, creating a dumb terminal (enable debug logging for more information)"); + } } return new DumbTerminal(name, type != null ? type : Terminal.TYPE_DUMB, new FileInputStream(FileDescriptor.in), diff --git a/src/main/java/org/jline/terminal/impl/PosixSysTerminal.java b/src/main/java/org/jline/terminal/impl/PosixSysTerminal.java index 343ac4e76..1915f32f1 100644 --- a/src/main/java/org/jline/terminal/impl/PosixSysTerminal.java +++ b/src/main/java/org/jline/terminal/impl/PosixSysTerminal.java @@ -108,5 +108,6 @@ public void close() throws IOException { Signals.unregister(entry.getKey().name(), entry.getValue()); } super.close(); + reader.shutdown(); } } diff --git a/src/main/java/org/jline/utils/Display.java b/src/main/java/org/jline/utils/Display.java index be722f452..3d9ac64d1 100644 --- a/src/main/java/org/jline/utils/Display.java +++ b/src/main/java/org/jline/utils/Display.java @@ -104,6 +104,13 @@ public void update(List newLines, int targetCursorPos) { reset = false; } + // If dumb display, get rid of ansi sequences now + Integer cols = terminal.getNumericCapability(Capability.max_colors); + if (cols == null || cols < 8) { + newLines = newLines.stream().map(s -> new AttributedString(s.toString())) + .collect(Collectors.toList()); + } + // Detect scrolling if (fullScreen && newLines.size() == oldLines.size() && canScroll) { int nbHeaders = 0; diff --git a/src/main/java/org/jline/utils/Log.java b/src/main/java/org/jline/utils/Log.java index 3b5eabdeb..5537ac287 100644 --- a/src/main/java/org/jline/utils/Log.java +++ b/src/main/java/org/jline/utils/Log.java @@ -48,6 +48,10 @@ public static void error(final Object... messages) { log(Level.SEVERE, messages); } + public static boolean isDebugEnabled() { + return isEnabled(Level.FINE); + } + /** * Helper to support rendering messages. */ @@ -107,4 +111,9 @@ static void logr(final Level level, final Supplier record) { } } + static boolean isEnabled(Level level) { + Logger logger = Logger.getLogger("org.jline"); + return logger.isLoggable(level); + } + } \ No newline at end of file