8203827: Upgrade JLine to 2.14.6

Reviewed-by: alanb, hannesw, rfield
This commit is contained in:
Jan Lahoda 2018-06-01 13:04:30 +02:00
parent f4b24c3473
commit aabea5d599
63 changed files with 3028 additions and 831 deletions

View File

@ -0,0 +1,135 @@
/*
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
*
* http://www.opensource.org/licenses/bsd-license.php
*/
package jdk.internal.jline;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import jdk.internal.jline.internal.InfoCmp;
/**
* Terminal wrapper with default ansi capabilities
*/
public class DefaultTerminal2 implements Terminal2 {
private final Terminal terminal;
private final Set<String> bools = new HashSet<String>();
private final Map<String, String> strings = new HashMap<String, String>();
public DefaultTerminal2(Terminal terminal) {
this.terminal = terminal;
registerCap("key_backspace", "^H");
registerCap("bell", "^G");
registerCap("carriage_return", "^M");
if (true/*isSupported() && isAnsiSupported()*/) {
registerCap("clr_eol", "\\E[K");
registerCap("clr_bol", "\\E[1K");
registerCap("cursor_up", "\\E[A");
registerCap("cursor_down", "^J");
registerCap("column_address", "\\E[%i%p1%dG");
registerCap("clear_screen", "\\E[H\\E[2J");
registerCap("parm_down_cursor", "\\E[%p1%dB");
registerCap("cursor_left", "^H");
registerCap("cursor_right", "\\E[C");
}
if (hasWeirdWrap()) {
registerCap("eat_newline_glitch");
registerCap("auto_right_margin");
}
}
public void init() throws Exception {
terminal.init();
}
public void restore() throws Exception {
terminal.restore();
}
public void reset() throws Exception {
terminal.reset();
}
public boolean isSupported() {
return terminal.isSupported();
}
public int getWidth() {
return terminal.getWidth();
}
public int getHeight() {
return terminal.getHeight();
}
public boolean isAnsiSupported() {
return terminal.isAnsiSupported();
}
public OutputStream wrapOutIfNeeded(OutputStream out) {
return terminal.wrapOutIfNeeded(out);
}
public InputStream wrapInIfNeeded(InputStream in) throws IOException {
return terminal.wrapInIfNeeded(in);
}
public boolean hasWeirdWrap() {
return terminal.hasWeirdWrap();
}
public boolean isEchoEnabled() {
return terminal.isEchoEnabled();
}
public void setEchoEnabled(boolean enabled) {
terminal.setEchoEnabled(enabled);
}
public void disableInterruptCharacter() {
terminal.disableInterruptCharacter();
}
public void enableInterruptCharacter() {
terminal.enableInterruptCharacter();
}
public String getOutputEncoding() {
return terminal.getOutputEncoding();
}
private void registerCap(String cap, String value) {
for (String key : InfoCmp.getNames(cap)) {
strings.put(key, value);
}
}
private void registerCap(String cap) {
Collections.addAll(bools, InfoCmp.getNames(cap));
}
public boolean getBooleanCapability(String capability) {
return bools.contains(capability);
}
public Integer getNumericCapability(String capability) {
return null;
}
public String getStringCapability(String capability) {
return strings.get(capability);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -18,6 +18,8 @@ package jdk.internal.jline;
public class NoInterruptUnixTerminal
extends UnixTerminal
{
private String intr;
public NoInterruptUnixTerminal() throws Exception {
super();
}
@ -25,12 +27,20 @@ public class NoInterruptUnixTerminal
@Override
public void init() throws Exception {
super.init();
getSettings().set("intr undef");
intr = getSettings().getPropertyAsString("intr");
if ("<undef>".equals(intr)) {
intr = null;
}
if (intr != null) {
getSettings().undef("intr");
}
}
@Override
public void restore() throws Exception {
getSettings().set("intr ^C");
if (intr != null) {
getSettings().set("intr", intr);
}
super.restore();
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
*
* http://www.opensource.org/licenses/bsd-license.php
*/
package jdk.internal.jline;
import jdk.internal.jline.internal.Log;
/**
* Terminal that is used for OSv. This is seperate to unix terminal
* implementation because exec cannot be used as currently used by UnixTerminal.
*
* This implimentation is derrived from the implementation at
* https://github.com/cloudius-systems/mgmt/blob/master/crash/src/main/java/com/cloudius/cli/OSvTerminal.java
* authored by Or Cohen.
*
* @author <a href-"mailto:orc@fewbytes.com">Or Cohen</a>
* @author <a href="mailto:arun.neelicattu@gmail.com">Arun Neelicattu</a>
* @since 2.13
*/
public class OSvTerminal
extends TerminalSupport
{
public Class<?> sttyClass = null;
public Object stty = null;
@SuppressWarnings("deprecation")
public OSvTerminal() {
super(true);
setAnsiSupported(true);
try {
if (stty == null) {
sttyClass = Class.forName("com.cloudius.util.Stty");
stty = sttyClass.newInstance();
}
} catch (Exception e) {
Log.warn("Failed to load com.cloudius.util.Stty", e);
}
}
@Override
public void init() throws Exception {
super.init();
if (stty != null) {
sttyClass.getMethod("jlineMode").invoke(stty);
}
}
@Override
public void restore() throws Exception {
if (stty != null) {
sttyClass.getMethod("reset").invoke(stty);
}
super.restore();
// Newline in end of restore like in jline.UnixTerminal
System.out.println();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -60,6 +60,9 @@ public interface Terminal
void setEchoEnabled(boolean enabled);
void disableInterruptCharacter();
void enableInterruptCharacter();
String getOutputEncoding();
}

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
*
* http://www.opensource.org/licenses/bsd-license.php
*/
package jdk.internal.jline;
/**
* Terminal extension.
*
* @author <a href="mailto:gnodet@gmail.com">Guillaume Nodet</a>
* @since 2.13
*/
public interface Terminal2 extends Terminal
{
boolean getBooleanCapability(String capability);
Integer getNumericCapability(String capability);
String getStringCapability(String capability);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -11,11 +11,9 @@ package jdk.internal.jline;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import jdk.internal.jline.internal.Configuration;
import jdk.internal.jline.internal.Log;
import jdk.internal.jline.internal.Preconditions;
import static jdk.internal.jline.internal.Preconditions.checkNotNull;
/**
@ -32,10 +30,14 @@ public class TerminalFactory
public static final String UNIX = "unix";
public static final String OSV = "osv";
public static final String WIN = "win";
public static final String WINDOWS = "windows";
public static final String FREEBSD = "freebsd";
public static final String NONE = "none";
public static final String OFF = "off";
@ -45,16 +47,17 @@ public class TerminalFactory
private static Terminal term = null;
public static synchronized Terminal create() {
return create(null);
}
public static synchronized Terminal create(String ttyDevice) {
if (Log.TRACE) {
//noinspection ThrowableInstanceNeverThrown
Log.trace(new Throwable("CREATE MARKER"));
}
String type = Configuration.getString(JLINE_TERMINAL, AUTO);
if ("dumb".equals(System.getenv("TERM"))) {
type = "none";
Log.debug("$TERM=dumb; setting type=", type);
}
String defaultType = "dumb".equals(System.getenv("TERM")) ? NONE : AUTO;
String type = Configuration.getString(JLINE_TERMINAL, defaultType);
Log.debug("Creating terminal; type=", type);
@ -65,11 +68,20 @@ public class TerminalFactory
if (tmp.equals(UNIX)) {
t = getFlavor(Flavor.UNIX);
}
else if (tmp.equals(WIN) | tmp.equals(WINDOWS)) {
else if (tmp.equals(OSV)) {
t = getFlavor(Flavor.OSV);
}
else if (tmp.equals(WIN) || tmp.equals(WINDOWS)) {
t = getFlavor(Flavor.WINDOWS);
}
else if (tmp.equals(NONE) || tmp.equals(OFF) || tmp.equals(FALSE)) {
t = new UnsupportedTerminal();
if (System.getenv("INSIDE_EMACS") != null) {
// emacs requires ansi on and echo off
t = new UnsupportedTerminal(true, false);
} else {
// others the other way round
t = new UnsupportedTerminal(false, true);
}
}
else {
if (tmp.equals(AUTO)) {
@ -77,8 +89,10 @@ public class TerminalFactory
Flavor flavor = Flavor.UNIX;
if (os.contains(WINDOWS)) {
flavor = Flavor.WINDOWS;
} else if (System.getenv("OSV_CPUS") != null) {
flavor = Flavor.OSV;
}
t = getFlavor(flavor);
t = getFlavor(flavor, ttyDevice);
}
else {
try {
@ -125,6 +139,7 @@ public class TerminalFactory
AUTO,
WINDOWS,
UNIX,
OSV,
NONE
}
@ -145,31 +160,52 @@ public class TerminalFactory
public static enum Flavor
{
WINDOWS,
UNIX
UNIX,
OSV
}
private static final Map<Flavor, Callable<? extends Terminal>> FLAVORS = new HashMap<>();
private static final Map<Flavor, TerminalConstructor> FLAVORS = new HashMap<>();
static {
// registerFlavor(Flavor.WINDOWS, AnsiWindowsTerminal.class);
// registerFlavor(Flavor.UNIX, UnixTerminal.class);
registerFlavor(Flavor.WINDOWS, WindowsTerminal :: new);
registerFlavor(Flavor.UNIX, UnixTerminal :: new);
registerFlavor(Flavor.WINDOWS, ttyDevice -> new WindowsTerminal());
registerFlavor(Flavor.UNIX, ttyDevice -> new UnixTerminal(ttyDevice));
registerFlavor(Flavor.OSV, ttyDevice -> new OSvTerminal());
}
public static synchronized Terminal get() {
public static synchronized Terminal get(String ttyDevice) {
// The code is assuming we've got only one terminal per process.
// Continuing this assumption, if this terminal is already initialized,
// we don't check if it's using the same tty line either. Both assumptions
// are a bit crude. TODO: check single terminal assumption.
if (term == null) {
term = create();
term = create(ttyDevice);
}
return term;
}
public static synchronized Terminal get() {
return get(null);
}
public static Terminal getFlavor(final Flavor flavor) throws Exception {
return FLAVORS.getOrDefault(flavor, () -> {throw new InternalError();}).call();
return getFlavor(flavor, null);
}
public static void registerFlavor(final Flavor flavor, final Callable<? extends Terminal> sup) {
FLAVORS.put(flavor, sup);
@SuppressWarnings("deprecation")
public static Terminal getFlavor(final Flavor flavor, String ttyDevice) throws Exception {
TerminalConstructor factory = FLAVORS.get(flavor);
if (factory != null) {
return factory.createTerminal(ttyDevice);
} else {
throw new InternalError();
}
}
public static void registerFlavor(final Flavor flavor, final TerminalConstructor factory) {
FLAVORS.put(flavor, factory);
}
public interface TerminalConstructor {
public Terminal createTerminal(String str) throws Exception;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -112,6 +112,12 @@ public abstract class TerminalSupport
Log.debug("Echo enabled: ", enabled);
}
public void disableInterruptCharacter() {
}
public void enableInterruptCharacter() {
}
public InputStream wrapInIfNeeded(InputStream in) throws IOException {
return in;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -8,9 +8,18 @@
*/
package jdk.internal.jline;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import jdk.internal.jline.internal.Configuration;
import jdk.internal.jline.internal.InfoCmp;
import jdk.internal.jline.internal.Log;
import jdk.internal.jline.internal.TerminalLineSettings;
import static jdk.internal.jline.internal.Preconditions.checkNotNull;
/**
* Terminal that is used for unix platforms. Terminal initialization
* is handled by issuing the <em>stty</em> command against the
@ -27,14 +36,36 @@ import jdk.internal.jline.internal.TerminalLineSettings;
*/
public class UnixTerminal
extends TerminalSupport
implements Terminal2
{
private final TerminalLineSettings settings = new TerminalLineSettings();
private final TerminalLineSettings settings;
private final String type;
private String intr;
private String lnext;
private Set<String> bools = new HashSet<String>();
private Map<String, Integer> ints = new HashMap<String, Integer>();
private Map<String, String> strings = new HashMap<String, String>();
public UnixTerminal() throws Exception {
super(true);
this(TerminalLineSettings.DEFAULT_TTY, null);
}
protected TerminalLineSettings getSettings() {
public UnixTerminal(String ttyDevice) throws Exception {
this(ttyDevice, null);
}
public UnixTerminal(String ttyDevice, String type) throws Exception {
super(true);
checkNotNull(ttyDevice);
this.settings = TerminalLineSettings.getSettings(ttyDevice);
if (type == null) {
type = System.getenv("TERM");
}
this.type = type;
parseInfoCmp();
}
public TerminalLineSettings getSettings() {
return settings;
}
@ -51,10 +82,20 @@ public class UnixTerminal
// Set the console to be character-buffered instead of line-buffered.
// Make sure we're distinguishing carriage return from newline.
// Allow ctrl-s keypress to be used (as forward search)
settings.set("-icanon min 1 -icrnl -inlcr -ixon");
settings.set("dsusp undef");
//
// Please note that FreeBSD does not seem to support -icrnl and thus
// has to be handled separately. Otherwise the console will be "stuck"
// and will neither accept input nor print anything to stdout.
if (Configuration.getOsName().contains(TerminalFactory.FREEBSD)) {
settings.set("-icanon min 1 -inlcr -ixon");
} else {
settings.set("-icanon min 1 -icrnl -inlcr -ixon");
}
settings.undef("dsusp");
setEchoEnabled(false);
parseInfoCmp();
}
/**
@ -86,6 +127,12 @@ public class UnixTerminal
return h < 1 ? DEFAULT_HEIGHT : h;
}
@Override
public boolean hasWeirdWrap() {
return getBooleanCapability("auto_right_margin")
&& getBooleanCapability("eat_newline_glitch");
}
@Override
public synchronized void setEchoEnabled(final boolean enabled) {
try {
@ -101,14 +148,18 @@ public class UnixTerminal
if (e instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
Log.error("Failed to ", (enabled ? "enable" : "disable"), " echo", e);
Log.error("Failed to ", enabled ? "enable" : "disable", " echo", e);
}
}
public void disableInterruptCharacter()
{
try {
settings.set("intr undef");
intr = getSettings().getPropertyAsString("intr");
if ("<undef>".equals(intr)) {
intr = null;
}
settings.undef("intr");
}
catch (Exception e) {
if (e instanceof InterruptedException) {
@ -121,7 +172,9 @@ public class UnixTerminal
public void enableInterruptCharacter()
{
try {
settings.set("intr ^C");
if (intr != null) {
settings.set("intr", intr);
}
}
catch (Exception e) {
if (e instanceof InterruptedException) {
@ -130,4 +183,62 @@ public class UnixTerminal
Log.error("Failed to enable interrupt character", e);
}
}
public void disableLitteralNextCharacter()
{
try {
lnext = getSettings().getPropertyAsString("lnext");
if ("<undef>".equals(lnext)) {
lnext = null;
}
settings.undef("lnext");
}
catch (Exception e) {
if (e instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
Log.error("Failed to disable litteral next character", e);
}
}
public void enableLitteralNextCharacter()
{
try {
if (lnext != null) {
settings.set("lnext", lnext);
}
}
catch (Exception e) {
if (e instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
Log.error("Failed to enable litteral next character", e);
}
}
public boolean getBooleanCapability(String capability) {
return bools.contains(capability);
}
public Integer getNumericCapability(String capability) {
return ints.get(capability);
}
public String getStringCapability(String capability) {
return strings.get(capability);
}
private void parseInfoCmp() {
String capabilities = null;
if (type != null) {
try {
capabilities = InfoCmp.getInfoCmp(type);
} catch (Exception e) {
}
}
if (capabilities == null) {
capabilities = InfoCmp.getAnsiCaps();
}
InfoCmp.parseInfoCmp(capabilities, bools, ints, strings);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -19,8 +19,12 @@ public class UnsupportedTerminal
extends TerminalSupport
{
public UnsupportedTerminal() {
this(false, true);
}
public UnsupportedTerminal(boolean ansiSupported, boolean echoEnabled) {
super(false);
setAnsiSupported(false);
setEchoEnabled(true);
setAnsiSupported(ansiSupported);
setEchoEnabled(echoEnabled);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -12,7 +12,11 @@ import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import jdk.internal.jline.extra.AnsiInterpretingOutputStream;
import jdk.internal.jline.extra.AnsiInterpretingOutputStream.BufferState;
import jdk.internal.jline.extra.AnsiInterpretingOutputStream.Performer;
import jdk.internal.jline.internal.Configuration;
import jdk.internal.jline.internal.Log;
//import org.fusesource.jansi.internal.WindowsSupport;
@ -71,7 +75,7 @@ public class WindowsTerminal
super.init();
// setAnsiSupported(Configuration.getBoolean(ANSI, true));
setAnsiSupported(false);
setAnsiSupported(true);
//
// FIXME: Need a way to disable direct console and sysin detection muck
@ -115,19 +119,27 @@ public class WindowsTerminal
setConsoleMode(getConsoleMode() |
ENABLE_ECHO_INPUT.code |
ENABLE_LINE_INPUT.code |
ENABLE_PROCESSED_INPUT.code |
ENABLE_WINDOW_INPUT.code);
}
else {
setConsoleMode(getConsoleMode() &
~(ENABLE_LINE_INPUT.code |
ENABLE_ECHO_INPUT.code |
ENABLE_PROCESSED_INPUT.code |
ENABLE_WINDOW_INPUT.code));
}
super.setEchoEnabled(enabled);
}
public void disableInterruptCharacter() {
setConsoleMode(getConsoleMode() &
~(ENABLE_PROCESSED_INPUT.code));
}
public void enableInterruptCharacter() {
setConsoleMode(getConsoleMode() |
ENABLE_PROCESSED_INPUT.code);
}
/**
* Whether or not to allow the use of the JNI console interaction.
*/
@ -181,6 +193,22 @@ public class WindowsTerminal
return false;
}
@Override
public OutputStream wrapOutIfNeeded(OutputStream out) {
return new AnsiInterpretingOutputStream(getOutputEncoding(), out, new Performer() {
@Override
public BufferState getBufferState() throws IOException {
out.flush();
return WindowsTerminal.this.getBufferState();
}
@Override
public void setCursorPosition(int cursorX, int cursorY) throws IOException {
out.flush();
WindowsTerminal.this.setCursorPosition(cursorX, cursorY);
}
});
}
@Override
public String getOutputEncoding() {
int codepage = getConsoleOutputCodepage();
@ -511,6 +539,10 @@ public class WindowsTerminal
private native int getWindowsTerminalHeight();
private native BufferState getBufferState();
private native void setCursorPosition(int x, int y);
/**
* Console mode
* <p/>

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -32,11 +32,14 @@ public class ConsoleKeys {
public ConsoleKeys(String appName, URL inputrcUrl) {
keyMaps = KeyMap.keyMaps();
setVar("editing-mode", "emacs");
loadKeys(appName, inputrcUrl);
}
protected boolean isViEditMode() {
return keys.isViKeyMap();
String editingMode = variables.get("editing-mode");
if ("vi".equalsIgnoreCase(editingMode)) {
keys = keyMaps.get(KeyMap.VI_INSERT);
} else if ("emacs".equalsIgnoreCase(editingMode)) {
keys = keyMaps.get(KeyMap.EMACS);
}
}
protected boolean setKeyMap (String name) {
@ -60,10 +63,6 @@ public class ConsoleKeys {
this.keys = keys;
}
protected boolean getViEditMode() {
return keys.isViKeyMap ();
}
protected void loadKeys(String appName, URL inputrcUrl) {
keys = keyMaps.get(KeyMap.EMACS);
@ -127,13 +126,8 @@ public class ConsoleKeys {
if (args.startsWith("term=")) {
// TODO
} else if (args.startsWith("mode=")) {
if (args.equalsIgnoreCase("mode=vi")) {
parsing = isViEditMode();
} else if (args.equals("mode=emacs")) {
parsing = !isViEditMode();
} else {
parsing = false;
}
String mode = variables.get("editing-mode");
parsing = args.substring("mode=".length()).equalsIgnoreCase(mode);
} else {
parsing = args.equalsIgnoreCase(appName);
}
@ -185,7 +179,7 @@ public class ConsoleKeys {
&& line.charAt(i) != ' ' && line.charAt(i) != '\t'
; i++);
keySeq = line.substring(0, i);
equivalency = (i + 1 < line.length() && line.charAt(i) == ':' && line.charAt(i + 1) == '=');
equivalency = i + 1 < line.length() && line.charAt(i) == ':' && line.charAt(i + 1) == '=';
i++;
if (equivalency) {
i++;
@ -256,7 +250,7 @@ public class ConsoleKeys {
}
}
private String translateQuoted(String keySeq) {
private static String translateQuoted(String keySeq) {
int i;
String str = keySeq.substring( 1, keySeq.length() - 1 );
keySeq = "";
@ -342,7 +336,7 @@ public class ConsoleKeys {
return keySeq;
}
private char getKeyFromName(String name) {
private static char getKeyFromName(String name) {
if ("DEL".equalsIgnoreCase(name) || "Rubout".equalsIgnoreCase(name)) {
return 0x7f;
} else if ("ESC".equalsIgnoreCase(name) || "Escape".equalsIgnoreCase(name)) {
@ -365,12 +359,6 @@ public class ConsoleKeys {
if (keyMaps.containsKey(val)) {
keys = keyMaps.get(val);
}
} else if ("editing-mode".equals(key)) {
if ("vi".equalsIgnoreCase(val)) {
keys = keyMaps.get(KeyMap.VI_INSERT);
} else if ("emacs".equalsIgnoreCase(key)) {
keys = keyMaps.get(KeyMap.EMACS);
}
} else if ("blink-matching-paren".equals(key)) {
if ("on".equalsIgnoreCase(val)) {
keys.setBlinkMatchingParen(true);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -92,7 +92,7 @@ public class CursorBuffer
cursor += str.length();
if (isOverTyping() && cursor < buffer.length()) {
buffer.delete(cursor, (cursor + str.length()));
buffer.delete(cursor, cursor + str.length());
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -33,20 +33,19 @@ public class KeyMap {
private Object[] mapping = new Object[KEYMAP_LENGTH];
private Object anotherKey = null;
private String name;
private boolean isViKeyMap;
public KeyMap(String name, boolean isViKeyMap) {
this(name, new Object[KEYMAP_LENGTH], isViKeyMap);
public KeyMap(String name) {
this(name, new Object[KEYMAP_LENGTH]);
}
protected KeyMap(String name, Object[] mapping, boolean isViKeyMap) {
@Deprecated
public KeyMap(String name, boolean unused) {
this(name);
}
protected KeyMap(String name, Object[] mapping) {
this.mapping = mapping;
this.name = name;
this.isViKeyMap = isViKeyMap;
}
public boolean isViKeyMap() {
return isViKeyMap;
}
public String getName() {
@ -110,7 +109,7 @@ public class KeyMap {
}
if (i < keySeq.length() - 1) {
if (!(map.mapping[c] instanceof KeyMap)) {
KeyMap m = new KeyMap("anonymous", false);
KeyMap m = new KeyMap("anonymous");
if (map.mapping[c] != Operation.DO_LOWERCASE_VERSION) {
m.anotherKey = map.mapping[c];
}
@ -239,11 +238,11 @@ public class KeyMap {
bindArrowKeys(viMov);
keyMaps.put(VI_MOVE, viMov);
keyMaps.put("vi-command", viMov);
keyMaps.put("vi", viMov);
KeyMap viIns = viInsertion();
bindArrowKeys(viIns);
keyMaps.put(VI_INSERT, viIns);
keyMaps.put("vi", viIns);
return keyMaps;
}
@ -290,7 +289,7 @@ public class KeyMap {
map[i] = Operation.SELF_INSERT;
}
map[DELETE] = Operation.BACKWARD_DELETE_CHAR;
return new KeyMap(EMACS, map, false);
return new KeyMap(EMACS, map);
}
public static final char CTRL_D = (char) 4;
@ -323,7 +322,7 @@ public class KeyMap {
}
map['e'] = Operation.CALL_LAST_KBD_MACRO;
map[DELETE] = Operation.KILL_LINE;
return new KeyMap(EMACS_CTLX, map, false);
return new KeyMap(EMACS_CTLX, map);
}
public static KeyMap emacsMeta() {
@ -364,7 +363,7 @@ public class KeyMap {
map['y'] = Operation.YANK_POP;
map['~'] = Operation.TILDE_EXPAND;
map[DELETE] = Operation.BACKWARD_KILL_WORD;
return new KeyMap(EMACS_META, map, false);
return new KeyMap(EMACS_META, map);
}
public static KeyMap viInsertion() {
@ -409,7 +408,7 @@ public class KeyMap {
map[i] = Operation.SELF_INSERT;
}
map[DELETE] = Operation.BACKWARD_DELETE_CHAR;
return new KeyMap(VI_INSERT, map, false);
return new KeyMap(VI_INSERT, map);
}
public static KeyMap viMovement() {
@ -485,7 +484,7 @@ public class KeyMap {
/* TODO */
Operation.VI_REDO, /* . */
Operation.VI_SEARCH, /* / */
Operation.VI_BEGNNING_OF_LINE_OR_ARG_DIGIT, /* 0 */
Operation.VI_BEGINNING_OF_LINE_OR_ARG_DIGIT, /* 0 */
Operation.VI_ARG_DIGIT, /* 1 */
Operation.VI_ARG_DIGIT, /* 2 */
Operation.VI_ARG_DIGIT, /* 3 */
@ -573,6 +572,6 @@ public class KeyMap {
for (int i = 128; i < 256; i++) {
map[i] = null;
}
return new KeyMap(VI_MOVE, map, false);
return new KeyMap(VI_MOVE, map);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2013, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -38,7 +38,7 @@ public final class KillRing {
}
/**
* Creates a new kill ring of the default size. {@see DEFAULT_SIZE}.
* Creates a new kill ring of the default size. See {@link #DEFAULT_SIZE}.
*/
public KillRing() {
this(DEFAULT_SIZE);
@ -152,7 +152,7 @@ public final class KillRing {
private void prev() {
head--;
if (head == -1) {
int x = (slots.length - 1);
int x = slots.length - 1;
for (; x >= 0; x--) {
if (slots[x] != null) {
break;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -81,6 +81,7 @@ public enum Operation {
POSSIBLE_COMPLETIONS,
PREVIOUS_HISTORY,
QUOTED_INSERT,
QUIT,
RE_READ_INIT_FILE,
REDRAW_CURRENT_LINE,
REVERSE_SEARCH_HISTORY,
@ -156,5 +157,5 @@ public enum Operation {
VI_NEXT_HISTORY,
VI_PREVIOUS_HISTORY,
VI_INSERT_COMMENT,
VI_BEGNNING_OF_LINE_OR_ARG_DIGIT,
VI_BEGINNING_OF_LINE_OR_ARG_DIGIT,
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.

View File

@ -0,0 +1,158 @@
/*
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
*
* http://www.opensource.org/licenses/bsd-license.php
*/
package jdk.internal.jline.console;
public class WCWidth {
/* The following two functions define the column width of an ISO 10646
* character as follows:
*
* - The null character (U+0000) has a column width of 0.
*
* - Other C0/C1 control characters and DEL will lead to a return
* value of -1.
*
* - Non-spacing and enclosing combining characters (general
* category code Mn or Me in the Unicode database) have a
* column width of 0.
*
* - SOFT HYPHEN (U+00AD) has a column width of 1.
*
* - Other format characters (general category code Cf in the Unicode
* database) and ZERO WIDTH SPACE (U+200B) have a column width of 0.
*
* - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF)
* have a column width of 0.
*
* - Spacing characters in the East Asian Wide (W) or East Asian
* Full-width (F) category as defined in Unicode Technical
* Report #11 have a column width of 2.
*
* - All remaining characters (including all printable
* ISO 8859-1 and WGL4 characters, Unicode control characters,
* etc.) have a column width of 1.
*
* This implementation assumes that wchar_t characters are encoded
* in ISO 10646.
*/
public static int wcwidth(int ucs)
{
/* test for 8-bit control characters */
if (ucs == 0)
return 0;
if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))
return -1;
/* binary search in table of non-spacing characters */
if (bisearch(ucs, combining, combining.length - 1))
return 0;
/* if we arrive here, ucs is not a combining or C0/C1 control character */
return 1 +
((ucs >= 0x1100 &&
(ucs <= 0x115f || /* Hangul Jamo init. consonants */
ucs == 0x2329 || ucs == 0x232a ||
(ucs >= 0x2e80 && ucs <= 0xa4cf &&
ucs != 0x303f) || /* CJK ... Yi */
(ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
(ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */
(ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */
(ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */
(ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */
(ucs >= 0xffe0 && ucs <= 0xffe6) ||
(ucs >= 0x20000 && ucs <= 0x2fffd) ||
(ucs >= 0x30000 && ucs <= 0x3fffd))) ? 1 : 0);
}
/* sorted list of non-overlapping intervals of non-spacing characters */
/* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */
static Interval[] combining = {
new Interval( 0x0300, 0x036F ), new Interval( 0x0483, 0x0486 ), new Interval( 0x0488, 0x0489 ),
new Interval( 0x0591, 0x05BD ), new Interval( 0x05BF, 0x05BF ), new Interval( 0x05C1, 0x05C2 ),
new Interval( 0x05C4, 0x05C5 ), new Interval( 0x05C7, 0x05C7 ), new Interval( 0x0600, 0x0603 ),
new Interval( 0x0610, 0x0615 ), new Interval( 0x064B, 0x065E ), new Interval( 0x0670, 0x0670 ),
new Interval( 0x06D6, 0x06E4 ), new Interval( 0x06E7, 0x06E8 ), new Interval( 0x06EA, 0x06ED ),
new Interval( 0x070F, 0x070F ), new Interval( 0x0711, 0x0711 ), new Interval( 0x0730, 0x074A ),
new Interval( 0x07A6, 0x07B0 ), new Interval( 0x07EB, 0x07F3 ), new Interval( 0x0901, 0x0902 ),
new Interval( 0x093C, 0x093C ), new Interval( 0x0941, 0x0948 ), new Interval( 0x094D, 0x094D ),
new Interval( 0x0951, 0x0954 ), new Interval( 0x0962, 0x0963 ), new Interval( 0x0981, 0x0981 ),
new Interval( 0x09BC, 0x09BC ), new Interval( 0x09C1, 0x09C4 ), new Interval( 0x09CD, 0x09CD ),
new Interval( 0x09E2, 0x09E3 ), new Interval( 0x0A01, 0x0A02 ), new Interval( 0x0A3C, 0x0A3C ),
new Interval( 0x0A41, 0x0A42 ), new Interval( 0x0A47, 0x0A48 ), new Interval( 0x0A4B, 0x0A4D ),
new Interval( 0x0A70, 0x0A71 ), new Interval( 0x0A81, 0x0A82 ), new Interval( 0x0ABC, 0x0ABC ),
new Interval( 0x0AC1, 0x0AC5 ), new Interval( 0x0AC7, 0x0AC8 ), new Interval( 0x0ACD, 0x0ACD ),
new Interval( 0x0AE2, 0x0AE3 ), new Interval( 0x0B01, 0x0B01 ), new Interval( 0x0B3C, 0x0B3C ),
new Interval( 0x0B3F, 0x0B3F ), new Interval( 0x0B41, 0x0B43 ), new Interval( 0x0B4D, 0x0B4D ),
new Interval( 0x0B56, 0x0B56 ), new Interval( 0x0B82, 0x0B82 ), new Interval( 0x0BC0, 0x0BC0 ),
new Interval( 0x0BCD, 0x0BCD ), new Interval( 0x0C3E, 0x0C40 ), new Interval( 0x0C46, 0x0C48 ),
new Interval( 0x0C4A, 0x0C4D ), new Interval( 0x0C55, 0x0C56 ), new Interval( 0x0CBC, 0x0CBC ),
new Interval( 0x0CBF, 0x0CBF ), new Interval( 0x0CC6, 0x0CC6 ), new Interval( 0x0CCC, 0x0CCD ),
new Interval( 0x0CE2, 0x0CE3 ), new Interval( 0x0D41, 0x0D43 ), new Interval( 0x0D4D, 0x0D4D ),
new Interval( 0x0DCA, 0x0DCA ), new Interval( 0x0DD2, 0x0DD4 ), new Interval( 0x0DD6, 0x0DD6 ),
new Interval( 0x0E31, 0x0E31 ), new Interval( 0x0E34, 0x0E3A ), new Interval( 0x0E47, 0x0E4E ),
new Interval( 0x0EB1, 0x0EB1 ), new Interval( 0x0EB4, 0x0EB9 ), new Interval( 0x0EBB, 0x0EBC ),
new Interval( 0x0EC8, 0x0ECD ), new Interval( 0x0F18, 0x0F19 ), new Interval( 0x0F35, 0x0F35 ),
new Interval( 0x0F37, 0x0F37 ), new Interval( 0x0F39, 0x0F39 ), new Interval( 0x0F71, 0x0F7E ),
new Interval( 0x0F80, 0x0F84 ), new Interval( 0x0F86, 0x0F87 ), new Interval( 0x0F90, 0x0F97 ),
new Interval( 0x0F99, 0x0FBC ), new Interval( 0x0FC6, 0x0FC6 ), new Interval( 0x102D, 0x1030 ),
new Interval( 0x1032, 0x1032 ), new Interval( 0x1036, 0x1037 ), new Interval( 0x1039, 0x1039 ),
new Interval( 0x1058, 0x1059 ), new Interval( 0x1160, 0x11FF ), new Interval( 0x135F, 0x135F ),
new Interval( 0x1712, 0x1714 ), new Interval( 0x1732, 0x1734 ), new Interval( 0x1752, 0x1753 ),
new Interval( 0x1772, 0x1773 ), new Interval( 0x17B4, 0x17B5 ), new Interval( 0x17B7, 0x17BD ),
new Interval( 0x17C6, 0x17C6 ), new Interval( 0x17C9, 0x17D3 ), new Interval( 0x17DD, 0x17DD ),
new Interval( 0x180B, 0x180D ), new Interval( 0x18A9, 0x18A9 ), new Interval( 0x1920, 0x1922 ),
new Interval( 0x1927, 0x1928 ), new Interval( 0x1932, 0x1932 ), new Interval( 0x1939, 0x193B ),
new Interval( 0x1A17, 0x1A18 ), new Interval( 0x1B00, 0x1B03 ), new Interval( 0x1B34, 0x1B34 ),
new Interval( 0x1B36, 0x1B3A ), new Interval( 0x1B3C, 0x1B3C ), new Interval( 0x1B42, 0x1B42 ),
new Interval( 0x1B6B, 0x1B73 ), new Interval( 0x1DC0, 0x1DCA ), new Interval( 0x1DFE, 0x1DFF ),
new Interval( 0x200B, 0x200F ), new Interval( 0x202A, 0x202E ), new Interval( 0x2060, 0x2063 ),
new Interval( 0x206A, 0x206F ), new Interval( 0x20D0, 0x20EF ), new Interval( 0x302A, 0x302F ),
new Interval( 0x3099, 0x309A ), new Interval( 0xA806, 0xA806 ), new Interval( 0xA80B, 0xA80B ),
new Interval( 0xA825, 0xA826 ), new Interval( 0xFB1E, 0xFB1E ), new Interval( 0xFE00, 0xFE0F ),
new Interval( 0xFE20, 0xFE23 ), new Interval( 0xFEFF, 0xFEFF ), new Interval( 0xFFF9, 0xFFFB ),
new Interval( 0x10A01, 0x10A03 ), new Interval( 0x10A05, 0x10A06 ), new Interval( 0x10A0C, 0x10A0F ),
new Interval( 0x10A38, 0x10A3A ), new Interval( 0x10A3F, 0x10A3F ), new Interval( 0x1D167, 0x1D169 ),
new Interval( 0x1D173, 0x1D182 ), new Interval( 0x1D185, 0x1D18B ), new Interval( 0x1D1AA, 0x1D1AD ),
new Interval( 0x1D242, 0x1D244 ), new Interval( 0xE0001, 0xE0001 ), new Interval( 0xE0020, 0xE007F ),
new Interval( 0xE0100, 0xE01EF )
};
private static class Interval {
public final int first;
public final int last;
public Interval(int first, int last) {
this.first = first;
this.last = last;
}
}
/* auxiliary function for binary search in interval table */
private static boolean bisearch(int ucs, Interval[] table, int max) {
int min = 0;
int mid;
if (ucs < table[0].first || ucs > table[max].last)
return false;
while (max >= min) {
mid = (min + max) / 2;
if (ucs > table[mid].last)
min = mid + 1;
else if (ucs < table[mid].first)
max = mid - 1;
else
return true;
}
return false;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
*
* http://www.opensource.org/licenses/bsd-license.php
*/
package jdk.internal.jline.console.completer;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import jdk.internal.jline.internal.Ansi;
import static jdk.internal.jline.internal.Preconditions.checkNotNull;
/**
* Completer for a set of strings.
*
* @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
* @since 2.3
*/
public class AnsiStringsCompleter
implements Completer
{
private final SortedMap<String, String> strings = new TreeMap<String, String>();
public AnsiStringsCompleter() {
// empty
}
public AnsiStringsCompleter(final Collection<String> strings) {
checkNotNull(strings);
for (String str : strings) {
this.strings.put(Ansi.stripAnsi(str), str);
}
}
public AnsiStringsCompleter(final String... strings) {
this(Arrays.asList(strings));
}
public Collection<String> getStrings() {
return strings.values();
}
public int complete(String buffer, final int cursor, final List<CharSequence> candidates) {
// buffer could be null
checkNotNull(candidates);
if (buffer == null) {
candidates.addAll(strings.values());
}
else {
buffer = Ansi.stripAnsi(buffer);
for (Map.Entry<String, String> match : strings.tailMap(buffer).entrySet()) {
if (!match.getKey().startsWith(buffer)) {
break;
}
candidates.add(match.getValue());
}
}
return candidates.isEmpty() ? -1 : 0;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -144,7 +144,7 @@ public class ArgumentCompleter
return -1;
}
if (subCandidates.size() == 0) {
if (!subCandidates.contains(arg)) {
return -1;
}
}
@ -326,10 +326,6 @@ public class ArgumentCompleter
/**
* Check if this character is a valid escape char (i.e. one that has not been escaped)
*
* @param buffer
* @param pos
* @return
*/
public boolean isEscapeChar(final CharSequence buffer, final int pos) {
if (pos < 0) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -10,6 +10,7 @@ package jdk.internal.jline.console.completer;
import jdk.internal.jline.console.ConsoleReader;
import jdk.internal.jline.console.CursorBuffer;
import jdk.internal.jline.internal.Ansi;
import java.io.IOException;
import java.util.ArrayList;
@ -33,6 +34,25 @@ import java.util.Set;
public class CandidateListCompletionHandler
implements CompletionHandler
{
private boolean printSpaceAfterFullCompletion = true;
private boolean stripAnsi;
public boolean getPrintSpaceAfterFullCompletion() {
return printSpaceAfterFullCompletion;
}
public void setPrintSpaceAfterFullCompletion(boolean printSpaceAfterFullCompletion) {
this.printSpaceAfterFullCompletion = printSpaceAfterFullCompletion;
}
public boolean isStripAnsi() {
return stripAnsi;
}
public void setStripAnsi(boolean stripAnsi) {
this.stripAnsi = stripAnsi;
}
// TODO: handle quotes and escaped quotes && enable automatic escaping of whitespace
public boolean complete(final ConsoleReader reader, final List<CharSequence> candidates, final int pos) throws
@ -42,7 +62,13 @@ public class CandidateListCompletionHandler
// if there is only one completion, then fill in the buffer
if (candidates.size() == 1) {
CharSequence value = candidates.get(0);
String value = Ansi.stripAnsi(candidates.get(0).toString());
if (buf.cursor == buf.buffer.length()
&& printSpaceAfterFullCompletion
&& !value.endsWith(" ")) {
value += " ";
}
// fail if the only candidate is the same as the current buffer
if (value.equals(buf.toString())) {
@ -90,7 +116,8 @@ public class CandidateListCompletionHandler
if (distinct.size() > reader.getAutoprintThreshold()) {
//noinspection StringConcatenation
reader.print(Messages.DISPLAY_CANDIDATES.format(candidates.size()));
reader.println();
reader.print(Messages.DISPLAY_CANDIDATES.format(distinct.size()));
reader.flush();
int c;
@ -142,10 +169,25 @@ public class CandidateListCompletionHandler
return null;
}
// convert to an array for speed
String[] strings = candidates.toArray(new String[candidates.size()]);
if (candidates.size() == 1) {
return candidates.get(0).toString();
}
// convert to an array for speed
String first = null;
String[] strings = new String[candidates.size() - 1];
for (int i = 0; i < candidates.size(); i++) {
String str = candidates.get(i).toString();
if (stripAnsi) {
str = Ansi.stripAnsi(str);
}
if (first == null) {
first = str;
} else {
strings[i - 1] = str;
}
}
String first = strings[0];
StringBuilder candidate = new StringBuilder();
for (int i = 0; i < first.length(); i++) {
@ -163,9 +205,9 @@ public class CandidateListCompletionHandler
/**
* @return true is all the elements of <i>candidates</i> start with <i>starts</i>
*/
private boolean startsWith(final String starts, final String[] candidates) {
private static boolean startsWith(final String starts, final String[] candidates) {
for (String candidate : candidates) {
if (!candidate.startsWith(starts)) {
if (!candidate.toLowerCase().startsWith(starts.toLowerCase())) {
return false;
}
}

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2002-2012, the original author or authors.
# Copyright (c) 2002-2016, the original author or authors.
#
# This software is distributable under the BSD license. See the terms of the
# BSD license in the documentation provided with this software.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -20,10 +20,14 @@ public class EnumCompleter
extends StringsCompleter
{
public EnumCompleter(Class<? extends Enum<?>> source) {
this(source, true);
}
public EnumCompleter(Class<? extends Enum<?>> source, boolean toLowerCase) {
checkNotNull(source);
for (Enum<?> n : source.getEnumConstants()) {
this.getStrings().add(n.name().toLowerCase());
this.getStrings().add(toLowerCase ? n.name().toLowerCase() : n.name());
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -61,10 +61,6 @@ public class StringsCompleter
}
}
if (candidates.size() == 1) {
candidates.set(0, candidates.get(0) + " ");
}
return candidates.isEmpty() ? -1 : 0;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -38,8 +38,29 @@ public class FileHistory
{
private final File file;
/**
* Load a history file into memory, truncating to default max size.
*/
public FileHistory(final File file) throws IOException {
this.file = checkNotNull(file);
this(file, true);
}
/**
* Create a FileHistory, but only initialize if doInit is true. This allows
* setting maxSize or other settings; call load() before using if doInit is
* false.
*/
public FileHistory(final File file, final boolean doInit) throws IOException {
this.file = checkNotNull(file).getAbsoluteFile();
if (doInit) {
load();
}
}
/**
* Load history from file, e.g. if using delayed init.
*/
public void load() throws IOException {
load(file);
}
@ -51,7 +72,15 @@ public class FileHistory
checkNotNull(file);
if (file.exists()) {
Log.trace("Loading history from: ", file);
load(new FileReader(file));
FileReader reader = null;
try{
reader = new FileReader(file);
load(reader);
} finally{
if(reader != null){
reader.close();
}
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -261,8 +261,6 @@ public class MemoryHistory
/**
* Move to the specified index in the history
* @param index
* @return
*/
public boolean moveTo(int index) {
index -= offset;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -12,6 +12,7 @@ import jdk.internal.jline.console.ConsoleReader;
import jdk.internal.jline.console.completer.ArgumentCompleter;
import jdk.internal.jline.console.completer.Completer;
import jdk.internal.jline.console.history.FileHistory;
import jdk.internal.jline.console.history.PersistentHistory;
import jdk.internal.jline.internal.Configuration;
import java.io.File;
@ -75,11 +76,15 @@ public class ConsoleRunner
try {
Class<?> type = Class.forName(mainClass);
Method method = type.getMethod("main", String[].class);
method.invoke(null);
String[] mainArgs = argList.toArray(new String[argList.size()]);
method.invoke(null, (Object) mainArgs);
}
finally {
// just in case this main method is called from another program
ConsoleReaderInputStream.restoreIn();
if (reader.getHistory() instanceof PersistentHistory) {
((PersistentHistory) reader.getHistory()).flush();
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.

View File

@ -0,0 +1,162 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.internal.jline.extra;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import jdk.internal.jline.internal.Ansi;
/**A stream that interprets some escape code sequences, and ignores those it does not support.
*/
public class AnsiInterpretingOutputStream extends OutputStream {
private final String encoding;
private final OutputStream out;
private final Performer performer;
private final Map<Character, AnsiCodeHandler> ESCAPE_CODE_ACTIONS = new HashMap<>();
private boolean inEscapeSequence;
private ByteArrayOutputStream escape = new ByteArrayOutputStream();
public AnsiInterpretingOutputStream(String encoding, OutputStream output, Performer performer) {
this.encoding = encoding;
this.out = output;
this.performer = performer;
ESCAPE_CODE_ACTIONS.put('A', code -> {
moveCursor(code, 0, -1);
});
ESCAPE_CODE_ACTIONS.put('B', code -> {
moveCursor(code, 0, +1);
});
ESCAPE_CODE_ACTIONS.put('C', code -> {
moveCursor(code, +1, 0);
});
ESCAPE_CODE_ACTIONS.put('D', code -> {
moveCursor(code, -1, 0);
});
ESCAPE_CODE_ACTIONS.put('K', code -> {
BufferState buffer = performer.getBufferState();
switch (parseOutIntValue(code, 0)) {
case 0:
for (int i = buffer.cursorX; i < buffer.sizeX - 1; i++) {
out.write(' ');
}
performer.setCursorPosition(buffer.cursorX, buffer.cursorY);
break;
case 1:
performer.setCursorPosition(0, buffer.cursorY);
for (int i = 0; i < buffer.cursorX; i++) {
out.write(' ');
}
break;
case 2:
for (int i = 0; i < buffer.sizeX - 1; i++) {
out.write(' ');
}
performer.setCursorPosition(buffer.cursorX, buffer.cursorY);
break;
}
out.flush();
});
}
@Override
public void write(int d) throws IOException {
if (inEscapeSequence) {
escape.write(d);
String escapeCandidate = new String(escape.toByteArray(), encoding);
if (Ansi.ANSI_CODE_PATTERN.asPredicate().test(escapeCandidate)) {
//escape sequence:
char key = escapeCandidate.charAt(escapeCandidate.length() - 1);
AnsiCodeHandler handler =
ESCAPE_CODE_ACTIONS.get(key);
if (handler != null) {
handler.handle(escapeCandidate);
} else {
//unknown escape sequence, ignore
}
inEscapeSequence = false;
escape = null;
}
} else if (d == '\033') {
inEscapeSequence = true;
escape = new ByteArrayOutputStream();
escape.write(d);
} else {
out.write(d);
}
}
@Override
public void flush() throws IOException {
out.flush();
}
private void moveCursor(String code, int dx, int dy) throws IOException {
int delta = parseOutIntValue(code, 1);
BufferState buffer = performer.getBufferState();
int tx = buffer.cursorX + dx * delta;
int ty = buffer.cursorY + dy * delta;
tx = Math.max(0, Math.min(buffer.sizeX - 1, tx));
ty = Math.max(0, Math.min(buffer.sizeY - 1, ty));
performer.setCursorPosition(tx, ty);
}
private int parseOutIntValue(String code, int def) {
try {
return Integer.parseInt(code.substring(code.indexOf('[') + 1, code.length() - 1));
} catch (NumberFormatException ex) {
return def;
}
}
interface AnsiCodeHandler {
public void handle(String code) throws IOException;
}
public interface Performer {
public BufferState getBufferState() throws IOException;
public void setCursorPosition(int cursorX, int cursorY) throws IOException;
}
public static class BufferState {
public final int cursorX;
public final int cursorY;
public final int sizeX;
public final int sizeY;
public BufferState(int cursorX, int cursorY, int sizeX, int sizeY) {
this.cursorX = cursorX;
this.cursorY = cursorY;
this.sizeX = sizeX;
this.sizeY = sizeY;
}
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
*
* http://www.opensource.org/licenses/bsd-license.php
*/
package jdk.internal.jline.internal;
import java.util.regex.Pattern;
/**
* Ansi support.
*
* @author <a href="mailto:gnodet@gmail.com">Guillaume Nodet</a>
* @since 2.13
*/
public class Ansi {
public static String stripAnsi(String str) {
if (str == null) return "";
return ANSI_CODE_PATTERN.matcher(str).replaceAll("");
//was:
// try {
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
// AnsiOutputStream aos = new AnsiOutputStream(baos);
// aos.write(str.getBytes());
// aos.close();
// return baos.toString();
// } catch (IOException e) {
// return str;
// }
}
public static final Pattern ANSI_CODE_PATTERN = Pattern.compile("\033\\[[\060-\077]*[\040-\057]*[\100-\176]");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -12,8 +12,10 @@ import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.FileNotFoundException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.util.Map;
import java.util.Properties;
@ -48,9 +50,12 @@ public class Configuration
try {
loadProperties(url, props);
}
catch (FileNotFoundException e) {
// debug here and no stack trace, as this can happen normally if default jline.rc file is missing
Log.debug("Unable to read configuration: ", e.toString());
}
catch (IOException e) {
// debug here instead of warn, as this can happen normally if default jline.rc file is missing
Log.debug("Unable to read configuration from: ", url, e);
Log.warn("Unable to read configuration from: ", url, e);
}
return props;
}
@ -138,6 +143,10 @@ public class Configuration
return getString(name, null);
}
public static boolean getBoolean(final String name) {
return getBoolean(name, false);
}
public static boolean getBoolean(final String name, final boolean defaultValue) {
String value = getString(name);
if (value == null) {
@ -197,25 +206,38 @@ public class Configuration
return getOsName().startsWith("windows");
}
// FIXME: Sort out use of property access of file.encoding in InputStreamReader, consolidate should configuration access here
public static boolean isHpux() {
return getOsName().startsWith("hp");
}
// FIXME: Sort out use of property access of file.encoding in InputStreamReader, should consolidate configuration access here
public static String getFileEncoding() {
return System.getProperty("file.encoding");
}
/**
* Get the default encoding. Will first look at the LC_CTYPE environment variable, then the input.encoding
* Get the default encoding. Will first look at the LC_ALL, LC_CTYPE, and LANG environment variables, then the input.encoding
* system property, then the default charset according to the JVM.
*
* @return The default encoding to use when none is specified.
*/
public static String getEncoding() {
// LC_CTYPE is usually in the form en_US.UTF-8
String envEncoding = extractEncodingFromCtype(System.getenv("LC_CTYPE"));
if (envEncoding != null) {
return envEncoding;
// Check for standard locale environment variables, in order of precedence, first.
// See http://www.gnu.org/s/libc/manual/html_node/Locale-Categories.html
for (String envOption : new String[]{"LC_ALL", "LC_CTYPE", "LANG"}) {
String envEncoding = extractEncodingFromCtype(System.getenv(envOption));
if (envEncoding != null) {
try {
if (Charset.isSupported(envEncoding)) {
return envEncoding;
}
} catch (IllegalCharsetNameException e) {
continue;
}
}
}
return System.getProperty("input.encoding", Charset.defaultCharset().name());
return getString("input.encoding", Charset.defaultCharset().name());
}
/**

View File

@ -0,0 +1,341 @@
/*
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
*
* http://www.opensource.org/licenses/bsd-license.php
*/
package jdk.internal.jline.internal;
import java.io.IOException;
import java.io.Writer;
import java.util.Stack;
/**
* Curses helper methods.
*
* @author <a href="mailto:gnodet@gmail.com">Guillaume Nodet</a>
*/
public class Curses {
private static Object[] sv = new Object[26];
private static Object[] dv = new Object[26];
private static final int IFTE_NONE = 0;
private static final int IFTE_IF = 1;
private static final int IFTE_THEN = 2;
private static final int IFTE_ELSE = 3;
/**
* Print the given terminal capabilities
*
* @param out the output stream
* @param str the capability to output
* @param params optional parameters
* @throws IOException if an error occurs
*/
public static void tputs(Writer out, String str, Object... params) throws IOException {
int index = 0;
int length = str.length();
int ifte = IFTE_NONE;
boolean exec = true;
Stack<Object> stack = new Stack<Object>();
while (index < length) {
char ch = str.charAt(index++);
switch (ch) {
case '\\':
ch = str.charAt(index++);
if (ch >= '0' && ch <= '9') {
throw new UnsupportedOperationException(); // todo
} else {
switch (ch) {
case 'e':
case 'E':
if (exec) {
out.write(27); // escape
}
break;
case 'n':
out.write('\n');
break;
// case 'l':
// rawPrint('\l');
// break;
case 'r':
if (exec) {
out.write('\r');
}
break;
case 't':
if (exec) {
out.write('\t');
}
break;
case 'b':
if (exec) {
out.write('\b');
}
break;
case 'f':
if (exec) {
out.write('\f');
}
break;
case 's':
if (exec) {
out.write(' ');
}
break;
case ':':
case '^':
case '\\':
if (exec) {
out.write(ch);
}
break;
default:
throw new IllegalArgumentException();
}
}
break;
case '^':
ch = str.charAt(index++);
if (exec) {
out.write(ch - '@');
}
break;
case '%':
ch = str.charAt(index++);
switch (ch) {
case '%':
if (exec) {
out.write('%');
}
break;
case 'p':
ch = str.charAt(index++);
if (exec) {
stack.push(params[ch - '1']);
}
break;
case 'P':
ch = str.charAt(index++);
if (ch >= 'a' && ch <= 'z') {
if (exec) {
dv[ch - 'a'] = stack.pop();
}
} else if (ch >= 'A' && ch <= 'Z') {
if (exec) {
sv[ch - 'A'] = stack.pop();
}
} else {
throw new IllegalArgumentException();
}
break;
case 'g':
ch = str.charAt(index++);
if (ch >= 'a' && ch <= 'z') {
if (exec) {
stack.push(dv[ch - 'a']);
}
} else if (ch >= 'A' && ch <= 'Z') {
if (exec) {
stack.push(sv[ch - 'A']);
}
} else {
throw new IllegalArgumentException();
}
break;
case '\'':
ch = str.charAt(index++);
if (exec) {
stack.push((int) ch);
}
ch = str.charAt(index++);
if (ch != '\'') {
throw new IllegalArgumentException();
}
break;
case '{':
int start = index;
while (str.charAt(index++) != '}') ;
if (exec) {
int v = Integer.valueOf(str.substring(start, index - 1));
stack.push(v);
}
break;
case 'l':
if (exec) {
stack.push(stack.pop().toString().length());
}
break;
case '+':
if (exec) {
int v2 = toInteger(stack.pop());
int v1 = toInteger(stack.pop());
stack.push(v1 + v2);
}
break;
case '-':
if (exec) {
int v2 = toInteger(stack.pop());
int v1 = toInteger(stack.pop());
stack.push(v1 - v2);
}
break;
case '*':
if (exec) {
int v2 = toInteger(stack.pop());
int v1 = toInteger(stack.pop());
stack.push(v1 * v2);
}
break;
case '/':
if (exec) {
int v2 = toInteger(stack.pop());
int v1 = toInteger(stack.pop());
stack.push(v1 / v2);
}
break;
case 'm':
if (exec) {
int v2 = toInteger(stack.pop());
int v1 = toInteger(stack.pop());
stack.push(v1 % v2);
}
break;
case '&':
if (exec) {
int v2 = toInteger(stack.pop());
int v1 = toInteger(stack.pop());
stack.push(v1 & v2);
}
break;
case '|':
if (exec) {
int v2 = toInteger(stack.pop());
int v1 = toInteger(stack.pop());
stack.push(v1 | v2);
}
break;
case '^':
if (exec) {
int v2 = toInteger(stack.pop());
int v1 = toInteger(stack.pop());
stack.push(v1 ^ v2);
}
break;
case '=':
if (exec) {
int v2 = toInteger(stack.pop());
int v1 = toInteger(stack.pop());
stack.push(v1 == v2);
}
break;
case '>':
if (exec) {
int v2 = toInteger(stack.pop());
int v1 = toInteger(stack.pop());
stack.push(v1 > v2);
}
break;
case '<':
if (exec) {
int v2 = toInteger(stack.pop());
int v1 = toInteger(stack.pop());
stack.push(v1 < v2);
}
break;
case 'A':
if (exec) {
int v2 = toInteger(stack.pop());
int v1 = toInteger(stack.pop());
stack.push(v1 != 0 && v2 != 0);
}
break;
case '!':
if (exec) {
int v1 = toInteger(stack.pop());
stack.push(v1 == 0);
}
break;
case '~':
if (exec) {
int v1 = toInteger(stack.pop());
stack.push(~v1);
}
break;
case 'O':
if (exec) {
int v2 = toInteger(stack.pop());
int v1 = toInteger(stack.pop());
stack.push(v1 != 0 || v2 != 0);
}
break;
case '?':
if (ifte != IFTE_NONE) {
throw new IllegalArgumentException();
} else {
ifte = IFTE_IF;
}
break;
case 't':
if (ifte != IFTE_IF && ifte != IFTE_ELSE) {
throw new IllegalArgumentException();
} else {
ifte = IFTE_THEN;
}
exec = toInteger(stack.pop()) != 0;
break;
case 'e':
if (ifte != IFTE_THEN) {
throw new IllegalArgumentException();
} else {
ifte = IFTE_ELSE;
}
exec = !exec;
break;
case ';':
if (ifte == IFTE_NONE || ifte == IFTE_IF) {
throw new IllegalArgumentException();
} else {
ifte = IFTE_NONE;
}
exec = true;
break;
case 'i':
if (params.length >= 1) {
params[0] = toInteger(params[0]) + 1;
}
if (params.length >= 2) {
params[1] = toInteger(params[1]) + 1;
}
break;
case 'd':
out.write(Integer.toString(toInteger(stack.pop())));
break;
default:
throw new UnsupportedOperationException();
}
break;
default:
if (exec) {
out.write(ch);
}
break;
}
}
}
private static int toInteger(Object pop) {
if (pop instanceof Number) {
return ((Number) pop).intValue();
} else if (pop instanceof Boolean) {
return (Boolean) pop ? 1 : 0;
} else {
return Integer.valueOf(pop.toString());
}
}
}

View File

@ -0,0 +1,591 @@
/*
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
*
* http://www.opensource.org/licenses/bsd-license.php
*/
package jdk.internal.jline.internal;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Infocmp helper methods.
*
* @author <a href="mailto:gnodet@gmail.com">Guillaume Nodet</a>
*/
public class InfoCmp {
private static final Map<String, String> CAPS = new HashMap<String, String>();
public static String getInfoCmp(
String terminal
) throws IOException, InterruptedException {
String caps = CAPS.get(terminal);
if (caps == null) {
Process p = new ProcessBuilder("infocmp", terminal).start();
caps = TerminalLineSettings.waitAndCapture(p);
CAPS.put(terminal, caps);
}
return caps;
}
public static String getAnsiCaps() {
return ANSI_CAPS;
}
public static void parseInfoCmp(
String capabilities,
Set<String> bools,
Map<String, Integer> ints,
Map<String, String> strings
) {
String[] lines = capabilities.split("\n");
for (int i = 2; i < lines.length; i++) {
Matcher m = Pattern.compile("\\s*(([^,]|\\\\,)+)\\s*[,$]").matcher(lines[i]);
while (m.find()) {
String cap = m.group(1);
if (cap.contains("#")) {
int index = cap.indexOf('#');
String key = cap.substring(0, index);
String val = cap.substring(index + 1);
int iVal;
if (val.startsWith("0x")) {
iVal = Integer.parseInt(val.substring(2), 16);
} else {
iVal = Integer.parseInt(val);
}
for (String name : getNames(key)) {
ints.put(name, iVal);
}
} else if (cap.contains("=")) {
int index = cap.indexOf('=');
String key = cap.substring(0, index);
String val = cap.substring(index + 1);
for (String name : getNames(key)) {
strings.put(name, val);
}
} else {
for (String name : getNames(cap)) {
bools.add(name);
}
}
}
}
}
public static String[] getNames(String name) {
String[] names = NAMES.get(name);
return names != null ? names : new String[] { name };
}
private static final Map<String, String[]> NAMES;
static {
String[][] list = {
{ "auto_left_margin", "bw", "bw" },
{ "auto_right_margin", "am", "am" },
{ "back_color_erase", "bce", "ut" },
{ "can_change", "ccc", "cc" },
{ "ceol_standout_glitch", "xhp", "xs" },
{ "col_addr_glitch", "xhpa", "YA" },
{ "cpi_changes_res", "cpix", "YF" },
{ "cr_cancels_micro_mode", "crxm", "YB" },
{ "dest_tabs_magic_smso", "xt", "xt" },
{ "eat_newline_glitch", "xenl", "xn" },
{ "erase_overstrike", "eo", "eo" },
{ "generic_type", "gn", "gn" },
{ "hard_copy", "hc", "hc" },
{ "hard_cursor", "chts", "HC" },
{ "has_meta_key", "km", "km" },
{ "has_print_wheel", "daisy", "YC" },
{ "has_status_line", "hs", "hs" },
{ "hue_lightness_saturation", "hls", "hl" },
{ "insert_null_glitch", "in", "in" },
{ "lpi_changes_res", "lpix", "YG" },
{ "memory_above", "da", "da" },
{ "memory_below", "db", "db" },
{ "move_insert_mode", "mir", "mi" },
{ "move_standout_mode", "msgr", "ms" },
{ "needs_xon_xoff", "nxon", "nx" },
{ "no_esc_ctlc", "xsb", "xb" },
{ "no_pad_char", "npc", "NP" },
{ "non_dest_scroll_region", "ndscr", "ND" },
{ "non_rev_rmcup", "nrrmc", "NR" },
{ "over_strike", "os", "os" },
{ "prtr_silent", "mc5i", "5i" },
{ "row_addr_glitch", "xvpa", "YD" },
{ "semi_auto_right_margin", "sam", "YE" },
{ "status_line_esc_ok", "eslok", "es" },
{ "tilde_glitch", "hz", "hz" },
{ "transparent_underline", "ul", "ul" },
{ "xon_xoff", "xon", "xo" },
{ "columns", "cols", "co" },
{ "init_tabs", "it", "it" },
{ "label_height", "lh", "lh" },
{ "label_width", "lw", "lw" },
{ "lines", "lines", "li" },
{ "lines_of_memory", "lm", "lm" },
{ "magic_cookie_glitch", "xmc", "sg" },
{ "max_attributes", "ma", "ma" },
{ "max_colors", "colors", "Co" },
{ "max_pairs", "pairs", "pa" },
{ "maximum_windows", "wnum", "MW" },
{ "no_color_video", "ncv", "NC" },
{ "num_labels", "nlab", "Nl" },
{ "padding_baud_rate", "pb", "pb" },
{ "virtual_terminal", "vt", "vt" },
{ "width_status_line", "wsl", "ws" },
{ "bit_image_entwining", "bitwin", "Yo" },
{ "bit_image_type", "bitype", "Yp" },
{ "buffer_capacity", "bufsz", "Ya" },
{ "buttons", "btns", "BT" },
{ "dot_horz_spacing", "spinh", "Yc" },
{ "dot_vert_spacing", "spinv", "Yb" },
{ "max_micro_address", "maddr", "Yd" },
{ "max_micro_jump", "mjump", "Ye" },
{ "micro_col_size", "mcs", "Yf" },
{ "micro_line_size", "mls", "Yg" },
{ "number_of_pins", "npins", "Yh" },
{ "output_res_char", "orc", "Yi" },
{ "output_res_horz_inch", "orhi", "Yk" },
{ "output_res_line", "orl", "Yj" },
{ "output_res_vert_inch", "orvi", "Yl" },
{ "print_rate", "cps", "Ym" },
{ "wide_char_size", "widcs", "Yn" },
{ "acs_chars", "acsc", "ac" },
{ "back_tab", "cbt", "bt" },
{ "bell", "bel", "bl" },
{ "carriage_return", "cr", "cr" },
{ "change_char_pitch", "cpi", "ZA" },
{ "change_line_pitch", "lpi", "ZB" },
{ "change_res_horz", "chr", "ZC" },
{ "change_res_vert", "cvr", "ZD" },
{ "change_scroll_region", "csr", "cs" },
{ "char_padding", "rmp", "rP" },
{ "clear_all_tabs", "tbc", "ct" },
{ "clear_margins", "mgc", "MC" },
{ "clear_screen", "clear", "cl" },
{ "clr_bol", "el1", "cb" },
{ "clr_eol", "el", "ce" },
{ "clr_eos", "ed", "cd" },
{ "column_address", "hpa", "ch" },
{ "command_character", "cmdch", "CC" },
{ "create_window", "cwin", "CW" },
{ "cursor_address", "cup", "cm" },
{ "cursor_down", "cud1", "do" },
{ "cursor_home", "home", "ho" },
{ "cursor_invisible", "civis", "vi" },
{ "cursor_left", "cub1", "le" },
{ "cursor_mem_address", "mrcup", "CM" },
{ "cursor_normal", "cnorm", "ve" },
{ "cursor_right", "cuf1", "nd" },
{ "cursor_to_ll", "ll", "ll" },
{ "cursor_up", "cuu1", "up" },
{ "cursor_visible", "cvvis", "vs" },
{ "define_char", "defc", "ZE" },
{ "delete_character", "dch1", "dc" },
{ "delete_line", "dl1", "dl" },
{ "dial_phone", "dial", "DI" },
{ "dis_status_line", "dsl", "ds" },
{ "display_clock", "dclk", "DK" },
{ "down_half_line", "hd", "hd" },
{ "ena_acs", "enacs", "eA" },
{ "enter_alt_charset_mode", "smacs", "as" },
{ "enter_am_mode", "smam", "SA" },
{ "enter_blink_mode", "blink", "mb" },
{ "enter_bold_mode", "bold", "md" },
{ "enter_ca_mode", "smcup", "ti" },
{ "enter_delete_mode", "smdc", "dm" },
{ "enter_dim_mode", "dim", "mh" },
{ "enter_doublewide_mode", "swidm", "ZF" },
{ "enter_draft_quality", "sdrfq", "ZG" },
{ "enter_insert_mode", "smir", "im" },
{ "enter_italics_mode", "sitm", "ZH" },
{ "enter_leftward_mode", "slm", "ZI" },
{ "enter_micro_mode", "smicm", "ZJ" },
{ "enter_near_letter_quality", "snlq", "ZK" },
{ "enter_normal_quality", "snrmq", "ZL" },
{ "enter_protected_mode", "prot", "mp" },
{ "enter_reverse_mode", "rev", "mr" },
{ "enter_secure_mode", "invis", "mk" },
{ "enter_shadow_mode", "sshm", "ZM" },
{ "enter_standout_mode", "smso", "so" },
{ "enter_subscript_mode", "ssubm", "ZN" },
{ "enter_superscript_mode", "ssupm", "ZO" },
{ "enter_underline_mode", "smul", "us" },
{ "enter_upward_mode", "sum", "ZP" },
{ "enter_xon_mode", "smxon", "SX" },
{ "erase_chars", "ech", "ec" },
{ "exit_alt_charset_mode", "rmacs", "ae" },
{ "exit_am_mode", "rmam", "RA" },
{ "exit_attribute_mode", "sgr0", "me" },
{ "exit_ca_mode", "rmcup", "te" },
{ "exit_delete_mode", "rmdc", "ed" },
{ "exit_doublewide_mode", "rwidm", "ZQ" },
{ "exit_insert_mode", "rmir", "ei" },
{ "exit_italics_mode", "ritm", "ZR" },
{ "exit_leftward_mode", "rlm", "ZS" },
{ "exit_micro_mode", "rmicm", "ZT" },
{ "exit_shadow_mode", "rshm", "ZU" },
{ "exit_standout_mode", "rmso", "se" },
{ "exit_subscript_mode", "rsubm", "ZV" },
{ "exit_superscript_mode", "rsupm", "ZW" },
{ "exit_underline_mode", "rmul", "ue" },
{ "exit_upward_mode", "rum", "ZX" },
{ "exit_xon_mode", "rmxon", "RX" },
{ "fixed_pause", "pause", "PA" },
{ "flash_hook", "hook", "fh" },
{ "flash_screen", "flash", "vb" },
{ "form_feed", "ff", "ff" },
{ "from_status_line", "fsl", "fs" },
{ "goto_window", "wingo", "WG" },
{ "hangup", "hup", "HU" },
{ "init_1string", "is1", "i1" },
{ "init_2string", "is2", "is" },
{ "init_3string", "is3", "i3" },
{ "init_file", "if", "if" },
{ "init_prog", "iprog", "iP" },
{ "initialize_color", "initc", "Ic" },
{ "initialize_pair", "initp", "Ip" },
{ "insert_character", "ich1", "ic" },
{ "insert_line", "il1", "al" },
{ "insert_padding", "ip", "ip" },
{ "key_a1", "ka1", "K1" },
{ "key_a3", "ka3", "K3" },
{ "key_b2", "kb2", "K2" },
{ "key_backspace", "kbs", "kb" },
{ "key_beg", "kbeg", "@1" },
{ "key_btab", "kcbt", "kB" },
{ "key_c1", "kc1", "K4" },
{ "key_c3", "kc3", "K5" },
{ "key_cancel", "kcan", "@2" },
{ "key_catab", "ktbc", "ka" },
{ "key_clear", "kclr", "kC" },
{ "key_close", "kclo", "@3" },
{ "key_command", "kcmd", "@4" },
{ "key_copy", "kcpy", "@5" },
{ "key_create", "kcrt", "@6" },
{ "key_ctab", "kctab", "kt" },
{ "key_dc", "kdch1", "kD" },
{ "key_dl", "kdl1", "kL" },
{ "key_down", "kcud1", "kd" },
{ "key_eic", "krmir", "kM" },
{ "key_end", "kend", "@7" },
{ "key_enter", "kent", "@8" },
{ "key_eol", "kel", "kE" },
{ "key_eos", "ked", "kS" },
{ "key_exit", "kext", "@9" },
{ "key_f0", "kf0", "k0" },
{ "key_f1", "kf1", "k1" },
{ "key_f10", "kf10", "k;" },
{ "key_f11", "kf11", "F1" },
{ "key_f12", "kf12", "F2" },
{ "key_f13", "kf13", "F3" },
{ "key_f14", "kf14", "F4" },
{ "key_f15", "kf15", "F5" },
{ "key_f16", "kf16", "F6" },
{ "key_f17", "kf17", "F7" },
{ "key_f18", "kf18", "F8" },
{ "key_f19", "kf19", "F9" },
{ "key_f2", "kf2", "k2" },
{ "key_f20", "kf20", "FA" },
{ "key_f21", "kf21", "FB" },
{ "key_f22", "kf22", "FC" },
{ "key_f23", "kf23", "FD" },
{ "key_f24", "kf24", "FE" },
{ "key_f25", "kf25", "FF" },
{ "key_f26", "kf26", "FG" },
{ "key_f27", "kf27", "FH" },
{ "key_f28", "kf28", "FI" },
{ "key_f29", "kf29", "FJ" },
{ "key_f3", "kf3", "k3" },
{ "key_f30", "kf30", "FK" },
{ "key_f31", "kf31", "FL" },
{ "key_f32", "kf32", "FM" },
{ "key_f33", "kf33", "FN" },
{ "key_f34", "kf34", "FO" },
{ "key_f35", "kf35", "FP" },
{ "key_f36", "kf36", "FQ" },
{ "key_f37", "kf37", "FR" },
{ "key_f38", "kf38", "FS" },
{ "key_f39", "kf39", "FT" },
{ "key_f4", "kf4", "k4" },
{ "key_f40", "kf40", "FU" },
{ "key_f41", "kf41", "FV" },
{ "key_f42", "kf42", "FW" },
{ "key_f43", "kf43", "FX" },
{ "key_f44", "kf44", "FY" },
{ "key_f45", "kf45", "FZ" },
{ "key_f46", "kf46", "Fa" },
{ "key_f47", "kf47", "Fb" },
{ "key_f48", "kf48", "Fc" },
{ "key_f49", "kf49", "Fd" },
{ "key_f5", "kf5", "k5" },
{ "key_f50", "kf50", "Fe" },
{ "key_f51", "kf51", "Ff" },
{ "key_f52", "kf52", "Fg" },
{ "key_f53", "kf53", "Fh" },
{ "key_f54", "kf54", "Fi" },
{ "key_f55", "kf55", "Fj" },
{ "key_f56", "kf56", "Fk" },
{ "key_f57", "kf57", "Fl" },
{ "key_f58", "kf58", "Fm" },
{ "key_f59", "kf59", "Fn" },
{ "key_f6", "kf6", "k6" },
{ "key_f60", "kf60", "Fo" },
{ "key_f61", "kf61", "Fp" },
{ "key_f62", "kf62", "Fq" },
{ "key_f63", "kf63", "Fr" },
{ "key_f7", "kf7", "k7" },
{ "key_f8", "kf8", "k8" },
{ "key_f9", "kf9", "k9" },
{ "key_find", "kfnd", "@0" },
{ "key_help", "khlp", "%1" },
{ "key_home", "khome", "kh" },
{ "key_ic", "kich1", "kI" },
{ "key_il", "kil1", "kA" },
{ "key_left", "kcub1", "kl" },
{ "key_ll", "kll", "kH" },
{ "key_mark", "kmrk", "%2" },
{ "key_message", "kmsg", "%3" },
{ "key_move", "kmov", "%4" },
{ "key_next", "knxt", "%5" },
{ "key_npage", "knp", "kN" },
{ "key_open", "kopn", "%6" },
{ "key_options", "kopt", "%7" },
{ "key_ppage", "kpp", "kP" },
{ "key_previous", "kprv", "%8" },
{ "key_print", "kprt", "%9" },
{ "key_redo", "krdo", "%0" },
{ "key_reference", "kref", "&1" },
{ "key_refresh", "krfr", "&2" },
{ "key_replace", "krpl", "&3" },
{ "key_restart", "krst", "&4" },
{ "key_resume", "kres", "&5" },
{ "key_right", "kcuf1", "kr" },
{ "key_save", "ksav", "&6" },
{ "key_sbeg", "kBEG", "&9" },
{ "key_scancel", "kCAN", "&0" },
{ "key_scommand", "kCMD", "*1" },
{ "key_scopy", "kCPY", "*2" },
{ "key_screate", "kCRT", "*3" },
{ "key_sdc", "kDC", "*4" },
{ "key_sdl", "kDL", "*5" },
{ "key_select", "kslt", "*6" },
{ "key_send", "kEND", "*7" },
{ "key_seol", "kEOL", "*8" },
{ "key_sexit", "kEXT", "*9" },
{ "key_sf", "kind", "kF" },
{ "key_sfind", "kFND", "*0" },
{ "key_shelp", "kHLP", "#1" },
{ "key_shome", "kHOM", "#2" },
{ "key_sic", "kIC", "#3" },
{ "key_sleft", "kLFT", "#4" },
{ "key_smessage", "kMSG", "%a" },
{ "key_smove", "kMOV", "%b" },
{ "key_snext", "kNXT", "%c" },
{ "key_soptions", "kOPT", "%d" },
{ "key_sprevious", "kPRV", "%e" },
{ "key_sprint", "kPRT", "%f" },
{ "key_sr", "kri", "kR" },
{ "key_sredo", "kRDO", "%g" },
{ "key_sreplace", "kRPL", "%h" },
{ "key_sright", "kRIT", "%i" },
{ "key_srsume", "kRES", "%j" },
{ "key_ssave", "kSAV", "!1" },
{ "key_ssuspend", "kSPD", "!2" },
{ "key_stab", "khts", "kT" },
{ "key_sundo", "kUND", "!3" },
{ "key_suspend", "kspd", "&7" },
{ "key_undo", "kund", "&8" },
{ "key_up", "kcuu1", "ku" },
{ "keypad_local", "rmkx", "ke" },
{ "keypad_xmit", "smkx", "ks" },
{ "lab_f0", "lf0", "l0" },
{ "lab_f1", "lf1", "l1" },
{ "lab_f10", "lf10", "la" },
{ "lab_f2", "lf2", "l2" },
{ "lab_f3", "lf3", "l3" },
{ "lab_f4", "lf4", "l4" },
{ "lab_f5", "lf5", "l5" },
{ "lab_f6", "lf6", "l6" },
{ "lab_f7", "lf7", "l7" },
{ "lab_f8", "lf8", "l8" },
{ "lab_f9", "lf9", "l9" },
{ "label_format", "fln", "Lf" },
{ "label_off", "rmln", "LF" },
{ "label_on", "smln", "LO" },
{ "meta_off", "rmm", "mo" },
{ "meta_on", "smm", "mm" },
{ "micro_column_address", "mhpa", "ZY" },
{ "micro_down", "mcud1", "ZZ" },
{ "micro_left", "mcub1", "Za" },
{ "micro_right", "mcuf1", "Zb" },
{ "micro_row_address", "mvpa", "Zc" },
{ "micro_up", "mcuu1", "Zd" },
{ "newline", "nel", "nw" },
{ "order_of_pins", "porder", "Ze" },
{ "orig_colors", "oc", "oc" },
{ "orig_pair", "op", "op" },
{ "pad_char", "pad", "pc" },
{ "parm_dch", "dch", "DC" },
{ "parm_delete_line", "dl", "DL" },
{ "parm_down_cursor", "cud", "DO" },
{ "parm_down_micro", "mcud", "Zf" },
{ "parm_ich", "ich", "IC" },
{ "parm_index", "indn", "SF" },
{ "parm_insert_line", "il", "AL" },
{ "parm_left_cursor", "cub", "LE" },
{ "parm_left_micro", "mcub", "Zg" },
{ "parm_right_cursor", "cuf", "RI" },
{ "parm_right_micro", "mcuf", "Zh" },
{ "parm_rindex", "rin", "SR" },
{ "parm_up_cursor", "cuu", "UP" },
{ "parm_up_micro", "mcuu", "Zi" },
{ "pkey_key", "pfkey", "pk" },
{ "pkey_local", "pfloc", "pl" },
{ "pkey_xmit", "pfx", "px" },
{ "plab_norm", "pln", "pn" },
{ "print_screen", "mc0", "ps" },
{ "prtr_non", "mc5p", "pO" },
{ "prtr_off", "mc4", "pf" },
{ "prtr_on", "mc5", "po" },
{ "pulse", "pulse", "PU" },
{ "quick_dial", "qdial", "QD" },
{ "remove_clock", "rmclk", "RC" },
{ "repeat_char", "rep", "rp" },
{ "req_for_input", "rfi", "RF" },
{ "reset_1string", "rs1", "r1" },
{ "reset_2string", "rs2", "r2" },
{ "reset_3string", "rs3", "r3" },
{ "reset_file", "rf", "rf" },
{ "restore_cursor", "rc", "rc" },
{ "row_address", "vpa", "cv" },
{ "save_cursor", "sc", "sc" },
{ "scroll_forward", "ind", "sf" },
{ "scroll_reverse", "ri", "sr" },
{ "select_char_set", "scs", "Zj" },
{ "set_attributes", "sgr", "sa" },
{ "set_background", "setb", "Sb" },
{ "set_bottom_margin", "smgb", "Zk" },
{ "set_bottom_margin_parm", "smgbp", "Zl" },
{ "set_clock", "sclk", "SC" },
{ "set_color_pair", "scp", "sp" },
{ "set_foreground", "setf", "Sf" },
{ "set_left_margin", "smgl", "ML" },
{ "set_left_margin_parm", "smglp", "Zm" },
{ "set_right_margin", "smgr", "MR" },
{ "set_right_margin_parm", "smgrp", "Zn" },
{ "set_tab", "hts", "st" },
{ "set_top_margin", "smgt", "Zo" },
{ "set_top_margin_parm", "smgtp", "Zp" },
{ "set_window", "wind", "wi" },
{ "start_bit_image", "sbim", "Zq" },
{ "start_char_set_def", "scsd", "Zr" },
{ "stop_bit_image", "rbim", "Zs" },
{ "stop_char_set_def", "rcsd", "Zt" },
{ "subscript_characters", "subcs", "Zu" },
{ "superscript_characters", "supcs", "Zv" },
{ "tab", "ht", "ta" },
{ "these_cause_cr", "docr", "Zw" },
{ "to_status_line", "tsl", "ts" },
{ "tone", "tone", "TO" },
{ "underline_char", "uc", "uc" },
{ "up_half_line", "hu", "hu" },
{ "user0", "u0", "u0" },
{ "user1", "u1", "u1" },
{ "user2", "u2", "u2" },
{ "user3", "u3", "u3" },
{ "user4", "u4", "u4" },
{ "user5", "u5", "u5" },
{ "user6", "u6", "u6" },
{ "user7", "u7", "u7" },
{ "user8", "u8", "u8" },
{ "user9", "u9", "u9" },
{ "wait_tone", "wait", "WA" },
{ "xoff_character", "xoffc", "XF" },
{ "xon_character", "xonc", "XN" },
{ "zero_motion", "zerom", "Zx" },
{ "alt_scancode_esc", "scesa", "S8" },
{ "bit_image_carriage_return", "bicr", "Yv" },
{ "bit_image_newline", "binel", "Zz" },
{ "bit_image_repeat", "birep", "Xy" },
{ "char_set_names", "csnm", "Zy" },
{ "code_set_init", "csin", "ci" },
{ "color_names", "colornm", "Yw" },
{ "define_bit_image_region", "defbi", "Yx" },
{ "device_type", "devt", "dv" },
{ "display_pc_char", "dispc", "S1" },
{ "end_bit_image_region", "endbi", "Yy" },
{ "enter_pc_charset_mode", "smpch", "S2" },
{ "enter_scancode_mode", "smsc", "S4" },
{ "exit_pc_charset_mode", "rmpch", "S3" },
{ "exit_scancode_mode", "rmsc", "S5" },
{ "get_mouse", "getm", "Gm" },
{ "key_mouse", "kmous", "Km" },
{ "mouse_info", "minfo", "Mi" },
{ "pc_term_options", "pctrm", "S6" },
{ "pkey_plab", "pfxl", "xl" },
{ "req_mouse_pos", "reqmp", "RQ" },
{ "scancode_escape", "scesc", "S7" },
{ "set0_des_seq", "s0ds", "s0" },
{ "set1_des_seq", "s1ds", "s1" },
{ "set2_des_seq", "s2ds", "s2" },
{ "set3_des_seq", "s3ds", "s3" },
{ "set_a_background", "setab", "AB" },
{ "set_a_foreground", "setaf", "AF" },
{ "set_color_band", "setcolor", "Yz" },
{ "set_lr_margin", "smglr", "ML" },
{ "set_page_length", "slines", "YZ" },
{ "set_tb_margin", "smgtb", "MT" },
{ "enter_horizontal_hl_mode", "ehhlm", "Xh" },
{ "enter_left_hl_mode", "elhlm", "Xl" },
{ "enter_low_hl_mode", "elohlm", "Xo" },
{ "enter_right_hl_mode", "erhlm", "Xr" },
{ "enter_top_hl_mode", "ethlm", "Xt" },
{ "enter_vertical_hl_mode", "evhlm", "Xv" },
{ "set_a_attributes", "sgr1", "sA" },
{ "set_pglen_inch", "slength", "sL" }
};
Map<String, String[]> map = new HashMap<String, String[]>();
for (String[] names : list) {
for (String name : names) {
map.put(name, names);
}
}
NAMES = Collections.unmodifiableMap(map);
}
private static String ANSI_CAPS =
"#\tReconstructed via infocmp from file: /usr/share/terminfo/61/ansi\n" +
"ansi|ansi/pc-term compatible with color,\n" +
"\tam, mc5i, mir, msgr,\n" +
"\tcolors#8, cols#80, it#8, lines#24, ncv#3, pairs#64,\n" +
"\tacsc=+\\020\\,\\021-\\030.^Y0\\333`\\004a\\261f\\370g\\361h\\260j\\331k\\277l\\332m\\300n\\305o~p\\304q\\304r\\304s_t\\303u\\264v\\301w\\302x\\263y\\363z\\362{\\343|\\330}\\234~\\376,\n" +
"\tbel=^G, blink=\\E[5m, bold=\\E[1m, cbt=\\E[Z, clear=\\E[H\\E[J,\n" +
"\tcr=^M, cub=\\E[%p1%dD, cub1=\\E[D, cud=\\E[%p1%dB, cud1=\\E[B,\n" +
"\tcuf=\\E[%p1%dC, cuf1=\\E[C, cup=\\E[%i%p1%d;%p2%dH,\n" +
"\tcuu=\\E[%p1%dA, cuu1=\\E[A, dch=\\E[%p1%dP, dch1=\\E[P,\n" +
"\tdl=\\E[%p1%dM, dl1=\\E[M, ech=\\E[%p1%dX, ed=\\E[J, el=\\E[K,\n" +
"\tel1=\\E[1K, home=\\E[H, hpa=\\E[%i%p1%dG, ht=\\E[I, hts=\\EH,\n" +
"\tich=\\E[%p1%d@, il=\\E[%p1%dL, il1=\\E[L, ind=^J,\n" +
"\tindn=\\E[%p1%dS, invis=\\E[8m, kbs=^H, kcbt=\\E[Z, kcub1=\\E[D,\n" +
"\tkcud1=\\E[B, kcuf1=\\E[C, kcuu1=\\E[A, khome=\\E[H, kich1=\\E[L,\n" +
"\tmc4=\\E[4i, mc5=\\E[5i, nel=\\r\\E[S, op=\\E[39;49m,\n" +
"\trep=%p1%c\\E[%p2%{1}%-%db, rev=\\E[7m, rin=\\E[%p1%dT,\n" +
"\trmacs=\\E[10m, rmpch=\\E[10m, rmso=\\E[m, rmul=\\E[m,\n" +
"\ts0ds=\\E(B, s1ds=\\E)B, s2ds=\\E*B, s3ds=\\E+B,\n" +
"\tsetab=\\E[4%p1%dm, setaf=\\E[3%p1%dm,\n" +
"\tsgr=\\E[0;10%?%p1%t;7%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;%?%p6%t;1%;%?%p7%t;8%;%?%p9%t;11%;m,\n" +
"\tsgr0=\\E[0;10m, smacs=\\E[11m, smpch=\\E[11m, smso=\\E[7m,\n" +
"\tsmul=\\E[4m, tbc=\\E[2g, u6=\\E[%i%d;%dR, u7=\\E[6n,\n" +
"\tu8=\\E[?%[;0123456789]c, u9=\\E[c, vpa=\\E[%i%p1%dd,";
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -49,8 +49,6 @@ public class InputStreamReader extends Reader {
private boolean endOfInput = false;
String encoding;
CharsetDecoder decoder;
ByteBuffer bytes = ByteBuffer.allocate(BUFFER_SIZE);
@ -67,9 +65,7 @@ public class InputStreamReader extends Reader {
public InputStreamReader(InputStream in) {
super(in);
this.in = in;
// FIXME: This should probably use Configuration.getFileEncoding()
encoding = System.getProperty("file.encoding", "ISO8859_1"); //$NON-NLS-1$//$NON-NLS-2$
decoder = Charset.forName(encoding).newDecoder().onMalformedInput(
decoder = Charset.defaultCharset().newDecoder().onMalformedInput(
CodingErrorAction.REPLACE).onUnmappableCharacter(
CodingErrorAction.REPLACE);
bytes.limit(0);
@ -172,7 +168,7 @@ public class InputStreamReader extends Reader {
if (!isOpen()) {
return null;
}
return encoding;
return decoder.charset().name();
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -8,7 +8,10 @@
*/
package jdk.internal.jline.internal;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
//import java.util.logging.LogRecord;
//import java.util.logging.Logger;
import static jdk.internal.jline.internal.Preconditions.checkNotNull;
@ -16,6 +19,7 @@ import static jdk.internal.jline.internal.Preconditions.checkNotNull;
* Internal logger.
*
* @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
* @author <a href="mailto:gnodet@gmail.com">Guillaume Nodet</a>
* @since 2.0
*/
public final class Log
@ -31,14 +35,14 @@ public final class Log
ERROR
}
@SuppressWarnings({"StringConcatenation"})
public static final boolean TRACE = Boolean.getBoolean(Log.class.getName() + ".trace");
public static final boolean TRACE = Configuration.getBoolean(Log.class.getName() + ".trace");
@SuppressWarnings({"StringConcatenation"})
public static final boolean DEBUG = TRACE || Boolean.getBoolean(Log.class.getName() + ".debug");
public static final boolean DEBUG = TRACE || Configuration.getBoolean(Log.class.getName() + ".debug");
private static PrintStream output = System.err;
private static boolean useJul = Configuration.getBoolean("jline.log.jul");
public static PrintStream getOutput() {
return output;
}
@ -71,6 +75,10 @@ public final class Log
@TestAccessible
static void log(final Level level, final Object... messages) {
if (useJul) {
logWithJul(level, messages);
return;
}
//noinspection SynchronizeOnNonFinalField
synchronized (output) {
output.format("[%s] ", level);
@ -91,6 +99,43 @@ public final class Log
}
}
static void logWithJul(Level level, Object... messages) {
// Logger logger = Logger.getLogger("jline");
// Throwable cause = null;
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
// PrintStream ps = new PrintStream(baos);
// for (int i = 0; i < messages.length; i++) {
// // Special handling for the last message if its a throwable, render its stack on the next line
// if (i + 1 == messages.length && messages[i] instanceof Throwable) {
// cause = (Throwable) messages[i];
// }
// else {
// render(ps, messages[i]);
// }
// }
// ps.close();
// LogRecord r = new LogRecord(toJulLevel(level), baos.toString());
// r.setThrown(cause);
// logger.log(r);
}
// private static java.util.logging.Level toJulLevel(Level level) {
// switch (level) {
// case TRACE:
// return java.util.logging.Level.FINEST;
// case DEBUG:
// return java.util.logging.Level.FINE;
// case INFO:
// return java.util.logging.Level.INFO;
// case WARN:
// return java.util.logging.Level.WARNING;
// case ERROR:
// return java.util.logging.Level.SEVERE;
// default:
// throw new IllegalArgumentException();
// }
// }
public static void trace(final Object... messages) {
if (TRACE) {
log(Level.TRACE, messages);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -111,7 +111,6 @@ public class NonBlockingInputStream
* @param timeout The amount of time to wait, 0 == forever
* @return -1 on eof, -2 if the timeout expired with no available input
* or the character that was read (without consuming it).
* @throws IOException
*/
public int peek(long timeout) throws IOException {
if (!nonBlockingEnabled || isShutdown) {
@ -127,7 +126,6 @@ public class NonBlockingInputStream
* @param timeout The amount of time to wait for the character
* @return The character read, -1 if EOF is reached, or -2 if the
* read timed out.
* @throws IOException
*/
public int read(long timeout) throws IOException {
if (!nonBlockingEnabled || isShutdown) {
@ -143,7 +141,6 @@ public class NonBlockingInputStream
* @param timeout The amount of time to wait for the character
* @return The character read, -1 if EOF is reached, or -2 if the
* read timed out.
* @throws IOException
*/
private synchronized int read(long timeout, boolean isPeek) throws IOException {
/*
@ -177,7 +174,7 @@ public class NonBlockingInputStream
notify();
}
boolean isInfinite = (timeout <= 0L);
boolean isInfinite = timeout <= 0L;
/*
* So the thread is currently doing the reading for us. So

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
@ -13,7 +13,10 @@ import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -26,6 +29,7 @@ import static jdk.internal.jline.internal.Preconditions.checkNotNull;
* @author <a href="mailto:dwkemp@gmail.com">Dale Kemp</a>
* @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
* @author <a href="mailto:jbonofre@apache.org">Jean-Baptiste Onofr\u00E9</a>
* @author <a href="mailto:gnodet@gmail.com">Guillaume Nodet</a>
* @since 2.0
*/
public final class TerminalLineSettings
@ -38,21 +42,72 @@ public final class TerminalLineSettings
public static final String DEFAULT_SH = "sh";
private static final String UNDEFINED;
public static final String DEFAULT_TTY = "/dev/tty";
private static final boolean SUPPORTS_REDIRECT;
private static final Object REDIRECT_INHERIT;
private static final Method REDIRECT_INPUT_METHOD;
private static final Map<String, TerminalLineSettings> SETTINGS = new HashMap<String, TerminalLineSettings>();
static {
if (Configuration.isHpux()) {
UNDEFINED = "^-";
} else {
UNDEFINED = "undef";
}
boolean supportsRedirect;
Object redirectInherit = null;
Method redirectInputMethod = null;
try {
Class<?> redirect = Class.forName("java.lang.ProcessBuilder$Redirect");
redirectInherit = redirect.getField("INHERIT").get(null);
redirectInputMethod = ProcessBuilder.class.getMethod("redirectInput", redirect);
supportsRedirect = System.class.getMethod("console").invoke(null) != null;
} catch (Throwable t) {
supportsRedirect = false;
}
SUPPORTS_REDIRECT = supportsRedirect;
REDIRECT_INHERIT = redirectInherit;
REDIRECT_INPUT_METHOD = redirectInputMethod;
}
private String sttyCommand;
private String shCommand;
private String ttyDevice;
private String config;
private String initialConfig;
private long configLastFetched;
private boolean useRedirect;
@Deprecated
public TerminalLineSettings() throws IOException, InterruptedException {
sttyCommand = Configuration.getString(JLINE_STTY, DEFAULT_STTY);
shCommand = Configuration.getString(JLINE_SH, DEFAULT_SH);
initialConfig = get("-g").trim();
config = get("-a");
configLastFetched = System.currentTimeMillis();
this(DEFAULT_TTY);
}
@Deprecated
public TerminalLineSettings(String ttyDevice) throws IOException, InterruptedException {
this(ttyDevice, false);
}
private TerminalLineSettings(String ttyDevice, boolean unused) throws IOException, InterruptedException {
checkNotNull(ttyDevice);
this.sttyCommand = Configuration.getString(JLINE_STTY, DEFAULT_STTY);
this.shCommand = Configuration.getString(JLINE_SH, DEFAULT_SH);
this.ttyDevice = ttyDevice;
this.useRedirect = SUPPORTS_REDIRECT && DEFAULT_TTY.equals(ttyDevice);
this.initialConfig = get("-g").trim();
this.config = get("-a");
this.configLastFetched = System.currentTimeMillis();
Log.debug("Config: ", config);
@ -62,6 +117,19 @@ public final class TerminalLineSettings
}
}
public static synchronized TerminalLineSettings getSettings(String device) throws IOException, InterruptedException {
TerminalLineSettings settings = SETTINGS.get(device);
if (settings == null) {
settings = new TerminalLineSettings(device, false);
SETTINGS.put(device, settings);
}
return settings;
}
public String getTtyDevice() {
return ttyDevice;
}
public String getConfig() {
return config;
}
@ -71,13 +139,25 @@ public final class TerminalLineSettings
}
public String get(final String args) throws IOException, InterruptedException {
checkNotNull(args);
return stty(args);
}
public void set(final String args) throws IOException, InterruptedException {
checkNotNull(args);
stty(args.split(" "));
}
public void set(final String... args) throws IOException, InterruptedException {
checkNotNull(args);
stty(args);
}
public void undef(final String name) throws IOException, InterruptedException {
checkNotNull(name);
stty(name, UNDEFINED);
}
/**
* <p>
* Get the value of a stty property, including the management of a cache.
@ -88,6 +168,21 @@ public final class TerminalLineSettings
*/
public int getProperty(String name) {
checkNotNull(name);
if (!fetchConfig(name)) {
return -1;
}
return getProperty(name, config);
}
public String getPropertyAsString(String name) {
checkNotNull(name);
if (!fetchConfig(name)) {
return null;
}
return getPropertyAsString(name, config);
}
private boolean fetchConfig(String name) {
long currentTime = System.currentTimeMillis();
try {
// tty properties are cached so we don't have to worry too much about getting term width/height
@ -100,7 +195,7 @@ public final class TerminalLineSettings
}
Log.debug("Failed to query stty ", name, "\n", e);
if (config == null) {
return -1;
return false;
}
}
@ -108,8 +203,7 @@ public final class TerminalLineSettings
if (currentTime - configLastFetched > 1000) {
configLastFetched = currentTime;
}
return getProperty(name, config);
return true;
}
/**
@ -121,7 +215,7 @@ public final class TerminalLineSettings
* @param stty string resulting of stty -a execution.
* @return value of the given property.
*/
protected static int getProperty(String name, String stty) {
protected static String getPropertyAsString(String name, String stty) {
// try the first kind of regex
Pattern pattern = Pattern.compile(name + "\\s+=\\s+(.*?)[;\\n\\r]");
Matcher matcher = pattern.matcher(stty);
@ -134,11 +228,16 @@ public final class TerminalLineSettings
pattern = Pattern.compile("(\\S*)\\s+" + name);
matcher = pattern.matcher(stty);
if (!matcher.find()) {
return -1;
return null;
}
}
}
return parseControlChar(matcher.group(1));
return matcher.group(1);
}
protected static int getProperty(String name, String stty) {
String str = getPropertyAsString(name, stty);
return str != null ? parseControlChar(str) : -1;
}
private static int parseControlChar(String str) {
@ -176,25 +275,53 @@ public final class TerminalLineSettings
}
}
private String stty(final String args) throws IOException, InterruptedException {
checkNotNull(args);
return exec(String.format("%s %s < /dev/tty", sttyCommand, args));
}
private String exec(final String cmd) throws IOException, InterruptedException {
checkNotNull(cmd);
return exec(shCommand, "-c", cmd);
private String stty(final String... args) throws IOException, InterruptedException {
String[] s = new String[args.length + 1];
s[0] = sttyCommand;
System.arraycopy(args, 0, s, 1, args.length);
return exec(s);
}
private String exec(final String... cmd) throws IOException, InterruptedException {
checkNotNull(cmd);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
Log.trace("Running: ", cmd);
Process p = Runtime.getRuntime().exec(cmd);
Process p = null;
if (useRedirect) {
try {
p = inheritInput(new ProcessBuilder(cmd)).start();
} catch (Throwable t) {
useRedirect = false;
}
}
if (p == null) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < cmd.length; i++) {
if (i > 0) {
sb.append(' ');
}
sb.append(cmd[i]);
}
sb.append(" < ");
sb.append(ttyDevice);
p = new ProcessBuilder(shCommand, "-c", sb.toString()).start();
}
String result = waitAndCapture(p);
Log.trace("Result: ", result);
return result;
}
private static ProcessBuilder inheritInput(ProcessBuilder pb) throws Exception {
REDIRECT_INPUT_METHOD.invoke(pb, REDIRECT_INHERIT);
return pb;
}
public static String waitAndCapture(Process p) throws IOException, InterruptedException {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
InputStream in = null;
InputStream err = null;
OutputStream out = null;
@ -215,20 +342,17 @@ public final class TerminalLineSettings
close(in, out, err);
}
String result = bout.toString();
Log.trace("Result: ", result);
return result;
return bout.toString();
}
private static void close(final Closeable... closeables) {
for (Closeable c : closeables) {
try {
c.close();
}
catch (Exception e) {
// Ignore
if (c != null) {
try {
c.close();
} catch (Exception e) {
// Ignore
}
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2012, the original author or authors.
* Copyright (c) 2002-2016, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.

View File

@ -1,11 +1,13 @@
## JLine v2.12.1
## JLine v2.14.6
### JLine License
<pre>
Copyright (c) 2002-2006, Marc Prud'hommeaux <mwp1@cornell.edu>
Copyright (c) 2002-2016, the original author or authors.
All rights reserved.
http://www.opensource.org/licenses/bsd-license.php
Redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following
conditions are met:

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -34,6 +34,8 @@
static jclass recordClass;
static jmethodID recordConstructor;
static jclass bufferStateClass;
static jmethodID bufferStateConstructor;
JNIEXPORT void JNICALL Java_jdk_internal_jline_WindowsTerminal_initIDs
(JNIEnv *env, jclass) {
@ -43,6 +45,12 @@ JNIEXPORT void JNICALL Java_jdk_internal_jline_WindowsTerminal_initIDs
CHECK_NULL(recordClass);
recordConstructor = env->GetMethodID(cls, "<init>", "(ZCIII)V");
CHECK_NULL(recordConstructor);
cls = env->FindClass("jdk/internal/jline/extra/AnsiInterpretingOutputStream$BufferState");
CHECK_NULL(cls);
bufferStateClass = (jclass) env->NewGlobalRef(cls);
CHECK_NULL(bufferStateClass);
bufferStateConstructor = env->GetMethodID(cls, "<init>", "(IIII)V");
CHECK_NULL(bufferStateConstructor);
}
JNIEXPORT jint JNICALL Java_jdk_internal_jline_WindowsTerminal_getConsoleMode
@ -81,8 +89,6 @@ JNIEXPORT jobject JNICALL Java_jdk_internal_jline_WindowsTerminal_readKeyEvent
return NULL;
}
if (record.EventType == KEY_EVENT) {
jclass clazz = env->FindClass("jdk/internal/jline/WindowsTerminal$KEY_EVENT_RECORD");
jmethodID constr = env->GetMethodID(clazz, "<init>", "(ZCIII)V");
return env->NewObject(recordClass,
recordConstructor,
record.Event.KeyEvent.bKeyDown,
@ -125,3 +131,31 @@ JNIEXPORT jint JNICALL Java_jdk_internal_jline_WindowsTerminal_getWindowsTermina
}
return info.srWindow.Bottom - info.srWindow.Top + 1;
}
JNIEXPORT jobject JNICALL Java_jdk_internal_jline_WindowsTerminal_getBufferState
(JNIEnv *env, jobject) {
HANDLE hStdOut;
if ((hStdOut = GetStdHandle(STD_OUTPUT_HANDLE)) == INVALID_HANDLE_VALUE) {
return NULL;
}
CONSOLE_SCREEN_BUFFER_INFO info;
if (! GetConsoleScreenBufferInfo(hStdOut, &info)) {
return NULL;
}
return env->NewObject(bufferStateClass,
bufferStateConstructor,
info.dwCursorPosition.X,
info.dwCursorPosition.Y,
info.dwSize.X,
info.dwSize.Y);
}
JNIEXPORT void JNICALL Java_jdk_internal_jline_WindowsTerminal_setCursorPosition
(JNIEnv *, jobject, jint x, jint y) {
HANDLE hStdOut;
if ((hStdOut = GetStdHandle(STD_OUTPUT_HANDLE)) == INVALID_HANDLE_VALUE) {
return ;
}
COORD coord = {(SHORT) x, (SHORT) y};
SetConsoleCursorPosition(hStdOut, coord);
}

View File

@ -173,7 +173,7 @@ class ConsoleIOContext extends IOContext {
}
}
repl.prefs.flush();
in.shutdown();
in.close();
try {
in.getTerminal().restore();
} catch (Exception ex) {
@ -1179,7 +1179,7 @@ class ConsoleIOContext extends IOContext {
public TestTerminal(StopDetectingInputStream input) throws Exception {
super(true);
setAnsiSupported(Boolean.getBoolean("test.terminal.ansi.supported"));
setAnsiSupported(true);
setEchoEnabled(false);
this.input = input;
int h = DEFAULT_HEIGHT;
@ -1218,7 +1218,7 @@ class ConsoleIOContext extends IOContext {
private final CompletionState completionState;
public CheckCompletionKeyMap(KeyMap del, CompletionState completionState) {
super(del.getName(), del.isViKeyMap());
super(del.getName());
this.del = del;
this.completionState = completionState;
}

View File

@ -40,6 +40,7 @@ import jdk.internal.jline.TerminalFactory.Flavor;
import jdk.internal.jline.WindowsTerminal;
import jdk.internal.jline.console.ConsoleReader;
import jdk.internal.jline.console.KeyMap;
import jdk.internal.jline.console.completer.CandidateListCompletionHandler;
import jdk.internal.jline.extra.EditingHistory;
import jdk.internal.misc.Signal;
import jdk.internal.misc.Signal.Handler;
@ -53,13 +54,14 @@ class Console implements AutoCloseable {
final NashornCompleter completer, final Function<String, String> docHelper) throws IOException {
this.historyFile = historyFile;
TerminalFactory.registerFlavor(Flavor.WINDOWS, isCygwin()? JJSUnixTerminal::new : JJSWindowsTerminal::new);
TerminalFactory.registerFlavor(Flavor.UNIX, JJSUnixTerminal::new);
TerminalFactory.registerFlavor(Flavor.WINDOWS, ttyDevice -> isCygwin() ? new JJSUnixTerminal() : new JJSWindowsTerminal());
TerminalFactory.registerFlavor(Flavor.UNIX, ttyDevice -> new JJSUnixTerminal());
in = new ConsoleReader(cmdin, cmdout);
in.setExpandEvents(false);
in.setHandleUserInterrupt(true);
in.setBellEnabled(true);
in.setCopyPasteDetection(true);
((CandidateListCompletionHandler) in.getCompletionHandler()).setPrintSpaceAfterFullCompletion(false);
final Iterable<String> existingHistory = historyFile.exists() ? Files.readAllLines(historyFile.toPath()) : null;
in.setHistory(new EditingHistory(in, existingHistory) {
@Override protected boolean isComplete(CharSequence input) {

View File

@ -24,16 +24,11 @@
/**
* @test
* @bug 8080679 8131913
* @modules jdk.internal.le/jdk.internal.jline
* jdk.internal.le/jdk.internal.jline.console:+open
* @modules jdk.internal.le/jdk.internal.jline.internal
* @summary Verify ConsoleReader.stripAnsi strips escape sequences from its input correctly.
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Method;
import jdk.internal.jline.UnsupportedTerminal;
import jdk.internal.jline.console.ConsoleReader;
import jdk.internal.jline.internal.Ansi;
public class StripAnsiTest {
public static void main(String... args) throws Exception {
@ -41,16 +36,10 @@ public class StripAnsiTest {
}
void run() throws Exception {
ByteArrayInputStream in = new ByteArrayInputStream(new byte[0]);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ConsoleReader reader = new ConsoleReader(in, out, new UnsupportedTerminal());
String withAnsi = "0\033[s1\033[2J2\033[37;4m3";
String expected = "0123";
Method stripAnsi = ConsoleReader.class.getDeclaredMethod("stripAnsi", String.class);
stripAnsi.setAccessible(true);
String actual = (String) stripAnsi.invoke(reader, withAnsi);
String actual = Ansi.stripAnsi(withAnsi);
if (!expected.equals(actual)) {
throw new IllegalStateException("Did not correctly strip escape sequences: " + actual);

View File

@ -0,0 +1,97 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8203827
* @summary Verify that escape sequences intepretation (used by Windows Terminal) works properly.
* @modules jdk.internal.le/jdk.internal.jline.extra
* @build AnsiInterpretingOutputStreamTest
* @run testng AnsiInterpretingOutputStreamTest
*/
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import jdk.internal.jline.extra.AnsiInterpretingOutputStream;
import jdk.internal.jline.extra.AnsiInterpretingOutputStream.BufferState;
import jdk.internal.jline.extra.AnsiInterpretingOutputStream.Performer;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
@Test
public class AnsiInterpretingOutputStreamTest {
public void testAnsiInterpretation() throws IOException {
BufferState[] state = new BufferState[] {new BufferState(5, 5, 10, 10)};
ByteArrayOutputStream result = new ByteArrayOutputStream();
OutputStream test = new AnsiInterpretingOutputStream("UTF-8", result, new Performer() {
@Override
public BufferState getBufferState() {
return state[0];
}
@Override
public void setCursorPosition(int cursorX, int cursorY) {
state[0] = new BufferState(cursorX, cursorY, state[0].sizeX, state[0].sizeY);
try {
result.write(("<setCursorPosition(" + cursorX + ", " + cursorY + ")>").getBytes("UTF-8"));
} catch (IOException ex) {
throw new AssertionError(ex);
}
}
});
Writer testWriter = new OutputStreamWriter(test, "UTF-8");
//cursor move:
testWriter.write("\033[A\033[3A\033[15A\n");
testWriter.write("\033[B\033[3B\033[15B\n");
testWriter.write("\033[D\033[3D\033[15D\n");
testWriter.write("\033[C\033[3C\033[15C\n");
//clearing line:
testWriter.write("\033[5D\n");
testWriter.write("\033[K\n");
testWriter.write("\033[1K\n");
testWriter.write("\033[2K\n");
testWriter.flush();
String expected = "<setCursorPosition(5, 4)><setCursorPosition(5, 1)><setCursorPosition(5, 0)>\n" +
"<setCursorPosition(5, 1)><setCursorPosition(5, 4)><setCursorPosition(5, 9)>\n" +
"<setCursorPosition(4, 9)><setCursorPosition(1, 9)><setCursorPosition(0, 9)>\n" +
"<setCursorPosition(1, 9)><setCursorPosition(4, 9)><setCursorPosition(9, 9)>\n" +
"<setCursorPosition(4, 9)>\n" +
" <setCursorPosition(4, 9)>\n" +
"<setCursorPosition(0, 9)> \n" +
" <setCursorPosition(0, 9)>\n";
String actual = new String(result.toByteArray(), "UTF-8");
assertEquals(actual, expected);
}
}

View File

@ -49,7 +49,6 @@ import org.testng.annotations.Test;
public class PasteAndMeasurementsUITest extends UITesting {
public void testPrevNextSnippet() throws Exception {
System.setProperty(ANSI_SUPPORTED_PROPERTY, "true");
Field cons = System.class.getDeclaredField("cons");
cons.setAccessible(true);
Constructor console = Console.class.getDeclaredConstructor();
@ -69,6 +68,5 @@ public class PasteAndMeasurementsUITest extends UITesting {
PROMPT + "\u001b\\[6n");
});
}
private static final String ANSI_SUPPORTED_PROPERTY = "test.terminal.ansi.supported";
private static final String LOC = "\033[12;1R";
}

View File

@ -83,7 +83,7 @@ public class ToolTabSnippetTest extends UITesting {
resource("jshell.console.see.documentation") +
REDRAW_PROMPT + "new JShellTest");
inputSink.write(TAB);
waitOutput(out, "jshelltest.JShellTest\n" +
waitOutput(out, "\\u001B\\[1mjshelltest.JShellTest\\u001B\\[0m\n" +
"JShellTest 0" +
REDRAW_PROMPT + "new JShellTest");
inputSink.write(TAB);
@ -105,7 +105,7 @@ public class ToolTabSnippetTest extends UITesting {
resource("jshell.console.see.documentation") +
REDRAW_PROMPT + "new JShellTest\\(");
inputSink.write(TAB);
waitOutput(out, "JShellTest\\(String str\\)\n" +
waitOutput(out, "\\u001B\\[1mJShellTest\\(String str\\)\\u001B\\[0m\n" +
"JShellTest 1\n" +
"1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n" +
"\n" +
@ -117,7 +117,7 @@ public class ToolTabSnippetTest extends UITesting {
resource("jshell.console.see.next.javadoc") +
REDRAW_PROMPT + "new JShellTest\\(");
inputSink.write(TAB);
waitOutput(out, "JShellTest\\(String str, int i\\)\n" +
waitOutput(out, "\\u001B\\[1mJShellTest\\(String str, int i\\)\\u001B\\[0m\n" +
"JShellTest 2\n" +
"\n" +
getMessage("jshell.console.completion.all.completions.number", "[0-9]+") +
@ -140,7 +140,7 @@ public class ToolTabSnippetTest extends UITesting {
resource("jshell.console.see.documentation") +
REDRAW_PROMPT + "new JShellTest\\(");
inputSink.write(TAB);
waitOutput(out, "JShellTest\\(String str\\)\n" +
waitOutput(out, "\\u001B\\[1mJShellTest\\(String str\\)\\u001B\\[0m\n" +
"JShellTest 1\n" +
"1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n" +
"\n" +
@ -152,7 +152,7 @@ public class ToolTabSnippetTest extends UITesting {
resource("jshell.console.see.next.javadoc") +
REDRAW_PROMPT + "new JShellTest\\(");
inputSink.write(TAB);
waitOutput(out, "JShellTest\\(String str, int i\\)\n" +
waitOutput(out, "\\u001B\\[1mJShellTest\\(String str, int i\\)\\u001B\\[0m\n" +
"JShellTest 2\n" +
"\n" +
getMessage("jshell.console.completion.all.completions.number", "[0-9]+") +

View File

@ -192,7 +192,7 @@ public class UITesting {
}
protected String clearOut(String what) {
return backspace(what.length()) + space(what.length()) + backspace(what.length());
return backspace(what.length()) + "\\u001B\\[K";
}
protected String backspace(int n) {
@ -222,7 +222,7 @@ public class UITesting {
}
protected String resource(String key) {
return Pattern.quote(getResource(key).replaceAll("\t", " "));
return Pattern.quote(getResource(key));
}
protected String getMessage(String key, Object... args) {