From 9a17a6ff0f7b53e9d87bf5db85399aabeb2582c8 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Thu, 20 Mar 2025 15:17:10 +0000 Subject: [PATCH] 8350749: Upgrade JLine to 3.29.0 Reviewed-by: liach --- .../internal/org/jline/reader/LineReader.java | 7 +- .../jline/reader/UserInterruptException.java | 5 ++ .../jline/reader/impl/DefaultHighlighter.java | 8 ++ .../org/jline/reader/impl/LineReaderImpl.java | 15 ++-- .../impl/completer/SystemCompleter.java | 9 +- .../reader/impl/history/DefaultHistory.java | 2 +- .../org/jline/terminal/TerminalBuilder.java | 44 ++++++++++ .../terminal/impl/AbstractPosixTerminal.java | 9 ++ .../jline/terminal/impl/AbstractTerminal.java | 8 ++ .../org/jline/terminal/impl/Diag.java | 85 +++++++++++++------ .../org/jline/terminal/impl/exec/ExecPty.java | 2 +- .../impl/exec/ExecTerminalProvider.java | 3 + .../org/jline/terminal/impl/ffm/Kernel32.java | 6 +- .../impl/ffm/NativeWinSysTerminal.java | 2 +- .../jdk/internal/org/jline/utils/Display.java | 6 +- .../org/jline/utils/InputStreamReader.java | 3 +- .../jdk/internal/org/jline/utils/Status.java | 8 +- src/jdk.internal.le/share/legal/jline.md | 2 +- 18 files changed, 174 insertions(+), 50 deletions(-) diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java index bc513f5f636..ca1c34ef4ee 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java @@ -10,6 +10,7 @@ package jdk.internal.org.jline.reader; import java.io.File; import java.io.InputStream; +import java.nio.file.Path; import java.util.Collection; import java.util.Map; import java.util.function.IntConsumer; @@ -766,7 +767,11 @@ public interface LineReader { void addCommandsInBuffer(Collection commands); - void editAndAddInBuffer(File file) throws Exception; + default void editAndAddInBuffer(File file) throws Exception { + editAndAddInBuffer(file != null ? file.toPath() : null); + } + + void editAndAddInBuffer(Path file) throws Exception; String getLastBinding(); diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/UserInterruptException.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/UserInterruptException.java index 68bec8041fa..e5bc5b3180c 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/UserInterruptException.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/UserInterruptException.java @@ -19,6 +19,11 @@ public class UserInterruptException extends RuntimeException { private final String partialLine; + public UserInterruptException(Throwable cause) { + super(cause); + this.partialLine = null; + } + public UserInterruptException(String partialLine) { this.partialLine = partialLine; } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultHighlighter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultHighlighter.java index 55d39efde27..87bf06d0073 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultHighlighter.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultHighlighter.java @@ -38,6 +38,7 @@ public class DefaultHighlighter implements Highlighter { int underlineEnd = -1; int negativeStart = -1; int negativeEnd = -1; + boolean first = true; String search = reader.getSearchTerm(); if (search != null && search.length() > 0) { underlineStart = buffer.indexOf(search); @@ -65,6 +66,7 @@ public class DefaultHighlighter implements Highlighter { } AttributedStringBuilder sb = new AttributedStringBuilder(); + commandStyle(reader, sb, true); for (int i = 0; i < buffer.length(); i++) { if (i == underlineStart) { sb.style(AttributedStyle::underline); @@ -77,6 +79,10 @@ public class DefaultHighlighter implements Highlighter { } char c = buffer.charAt(i); + if (first && Character.isSpaceChar(c)) { + first = false; + commandStyle(reader, sb, false); + } if (c == '\t' || c == '\n') { sb.append(c); } else if (c < 32) { @@ -105,4 +111,6 @@ public class DefaultHighlighter implements Highlighter { } return sb.toAttributedString(); } + + protected void commandStyle(LineReader reader, AttributedStringBuilder sb, boolean enable) {} } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java index da69d08b23c..302254ab61f 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java @@ -10,7 +10,6 @@ package jdk.internal.org.jline.reader.impl; import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; import java.io.FileWriter; import java.io.Flushable; import java.io.IOError; @@ -1131,16 +1130,16 @@ public class LineReaderImpl implements LineReader, Flushable { } @Override - public void editAndAddInBuffer(File file) throws Exception { + public void editAndAddInBuffer(Path file) throws Exception { if (isSet(Option.BRACKETED_PASTE)) { terminal.writer().write(BRACKETED_PASTE_OFF); } - Constructor ctor = Class.forName("org.jline.builtins.Nano").getConstructor(Terminal.class, File.class); - Editor editor = (Editor) ctor.newInstance(terminal, new File(file.getParent())); + Constructor ctor = Class.forName("org.jline.builtins.Nano").getConstructor(Terminal.class, Path.class); + Editor editor = (Editor) ctor.newInstance(terminal, file.getParent()); editor.setRestricted(true); - editor.open(Collections.singletonList(file.getName())); + editor.open(Collections.singletonList(file.getFileName().toString())); editor.run(); - try (BufferedReader br = new BufferedReader(new FileReader(file))) { + try (BufferedReader br = Files.newBufferedReader(file)) { String line; commandsBuffer.clear(); while ((line = br.readLine()) != null) { @@ -3529,7 +3528,7 @@ public class LineReaderImpl implements LineReader, Flushable { buf.move(1); putString(yankBuffer); buf.move(-yankBuffer.length()); - } else if (yankBuffer.length() != 0) { + } else if (!yankBuffer.isEmpty()) { if (buf.cursor() < buf.length()) { buf.move(1); } @@ -3547,7 +3546,7 @@ public class LineReaderImpl implements LineReader, Flushable { ; putString(yankBuffer); buf.move(-yankBuffer.length()); - } else if (yankBuffer.length() != 0) { + } else if (!yankBuffer.isEmpty()) { if (buf.cursor() > 0) { buf.move(-1); } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/SystemCompleter.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/SystemCompleter.java index 2fe6f8df492..642cf275142 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/SystemCompleter.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/SystemCompleter.java @@ -9,6 +9,8 @@ package jdk.internal.org.jline.reader.impl.completer; import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; import jdk.internal.org.jline.reader.Candidate; import jdk.internal.org.jline.reader.Completer; @@ -24,6 +26,7 @@ import jdk.internal.org.jline.utils.AttributedString; public class SystemCompleter implements Completer { private Map> completers = new HashMap<>(); private Map aliasCommand = new HashMap<>(); + private Map descriptions = new HashMap<>(); private StringsCompleter commands; private boolean compiled = false; @@ -124,6 +127,10 @@ public class SystemCompleter implements Completer { } public void compile() { + compile(s -> new Candidate(AttributedString.stripAnsi(s), s, null, null, null, null, true)); + } + + public void compile(Function candidateBuilder) { if (compiled) { return; } @@ -139,7 +146,7 @@ public class SystemCompleter implements Completer { completers = compiledCompleters; Set cmds = new HashSet<>(completers.keySet()); cmds.addAll(aliasCommand.keySet()); - commands = new StringsCompleter(cmds); + commands = new StringsCompleter(cmds.stream().map(candidateBuilder).collect(Collectors.toList())); compiled = true; } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java index c696b33ba9e..ca275c43c6d 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java @@ -200,7 +200,7 @@ public class DefaultHistory implements History { public void write(Path file, boolean incremental) throws IOException { Path path = file != null ? file : getPath(); if (path != null && Files.exists(path)) { - path.toFile().delete(); + Files.deleteIfExists(path); } internalWrite(path, incremental ? getLastLoaded(path) : 0); } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/TerminalBuilder.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/TerminalBuilder.java index 3b02ec2d8d8..d66b124448e 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/TerminalBuilder.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/TerminalBuilder.java @@ -209,41 +209,85 @@ public final class TerminalBuilder { return this; } + /** + * Forces the usage of the give terminal provider. + * + * @param provider The {@link TerminalProvider}'s name to use when creating the Terminal. + * @return The builder. + */ public TerminalBuilder provider(String provider) { this.provider = provider; return this; } + /** + * Sets the list of providers to try when creating the terminal. + * If not specified, the system property {@link #PROP_PROVIDERS} will be used if set. + * Else, the value {@link #PROP_PROVIDERS_DEFAULT} will be used. + * + * @param providers The list of {@link TerminalProvider}'s names to check when creating the Terminal. + * @return The builder. + */ public TerminalBuilder providers(String providers) { this.providers = providers; return this; } + /** + * Enables or disables the {@link #PROP_PROVIDER_JNA}/{@code jna} terminal provider. + * If not specified, the system property {@link #PROP_JNA} will be used if set. + * If not specified, the provider will be checked. + */ public TerminalBuilder jna(boolean jna) { this.jna = jna; return this; } + /** + * Enables or disables the {@link #PROP_PROVIDER_JANSI}/{@code jansi} terminal provider. + * If not specified, the system property {@link #PROP_JANSI} will be used if set. + * If not specified, the provider will be checked. + */ public TerminalBuilder jansi(boolean jansi) { this.jansi = jansi; return this; } + /** + * Enables or disables the {@link #PROP_PROVIDER_JNI}/{@code jni} terminal provider. + * If not specified, the system property {@link #PROP_JNI} will be used if set. + * If not specified, the provider will be checked. + */ public TerminalBuilder jni(boolean jni) { this.jni = jni; return this; } + /** + * Enables or disables the {@link #PROP_PROVIDER_EXEC}/{@code exec} terminal provider. + * If not specified, the system property {@link #PROP_EXEC} will be used if set. + * If not specified, the provider will be checked. + */ public TerminalBuilder exec(boolean exec) { this.exec = exec; return this; } + /** + * Enables or disables the {@link #PROP_PROVIDER_FFM}/{@code ffm} terminal provider. + * If not specified, the system property {@link #PROP_FFM} will be used if set. + * If not specified, the provider will be checked. + */ public TerminalBuilder ffm(boolean ffm) { this.ffm = ffm; return this; } + /** + * Enables or disables the {@link #PROP_PROVIDER_DUMB}/{@code dumb} terminal provider. + * If not specified, the system property {@link #PROP_DUMB} will be used if set. + * If not specified, the provider will be checked. + */ public TerminalBuilder dumb(boolean dumb) { this.dumb = dumb; return this; diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPosixTerminal.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPosixTerminal.java index 5d000d07083..862bf93cd46 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPosixTerminal.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPosixTerminal.java @@ -94,4 +94,13 @@ public abstract class AbstractPosixTerminal extends AbstractTerminal { public SystemStream getSystemStream() { return getPty().getSystemStream(); } + + @Override + public String toString() { + return getKind() + "[" + "name='" + + name + '\'' + ", pty='" + + pty + '\'' + ", type='" + + type + '\'' + ", size='" + + getSize() + '\'' + ']'; + } } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractTerminal.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractTerminal.java index 2608e2e5f37..34b07048790 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractTerminal.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractTerminal.java @@ -287,4 +287,12 @@ public abstract class AbstractTerminal implements TerminalExt { public ColorPalette getPalette() { return palette; } + + @Override + public String toString() { + return getKind() + "[" + "name='" + + name + '\'' + ", type='" + + type + '\'' + ", size='" + + getSize() + '\'' + ']'; + } } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/Diag.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/Diag.java index dc54ea2157d..7b7d17499b6 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/Diag.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/Diag.java @@ -10,7 +10,7 @@ package jdk.internal.org.jline.terminal.impl; import java.io.PrintStream; import java.nio.charset.StandardCharsets; -import java.util.ServiceLoader; +import java.util.Arrays; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask; import java.util.concurrent.TimeUnit; @@ -24,10 +24,26 @@ import jdk.internal.org.jline.utils.OSUtils; public class Diag { public static void main(String[] args) { - diag(System.out); + diag(System.out, Arrays.asList(args).contains("--verbose")); } public static void diag(PrintStream out) { + diag(out, true); + } + + public static void diag(PrintStream out, boolean verbose) { + new Diag(out, verbose).run(); + } + + private final PrintStream out; + private final boolean verbose; + + public Diag(PrintStream out, boolean verbose) { + this.out = out; + this.verbose = verbose; + } + + public void run() { out.println("System properties"); out.println("================="); out.println("os.name = " + System.getProperty("os.name")); @@ -56,9 +72,9 @@ public class Diag { out.println("================="); try { TerminalProvider provider = TerminalProvider.load("ffm"); - testProvider(out, provider); + testProvider(provider); } catch (Throwable t) { - out.println("FFM support not available: " + t); + error("FFM support not available", t); } out.println(); @@ -66,9 +82,9 @@ public class Diag { out.println("================="); try { TerminalProvider provider = TerminalProvider.load("jna"); - testProvider(out, provider); + testProvider(provider); } catch (Throwable t) { - out.println("JNA support not available: " + t); + error("JNA support not available", t); } out.println(); @@ -76,9 +92,9 @@ public class Diag { out.println("================="); try { TerminalProvider provider = TerminalProvider.load("jansi"); - testProvider(out, provider); + testProvider(provider); } catch (Throwable t) { - out.println("Jansi 2 support not available: " + t); + error("Jansi 2 support not available", t); } out.println(); @@ -86,9 +102,9 @@ public class Diag { out.println("================="); try { TerminalProvider provider = TerminalProvider.load("jni"); - testProvider(out, provider); + testProvider(provider); } catch (Throwable t) { - out.println("JNI support not available: " + t); + error("JNI support not available", t); } out.println(); @@ -97,26 +113,31 @@ public class Diag { out.println("================="); try { TerminalProvider provider = TerminalProvider.load("exec"); - testProvider(out, provider); + testProvider(provider); } catch (Throwable t) { - out.println("Exec support not available: " + t); + error("Exec support not available", t); + } + + if (!verbose) { + out.println(); + out.println("Run with --verbose argument to print stack traces"); } } - private static void testProvider(PrintStream out, TerminalProvider provider) { + private void testProvider(TerminalProvider provider) { try { out.println("StdIn stream = " + provider.isSystemStream(SystemStream.Input)); out.println("StdOut stream = " + provider.isSystemStream(SystemStream.Output)); out.println("StdErr stream = " + provider.isSystemStream(SystemStream.Error)); - } catch (Throwable t2) { - out.println("Unable to check stream: " + t2); + } catch (Throwable t) { + error("Unable to check stream", t); } try { out.println("StdIn stream name = " + provider.systemStreamName(SystemStream.Input)); out.println("StdOut stream name = " + provider.systemStreamName(SystemStream.Output)); out.println("StdErr stream name = " + provider.systemStreamName(SystemStream.Error)); - } catch (Throwable t2) { - out.println("Unable to check stream names: " + t2); + } catch (Throwable t) { + error("Unable to check stream names", t); } try (Terminal terminal = provider.sysTerminal( "diag", @@ -132,9 +153,14 @@ public class Diag { Attributes attr = terminal.enterRawMode(); try { out.println("Terminal size: " + terminal.getSize()); - ForkJoinTask t = - new ForkJoinPool(1).submit(() -> terminal.reader().read(1)); - int r = t.get(1000, TimeUnit.MILLISECONDS); + ForkJoinPool forkJoinPool = new ForkJoinPool(1); + try { + ForkJoinTask t = + forkJoinPool.submit(() -> terminal.reader().read(1)); + t.get(1000, TimeUnit.MILLISECONDS); + } finally { + forkJoinPool.shutdown(); + } StringBuilder sb = new StringBuilder(); sb.append("The terminal seems to work: "); sb.append("terminal ").append(terminal.getClass().getName()); @@ -146,22 +172,25 @@ public class Diag { .getName()); } out.println(sb); - } catch (Throwable t3) { - out.println("Unable to read from terminal: " + t3); - t3.printStackTrace(); + } catch (Throwable t2) { + error("Unable to read from terminal", t2); } finally { terminal.setAttributes(attr); } } else { out.println("Not supported by provider"); } - } catch (Throwable t2) { - out.println("Unable to open terminal: " + t2); - t2.printStackTrace(); + } catch (Throwable t) { + error("Unable to open terminal", t); } } - static S load(Class clazz) { - return ServiceLoader.load(clazz, clazz.getClassLoader()).iterator().next(); + private void error(String message, Throwable cause) { + if (verbose) { + out.println(message); + cause.printStackTrace(out); + } else { + out.println(message + ": " + cause); + } } } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecPty.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecPty.java index c0a35cbd6a2..f21920160d6 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecPty.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecPty.java @@ -278,7 +278,7 @@ public class ExecPty extends AbstractPty implements Pty { return Integer.parseInt(matcher.group(1)); } } - throw new IOException("Unable to parse " + name); + return 0; } @Override diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecTerminalProvider.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecTerminalProvider.java index 418d3452d4a..74c68859a1e 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecTerminalProvider.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecTerminalProvider.java @@ -46,6 +46,9 @@ public class ExecTerminalProvider implements TerminalProvider { } public Pty current(SystemStream systemStream) throws IOException { + if (!isSystemStream(systemStream)) { + throw new IOException("Not a system stream: " + systemStream); + } return ExecPty.current(this, systemStream); } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/Kernel32.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/Kernel32.java index 4e7adbe3355..baa4aad0ee0 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/Kernel32.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/Kernel32.java @@ -19,7 +19,7 @@ final class Kernel32 { public static final int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; - public static final int INVALID_HANDLE_VALUE = -1; + public static final long INVALID_HANDLE_VALUE = -1; public static final int STD_INPUT_HANDLE = -10; public static final int STD_OUTPUT_HANDLE = -11; public static final int STD_ERROR_HANDLE = -12; @@ -235,8 +235,8 @@ final class Kernel32 { CHAR_INFO lpFill) { MethodHandle mh$ = requireNonNull(ScrollConsoleScreenBufferW$MH, "ScrollConsoleScreenBuffer"); try { - return (int) - mh$.invokeExact(hConsoleOutput, lpScrollRectangle.seg, lpClipRectangle.seg, dwDestinationOrigin.seg, lpFill.seg); + return (int) mh$.invokeExact( + hConsoleOutput, lpScrollRectangle.seg, lpClipRectangle.seg, dwDestinationOrigin.seg, lpFill.seg); } catch (Throwable ex$) { throw new AssertionError("should not reach here", ex$); } diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/NativeWinSysTerminal.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/NativeWinSysTerminal.java index 189fc2808d9..e4c123711f3 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/NativeWinSysTerminal.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ffm/NativeWinSysTerminal.java @@ -83,7 +83,7 @@ public class NativeWinSysTerminal extends AbstractWindowsTerminal 0 && size.getRows() < 1000 && size.getColumns() > 0 && size.getColumns() < 1000; + } + public void close() { terminal.puts(Capability.save_cursor); terminal.puts(Capability.change_scroll_region, 0, display.rows - 1); @@ -147,6 +152,7 @@ public class Status { if (newScrollRegion < scrollRegion) { // We need to scroll up to grow the status bar terminal.puts(Capability.save_cursor); + terminal.puts(Capability.cursor_address, scrollRegion, 0); for (int i = newScrollRegion; i < scrollRegion; i++) { terminal.puts(Capability.cursor_down); } diff --git a/src/jdk.internal.le/share/legal/jline.md b/src/jdk.internal.le/share/legal/jline.md index 5b813c0af2f..17392e93659 100644 --- a/src/jdk.internal.le/share/legal/jline.md +++ b/src/jdk.internal.le/share/legal/jline.md @@ -1,4 +1,4 @@ -## JLine v3.26.1 +## JLine v3.29.0 ### JLine License