8203827: Upgrade JLine to 2.14.6
Reviewed-by: alanb, hannesw, rfield
This commit is contained in:
parent
f4b24c3473
commit
aabea5d599
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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/>
|
||||
|
@ -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);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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]");
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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,";
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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";
|
||||
}
|
||||
|
@ -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]+") +
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user