Skip to content

Commit

Permalink
Merge branch 'master' into jansi
Browse files Browse the repository at this point in the history
  • Loading branch information
gnodet authored Oct 24, 2023
2 parents e6cab2a + 2c8891a commit fd03959
Show file tree
Hide file tree
Showing 19 changed files with 195 additions and 33 deletions.
2 changes: 1 addition & 1 deletion native/Makefile.common
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ OpenBSD-x86_64_LIBNAME := libjlinenative.so

SunOS-sparcv9_CC := $(CROSS_PREFIX)gcc
SunOS-sparcv9_STRIP := $(CROSS_PREFIX)strip
SunOS-sparcv9_CCFLAGS := -I$(JAVA_HOME)/include -Itarget/inc -Itarget/inc/unix -O2s-fPIC -m64 -fvisibility=hidden
SunOS-sparcv9_CCFLAGS := -I$(JAVA_HOME)/include -Itarget/inc -Itarget/inc/unix -O2s -fPIC -m64 -fvisibility=hidden
SunOS-sparcv9_LINKFLAGS := -shared -static-libgcc
SunOS-sparcv9_LIBNAME := libjlinenative.so

Expand Down
5 changes: 4 additions & 1 deletion native/src/main/java/org/jline/nativ/JLineNativeLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ public class JLineNativeLoader {
public static synchronized boolean initialize() {
// only cleanup before the first extract
if (!loaded) {
cleanup();
Thread cleanup = new Thread(JLineNativeLoader::cleanup, "cleanup");
cleanup.setPriority(Thread.MIN_PRIORITY);
cleanup.setDaemon(true);
cleanup.start();
}
try {
loadJLineNativeLibrary();
Expand Down
6 changes: 6 additions & 0 deletions reader/src/main/java/org/jline/reader/LineReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ public interface LineReader {
String MAIN = "main";
String EMACS = "emacs";
String SAFE = ".safe";
String DUMB = "dumb";
String MENU = "menu";

//
Expand Down Expand Up @@ -395,6 +396,11 @@ public interface LineReader {
*/
String SUGGESTIONS_MIN_BUFFER_SIZE = "suggestions-min-buffer-size";

/**
* Max number of times a command can be repeated.
*/
String MAX_REPEAT_COUNT = "max-repeat-count";

Map<String, KeyMap<Binding>> defaultKeyMaps();

enum Option {
Expand Down
20 changes: 18 additions & 2 deletions reader/src/main/java/org/jline/reader/impl/LineReaderImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ public class LineReaderImpl implements LineReader, Flushable {

public static final String FOCUS_IN_SEQ = "\033[I";
public static final String FOCUS_OUT_SEQ = "\033[O";
public static final int DEFAULT_MAX_REPEAT_COUNT = 9999;

/**
* Possible states in which the current readline operation may be in.
Expand Down Expand Up @@ -2392,6 +2393,10 @@ protected boolean negArgument() {
protected boolean digitArgument() {
String s = getLastBinding();
repeatCount = (repeatCount * 10) + s.charAt(s.length() - 1) - '0';
int maxRepeatCount = getInt(MAX_REPEAT_COUNT, DEFAULT_MAX_REPEAT_COUNT);
if (repeatCount > maxRepeatCount) {
throw new IllegalArgumentException("digit argument should be less than " + maxRepeatCount);
}
isArgDigit = true;
return true;
}
Expand Down Expand Up @@ -5997,6 +6002,8 @@ public Map<String, KeyMap<Binding>> defaultKeyMaps() {
keyMaps.put(VIOPP, viOpp());
keyMaps.put(VISUAL, visual());
keyMaps.put(SAFE, safe());
keyMaps.put(DUMB, dumb());

if (getBoolean(BIND_TTY_SPECIAL_CHARS, true)) {
Attributes attr = terminal.getAttributes();
bindConsoleChars(keyMaps.get(EMACS), attr);
Expand All @@ -6007,8 +6014,9 @@ public Map<String, KeyMap<Binding>> defaultKeyMaps() {
keyMap.setUnicode(new Reference(SELF_INSERT));
keyMap.setAmbiguousTimeout(getLong(AMBIGUOUS_BINDING, DEFAULT_AMBIGUOUS_BINDING));
}
// By default, link main to emacs
keyMaps.put(MAIN, keyMaps.get(EMACS));
// By default, link main to emacs unless the temrinal is dumb
keyMaps.put(MAIN, keyMaps.get(isTerminalDumb() ? DUMB : EMACS));

return keyMaps;
}

Expand Down Expand Up @@ -6263,6 +6271,14 @@ public KeyMap<Binding> safe() {
return safe;
}

public KeyMap<Binding> dumb() {
KeyMap<Binding> dumb = new KeyMap<>();
bind(dumb, SELF_INSERT, range("^@-^?"));
bind(dumb, ACCEPT_LINE, "\r", "\n");
bind(dumb, BEEP, ctrl('G'));
return dumb;
}

public KeyMap<Binding> visual() {
KeyMap<Binding> visual = new KeyMap<>();
bind(visual, UP_LINE, key(Capability.key_up), "k");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,16 @@ protected void trimHistory(Path path, int max) throws IOException {
Log.trace("Trimming history path: ", path);
// Load all history entries
LinkedList<Entry> allItems = new LinkedList<>();
try (BufferedReader reader = Files.newBufferedReader(path)) {
reader.lines().forEach(l -> {
int idx = l.indexOf(':');
Instant time = Instant.ofEpochMilli(Long.parseLong(l.substring(0, idx)));
String line = unescape(l.substring(idx + 1));
allItems.add(createEntry(allItems.size(), time, line));
try (BufferedReader historyFileReader = Files.newBufferedReader(path)) {
historyFileReader.lines().forEach(l -> {
if (reader.isSet(LineReader.Option.HISTORY_TIMESTAMPED)) {
int idx = l.indexOf(':');
Instant time = Instant.ofEpochMilli(Long.parseLong(l.substring(0, idx)));
String line = unescape(l.substring(idx + 1));
allItems.add(createEntry(allItems.size(), time, line));
} else {
allItems.add(createEntry(allItems.size(), Instant.now(), unescape(l)));
}
});
}
// Remove duplicates
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.Instant;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
Expand All @@ -19,6 +20,7 @@
import org.jline.reader.LineReader;
import org.jline.reader.impl.ReaderTestSupport;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -97,4 +99,32 @@ public void testFileHistory() throws Exception {
lines = Files.readAllLines(Paths.get("test"));
assertEquals(cmdsPerThread * (nbThreads + 1), lines.size());
}

private void testHistoryTrim(boolean timestamped) {
reader.unsetOpt(LineReader.Option.HISTORY_INCREMENTAL);
reader.option(LineReader.Option.HISTORY_TIMESTAMPED, timestamped);
reader.setVariable(LineReader.HISTORY_FILE_SIZE, 5);
reader.setVariable(LineReader.HISTORY_FILE, Paths.get("test"));

DefaultHistory history = new DefaultHistory(reader);
for (int i = 0; i < 50; i++) {
history.add(Instant.now(), "Hello " + i);
if (i % 5 == 0) {
Assertions.assertDoesNotThrow(history::save);
}
}

Assertions.assertDoesNotThrow(history::load);
Assertions.assertEquals(5, history.size());
}

@Test
public void testHistoryTrimNonTimestamped() {
testHistoryTrim(false);
}

@Test
public void testHistoryTrimTimestamped() {
testHistoryTrim(true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public TestTerminal(StringWriter sw) throws IOException {
null,
new AnsiWriter(new BufferedWriter(sw)),
"name",
AbstractWindowsTerminal.TYPE_DUMB,
"windows",
Charset.defaultCharset(),
false,
SignalHandler.SIG_DFL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,9 @@ public String systemStreamName(SystemStream stream) {
public int systemStreamWidth(SystemStream stream) {
return FfmNativePty.systemStreamWidth(stream);
}

@Override
public String toString() {
return "TerminalProvider[" + name() + "]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -219,4 +219,9 @@ public String systemStreamName(SystemStream stream) {
public int systemStreamWidth(SystemStream stream) {
return JansiNativePty.systemStreamWidth(stream);
}

@Override
public String toString() {
return "TerminalProvider[" + name() + "]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,9 @@ public int systemStreamWidth(SystemStream stream) {
return -1;
}
}

@Override
public String toString() {
return "TerminalProvider[" + name() + "]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,9 @@ public String systemStreamName(SystemStream stream) {
public int systemStreamWidth(SystemStream stream) {
return JniNativePty.systemStreamWidth(stream);
}

@Override
public String toString() {
return "TerminalProvider[" + name() + "]";
}
}
75 changes: 59 additions & 16 deletions terminal/src/main/java/org/jline/terminal/TerminalBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

import org.jline.terminal.impl.AbstractPosixTerminal;
import org.jline.terminal.impl.AbstractTerminal;
import org.jline.terminal.impl.DumbTerminal;
import org.jline.terminal.impl.DumbTerminalProvider;
import org.jline.terminal.spi.SystemStream;
import org.jline.terminal.spi.TerminalProvider;
Expand All @@ -46,6 +47,7 @@ public final class TerminalBuilder {
public static final String PROP_ENCODING = "org.jline.terminal.encoding";
public static final String PROP_CODEPAGE = "org.jline.terminal.codepage";
public static final String PROP_TYPE = "org.jline.terminal.type";
public static final String PROP_PROVIDER = "org.jline.terminal.provider";
public static final String PROP_PROVIDERS = "org.jline.terminal.providers";
public static final String PROP_PROVIDER_FFM = "ffm";
public static final String PROP_PROVIDER_JNI = "jni";
Expand Down Expand Up @@ -366,9 +368,17 @@ private Terminal doBuild() throws IOException {
Charset encoding = computeEncoding();
String type = computeType();

IllegalStateException exception = new IllegalStateException("Unable to create a terminal");
List<TerminalProvider> providers = getProviders(exception);
String forcedProvider = System.getProperty(PROP_PROVIDER, null);

boolean forceDumb =
(DumbTerminal.TYPE_DUMB.equals(type) || type != null && type.startsWith(DumbTerminal.TYPE_DUMB_COLOR))
|| (forcedProvider != null && forcedProvider.equals(PROP_PROVIDER_DUMB));
Boolean dumb = this.dumb;
if (dumb == null) {
dumb = getBoolean(PROP_DUMB, null);
}
IllegalStateException exception = new IllegalStateException("Unable to create a terminal");
List<TerminalProvider> providers = getProviders(forcedProvider, exception);
Terminal terminal = null;
if ((system != null && system) || (system == null && in == null && out == null)) {
if (system != null
Expand All @@ -384,6 +394,43 @@ private Terminal doBuild() throws IOException {
.collect(Collectors.toMap(
stream -> stream, stream -> providers.stream().anyMatch(p -> p.isSystemStream(stream))));
SystemStream systemStream = select(system, systemOutput);

if (!forceDumb && system.get(SystemStream.Input) && systemStream != null) {
if (attributes != null || size != null) {
Log.warn("Attributes and size fields are ignored when creating a system terminal");
}
boolean ansiPassThrough = OSUtils.IS_CONEMU;
// Cygwin defaults to XTERM, but actually supports 256 colors,
// so if the value comes from the environment, change it to xterm-256color
if ((OSUtils.IS_CYGWIN || OSUtils.IS_MSYSTEM)
&& "xterm".equals(type)
&& this.type == null
&& System.getProperty(PROP_TYPE) == null) {
type = "xterm-256color";
}
for (TerminalProvider provider : providers) {
if (terminal == null) {
try {
terminal = provider.sysTerminal(
name,
type,
ansiPassThrough,
encoding,
nativeSignals,
signalHandler,
paused,
systemStream);
} catch (Throwable t) {
Log.debug("Error creating " + provider.name() + " based terminal: ", t.getMessage(), t);
exception.addSuppressed(t);
}
}
}
if (terminal == null && OSUtils.IS_WINDOWS && !jna && !jansi && !jni && (dumb == null || !dumb)) {
throw new IllegalStateException("Unable to create a system terminal. On windows, either "
+ "JNA or JANSI library is required. Make sure to add one of those in the classpath.");
}
}
if (terminal instanceof AbstractTerminal) {
AbstractTerminal t = (AbstractTerminal) terminal;
if (SYSTEM_TERMINAL.compareAndSet(null, t)) {
Expand All @@ -396,13 +443,8 @@ private Terminal doBuild() throws IOException {
terminal = null;
}
}

Boolean dumb = this.dumb;
if (dumb == null) {
dumb = getBoolean(PROP_DUMB, null);
}
if (terminal == null && (dumb == null || dumb)) {
if (dumb == null) {
if (terminal == null && (forceDumb || dumb == null || dumb)) {
if (!forceDumb && dumb == null) {
if (Log.isDebugEnabled()) {
Log.warn("input is tty: {}", system.get(SystemStream.Input));
Log.warn("output is tty: {}", system.get(SystemStream.Output));
Expand Down Expand Up @@ -557,18 +599,18 @@ public Charset computeEncoding() {
return encoding;
}

public List<TerminalProvider> getProviders(IllegalStateException exception) {
public List<TerminalProvider> getProviders(String forcedProvider, IllegalStateException exception) {
List<TerminalProvider> providers = new ArrayList<>();
// Check ffm provider
checkProvider(exception, providers, ffm, PROP_FFM, PROP_PROVIDER_FFM);
checkProvider(forcedProvider, exception, providers, ffm, PROP_FFM, PROP_PROVIDER_FFM);
// Check jni provider
checkProvider(exception, providers, jni, PROP_JNI, PROP_PROVIDER_JNI);
checkProvider(forcedProvider, exception, providers, jni, PROP_JNI, PROP_PROVIDER_JNI);
// Check jansi provider
checkProvider(exception, providers, jansi, PROP_JANSI, PROP_PROVIDER_JANSI);
checkProvider(forcedProvider, exception, providers, jansi, PROP_JANSI, PROP_PROVIDER_JANSI);
// Check jna provider
checkProvider(exception, providers, jna, PROP_JNA, PROP_PROVIDER_JNA);
checkProvider(forcedProvider, exception, providers, jna, PROP_JNA, PROP_PROVIDER_JNA);
// Check exec provider
checkProvider(exception, providers, exec, PROP_EXEC, PROP_PROVIDER_EXEC);
checkProvider(forcedProvider, exception, providers, exec, PROP_EXEC, PROP_PROVIDER_EXEC);
// Order providers
List<String> order = Arrays.asList(
(this.providers != null ? this.providers : System.getProperty(PROP_PROVIDERS, PROP_PROVIDERS_DEFAULT))
Expand All @@ -583,12 +625,13 @@ public List<TerminalProvider> getProviders(IllegalStateException exception) {
}

private void checkProvider(
String forcedProvider,
IllegalStateException exception,
List<TerminalProvider> providers,
Boolean load,
String property,
String name) {
Boolean doLoad = load;
Boolean doLoad = forcedProvider != null ? (Boolean) name.equals(forcedProvider) : load;
if (doLoad == null) {
doLoad = getBoolean(property, true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,9 @@ public String systemStreamName(SystemStream stream) {
public int systemStreamWidth(SystemStream stream) {
return 0;
}

@Override
public String toString() {
return "TerminalProvider[" + name() + "]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -252,4 +252,9 @@ public ProcessBuilder.Redirect newRedirectPipe(FileDescriptor fd) {
return JLineLibrary.newRedirectPipe(fd);
}
}

@Override
public String toString() {
return "TerminalProvider[" + name() + "]";
}
}
5 changes: 5 additions & 0 deletions terminal/src/main/java/org/jline/utils/ColorPalette.java
Original file line number Diff line number Diff line change
Expand Up @@ -265,4 +265,9 @@ private static int[] doLoad(Terminal terminal) throws IOException {
;
return Arrays.copyOfRange(palette, 0, max + 1);
}

@Override
public String toString() {
return "ColorPalette[" + "length=" + getLength() + ", " + "distance='" + getDist() + "\']";
}
}
Loading

0 comments on commit fd03959

Please sign in to comment.