Skip to content

Commit 67a5ed9

Browse files
committed
push to org.jline:jline:3.13.1
set version to 3.4.0
1 parent f708245 commit 67a5ed9

File tree

4 files changed

+115
-83
lines changed

4 files changed

+115
-83
lines changed

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ gitPublish {
299299

300300
project('text-io') {
301301
dependencies {
302-
compile 'jline:jline:2.14.5'
302+
compile 'org.jline:jline:3.13.1'
303303
compile 'org.beryx:awt-color-factory:1.0.0'
304304
}
305305
jar {

gradle.properties

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
textIoVersionMajor = 3
2-
textIoVersionMinor = 3
3-
textIoVersionPatch = 1
2+
textIoVersionMinor = 4
3+
textIoVersionPatch = 0
44
# textIoVersionLabel = alpha-1
55
textIoReleaseBuild = false

text-io/src/main/java/org/beryx/textio/jline/JLineTextTerminal.java

+108-75
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,21 @@
1515
*/
1616
package org.beryx.textio.jline;
1717

18-
import java.awt.Color;
19-
import jline.console.ConsoleReader;
20-
import jline.console.CursorBuffer;
21-
import jline.console.UserInterruptException;
22-
import org.beryx.awt.color.ColorFactory;
23-
import org.beryx.textio.*;
24-
import org.slf4j.Logger;
25-
import org.slf4j.LoggerFactory;
18+
import static org.beryx.textio.PropertiesConstants.PROP_ANSI_COLOR_MODE;
19+
import static org.beryx.textio.PropertiesConstants.PROP_INPUT_BGCOLOR;
20+
import static org.beryx.textio.PropertiesConstants.PROP_INPUT_BOLD;
21+
import static org.beryx.textio.PropertiesConstants.PROP_INPUT_COLOR;
22+
import static org.beryx.textio.PropertiesConstants.PROP_INPUT_ITALIC;
23+
import static org.beryx.textio.PropertiesConstants.PROP_INPUT_UNDERLINE;
24+
import static org.beryx.textio.PropertiesConstants.PROP_PROMPT_BGCOLOR;
25+
import static org.beryx.textio.PropertiesConstants.PROP_PROMPT_BOLD;
26+
import static org.beryx.textio.PropertiesConstants.PROP_PROMPT_COLOR;
27+
import static org.beryx.textio.PropertiesConstants.PROP_PROMPT_ITALIC;
28+
import static org.beryx.textio.PropertiesConstants.PROP_PROMPT_UNDERLINE;
29+
import static org.beryx.textio.ReadInterruptionStrategy.Action.CONTINUE;
30+
import static org.beryx.textio.ReadInterruptionStrategy.Action.RESTART;
2631

32+
import java.awt.Color;
2733
import java.awt.event.ActionEvent;
2834
import java.awt.event.ActionListener;
2935
import java.io.IOException;
@@ -33,15 +39,31 @@
3339
import java.util.function.Consumer;
3440
import java.util.function.Function;
3541

36-
import static org.beryx.textio.PropertiesConstants.*;
37-
import static org.beryx.textio.ReadInterruptionStrategy.Action.*;
42+
import org.beryx.awt.color.ColorFactory;
43+
import org.beryx.textio.AbstractTextTerminal;
44+
import org.beryx.textio.KeyCombination;
45+
import org.beryx.textio.PropertiesPrefixes;
46+
import org.beryx.textio.ReadHandlerData;
47+
import org.beryx.textio.ReadInterruptionData;
48+
import org.beryx.textio.ReadInterruptionException;
49+
import org.beryx.textio.ReadInterruptionStrategy;
50+
import org.beryx.textio.TerminalProperties;
51+
import org.beryx.textio.TextTerminal;
52+
import org.jline.reader.Binding;
53+
import org.jline.reader.Buffer;
54+
import org.jline.reader.LineReaderBuilder;
55+
import org.jline.reader.UserInterruptException;
56+
import org.jline.reader.impl.LineReaderImpl;
57+
import org.jline.terminal.TerminalBuilder;
58+
import org.slf4j.Logger;
59+
import org.slf4j.LoggerFactory;
3860

3961
/**
4062
* A JLine-based {@link TextTerminal}.
4163
*/
42-
@PropertiesPrefixes({"jline"})
64+
@PropertiesPrefixes({ "jline" })
4365
public class JLineTextTerminal extends AbstractTextTerminal<JLineTextTerminal> {
44-
private static final Logger logger = LoggerFactory.getLogger(JLineTextTerminal.class);
66+
private static final Logger logger = LoggerFactory.getLogger(JLineTextTerminal.class);
4567

4668
private static final Consumer<JLineTextTerminal> DEFAULT_USER_INTERRUPT_HANDLER = textTerm -> System.exit(-1);
4769

@@ -74,8 +96,8 @@ public class JLineTextTerminal extends AbstractTextTerminal<JLineTextTerminal> {
7496
Color.WHITE
7597
};
7698

77-
private final ConsoleReader reader;
78-
private Consumer<JLineTextTerminal>userInterruptHandler = DEFAULT_USER_INTERRUPT_HANDLER;
99+
private final LineReaderImpl reader;
100+
private Consumer<JLineTextTerminal> userInterruptHandler = DEFAULT_USER_INTERRUPT_HANDLER;
79101
private boolean abortRead = true;
80102

81103
private AnsiColorMode ansiColorMode = AnsiColorMode.STANDARD;
@@ -113,9 +135,9 @@ String getAnsiColorCode(Color color) {
113135
private static String getStandardColorCode(Color color) {
114136
double bestDist = Double.MAX_VALUE;
115137
int bestIndex = -1;
116-
for(int i = 0; i < STANDARD_COLORS.length; i++) {
117-
double dist = getColorDistance(color, STANDARD_COLORS[i]);
118-
if(dist < bestDist) {
138+
for (int i = 0; i < STANDARD_COLORS.length; i++) {
139+
double dist = getColorDistance(color, STANDARD_COLORS[i]);
140+
if (dist < bestDist) {
119141
bestDist = dist;
120142
bestIndex = i;
121143
}
@@ -159,10 +181,12 @@ public static int getStandardColorCode(String colorName) {
159181
}
160182

161183
public Optional<String> getColorCode(String colorName) {
162-
if(colorName == null || colorName.isEmpty()) return Optional.empty();
184+
if (colorName == null || colorName.isEmpty()) {
185+
return Optional.empty();
186+
}
163187
try {
164188
int code = getStandardColorCode(colorName);
165-
if(code >= 0) {
189+
if (code >= 0) {
166190
return Optional.of("" + code);
167191
}
168192
Color color = ColorFactory.web(colorName);
@@ -175,14 +199,18 @@ public Optional<String> getColorCode(String colorName) {
175199
}
176200

177201
private static int mapTo6(double val) {
178-
if(val < 0) val = 0;
179-
if(val > 255) val = 255;
180-
return (int)(val * 6.0 / 256.0);
202+
if (val < 0) {
203+
val = 0;
204+
}
205+
if (val > 255) {
206+
val = 255;
207+
}
208+
return (int) (val * 6.0 / 256.0);
181209
}
182210

183211
private String getAnsiColorWithPrefix(int prefix, String colorName) {
184212
String ansiCode = getColorCode(colorName).map(col -> "\u001B[1;" + prefix + col + "m").orElse("");
185-
logger.debug("ansiColor({}, {}) = {}", prefix , colorName, ansiCode);
213+
logger.debug("ansiColor({}, {}) = {}", prefix, colorName, ansiCode);
186214
return ansiCode;
187215
}
188216

@@ -194,22 +222,24 @@ public String getAnsiBackgroundColor(String colorName) {
194222
return getAnsiColorWithPrefix(4, colorName);
195223
}
196224

197-
public static ConsoleReader createReader() {
225+
public static LineReaderImpl createReader() {
198226
try {
199-
if(System.console() == null) throw new IllegalArgumentException("Console not available.");
200-
return new ConsoleReader();
227+
return (LineReaderImpl) LineReaderBuilder.builder()
228+
.terminal(TerminalBuilder.builder().build())
229+
.build();
201230
} catch (IOException e) {
202-
throw new IllegalArgumentException("Cannot create a JLine ConsoleReader.", e);
231+
throw new IllegalArgumentException("Cannot create a JLine Terminal.", e);
203232
}
204233
}
205234

206235
public JLineTextTerminal() {
207236
this(createReader());
208237
}
209238

210-
public JLineTextTerminal(ConsoleReader reader) {
211-
if(reader == null) throw new IllegalArgumentException("reader is null");
212-
reader.setHandleUserInterrupt(true);
239+
public JLineTextTerminal(LineReaderImpl reader) {
240+
if (reader == null) {
241+
throw new IllegalArgumentException("reader is null");
242+
}
213243
this.reader = reader;
214244

215245
TerminalProperties<JLineTextTerminal> props = getProperties();
@@ -224,7 +254,8 @@ public JLineTextTerminal(ConsoleReader reader) {
224254
props.addBooleanListener(PROP_INPUT_ITALIC, false, (term, newVal) -> setInputItalic(newVal));
225255
props.addBooleanListener(PROP_INPUT_UNDERLINE, false, (term, newVal) -> setInputUnderline(newVal));
226256

227-
props.addStringListener(PROP_ANSI_COLOR_MODE, AnsiColorMode.STANDARD.toString(), (term, newVal) -> setAnsiColorMode(newVal));
257+
props.addStringListener(PROP_ANSI_COLOR_MODE, AnsiColorMode.STANDARD.toString(),
258+
(term, newVal) -> setAnsiColorMode(newVal));
228259
}
229260

230261
@Override
@@ -233,20 +264,19 @@ public String read(boolean masking) {
233264
try {
234265
String prefix = "";
235266
Character mask = masking ? '*' : null;
236-
while(true) {
267+
while (true) {
237268
try {
238269
String buffer = initialReadBuffer;
239270
initialReadBuffer = null;
240271
return prefix + reader.readLine(null, mask, buffer);
241-
} catch(UserInterruptException e) {
272+
} catch (UserInterruptException e) {
242273
userInterruptHandler.accept(this);
243274
prefix = prefix + e.getPartialLine();
244-
if(abortRead) return prefix;
275+
if (abortRead) {
276+
return prefix;
277+
}
245278
} catch (ReadInterruptionException e) {
246279
throw e;
247-
} catch (IOException e) {
248-
logger.error("read error.", e);
249-
return "";
250280
} catch (Exception e) {
251281
logger.error("read error.", e);
252282
}
@@ -259,7 +289,7 @@ public String read(boolean masking) {
259289
@Override
260290
public void rawPrint(String message) {
261291
String msgPrefix = "";
262-
if(moveToLineStartRequired) {
292+
if (moveToLineStartRequired) {
263293
moveToLineStartRequired = false;
264294
msgPrefix = "\r";
265295
}
@@ -269,10 +299,7 @@ public void rawPrint(String message) {
269299
public void printAnsi(String message) {
270300
try {
271301
reader.setPrompt(message);
272-
reader.drawLine();
273-
reader.flush();
274-
} catch (IOException e) {
275-
logger.error("print error.", e);
302+
println();
276303
} finally {
277304
reader.setPrompt(null);
278305
}
@@ -288,23 +315,13 @@ public String getAnsiPrefix(StyleData styleData) {
288315

289316
@Override
290317
public void println() {
291-
try {
292-
reader.println();
293-
reader.flush();
294-
} catch (IOException e) {
295-
logger.error("println error.", e);
296-
}
318+
reader.getTerminal().writer().println();
319+
reader.flush();
297320
}
298321

299322
@Override
300323
public boolean resetLine() {
301-
try {
302-
reader.resetPromptLine("", "", 0);
303-
return true;
304-
} catch (IOException e) {
305-
logger.error("resetLine error.", e);
306-
return false;
307-
}
324+
return reader.redrawLine();
308325
}
309326

310327
@Override
@@ -320,7 +337,7 @@ public boolean registerUserInterruptHandler(Consumer<JLineTextTerminal> handler,
320337
return true;
321338
}
322339

323-
private static class UserHandler implements ActionListener {
340+
private static class UserHandler implements ActionListener, Binding {
324341
private final JLineTextTerminal textTerminal;
325342
private final Function<JLineTextTerminal, ReadHandlerData> handler;
326343

@@ -331,16 +348,16 @@ private UserHandler(JLineTextTerminal textTerminal, Function<JLineTextTerminal,
331348

332349
@Override
333350
public void actionPerformed(ActionEvent e) {
334-
CursorBuffer buf = textTerminal.reader.getCursorBuffer();
335-
String partialInput = buf.buffer.toString();
351+
Buffer buf = textTerminal.reader.getBuffer();
352+
String partialInput = buf.substring(0);
336353
buf.clear();
337354

338355
ReadHandlerData handlerData = handler.apply(textTerminal);
339356
ReadInterruptionStrategy.Action action = handlerData.getAction();
340-
if(action == CONTINUE) {
357+
if (action == CONTINUE) {
341358
buf.write(partialInput);
342359
} else {
343-
if(action == RESTART) {
360+
if (action == RESTART) {
344361
textTerminal.initialReadBuffer = partialInput;
345362
}
346363
ReadInterruptionData interruptData = ReadInterruptionData.from(handlerData, partialInput);
@@ -352,24 +369,32 @@ public void actionPerformed(ActionEvent e) {
352369
@Override
353370
public boolean registerHandler(String keyStroke, Function<JLineTextTerminal, ReadHandlerData> handler) {
354371
String keySeq = getKeySequence(keyStroke);
355-
if(keySeq == null) return false;
356-
reader.getKeys().bind(keySeq, new UserHandler(this, handler));
372+
if (keySeq == null) {
373+
return false;
374+
}
375+
reader.getKeys().bind(new UserHandler(this, handler), keySeq);
357376
return true;
358377
}
359378

360379
@Override
361380
public void dispose(String resultData) {
362381
printAnsi(ANSI_RESET);
363-
reader.close();
382+
try {
383+
reader.getTerminal().close();
384+
} catch (IOException e) {
385+
}
364386
}
365387

366388
@Override
367389
public void abort() {
368390
printAnsi(ANSI_RESET);
369-
reader.close();
391+
try {
392+
reader.getTerminal().close();
393+
} catch (IOException e) {
394+
}
370395
}
371396

372-
public ConsoleReader getReader() {
397+
public LineReaderImpl getReader() {
373398
return reader;
374399
}
375400

@@ -414,7 +439,7 @@ public void setInputUnderline(boolean underline) {
414439
}
415440

416441
public void setAnsiColorMode(String mode) {
417-
if(mode == null || mode.isEmpty()) {
442+
if (mode == null || mode.isEmpty()) {
418443
ansiColorMode = AnsiColorMode.STANDARD;
419444
return;
420445
}
@@ -428,18 +453,26 @@ public void setAnsiColorMode(String mode) {
428453

429454
public static String getKeySequence(String keyStroke) {
430455
KeyCombination kc = KeyCombination.of(keyStroke);
431-
if(kc == null) return null;
432-
if(kc.isTyped()) return String.valueOf(kc.getChar());
456+
if (kc == null) {
457+
return null;
458+
}
459+
if (kc.isTyped()) {
460+
return String.valueOf(kc.getChar());
461+
}
433462
int code = kc.getCode();
434-
if(code < 'A' || code > 'Z') return null;
435-
if(kc.isCtrlDown()) {
436-
if(kc.isAltDown()) return null;
437-
return String.valueOf((char)(code + 1 -'A'));
438-
} else if(kc.isAltDown()) {
439-
if(!kc.isShiftDown()) {
463+
if (code < 'A' || code > 'Z') {
464+
return null;
465+
}
466+
if (kc.isCtrlDown()) {
467+
if (kc.isAltDown()) {
468+
return null;
469+
}
470+
return String.valueOf((char) (code + 1 - 'A'));
471+
} else if (kc.isAltDown()) {
472+
if (!kc.isShiftDown()) {
440473
code += 32;
441474
}
442-
return String.format("%c%c", (char)27, (char)code);
475+
return String.format("%c%c", (char) 27, (char) code);
443476
}
444477
return null;
445478
}

text-io/src/main/java/org/beryx/textio/jline/JLineTextTerminalProvider.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,17 @@
1515
*/
1616
package org.beryx.textio.jline;
1717

18-
import jline.console.ConsoleReader;
1918
import org.beryx.textio.TextTerminalProvider;
2019

2120
/**
22-
* If {@link System#console()} is not null and a ConsoleReader can be created, it provides a {@link JLineTextTerminal}.
21+
* If {@link System#console()} is not null and a ConsoleReader can be created,
22+
* it provides a {@link JLineTextTerminal}.
2323
*/
2424
public class JLineTextTerminalProvider implements TextTerminalProvider {
25+
@Override
2526
public JLineTextTerminal getTextTerminal() {
26-
if(System.console() == null) return null;
2727
try {
28-
ConsoleReader reader = new ConsoleReader();
29-
return new JLineTextTerminal(reader);
28+
return new JLineTextTerminal();
3029
} catch (Exception e) {
3130
return null;
3231
}

0 commit comments

Comments
 (0)