diff --git a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java index 2812dc19695..a2b1ca0d2d0 100644 --- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java +++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, 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 @@ -121,7 +121,7 @@ class ConsoleIOContext extends IOContext { String prefix = ""; ConsoleIOContext(JShellTool repl, InputStream cmdin, PrintStream cmdout, - boolean interactive) throws Exception { + boolean interactive, Size size) throws Exception { this.repl = repl; Map variables = new HashMap<>(); this.input = new StopDetectingInputStream(() -> repl.stop(), @@ -143,7 +143,6 @@ class ConsoleIOContext extends IOContext { terminal = new TestTerminal(nonBlockingInput, cmdout); enableHighlighter = Boolean.getBoolean("test.enable.highlighter"); } else { - Size size = null; terminal = new ProgrammaticInTerminal(nonBlockingInput, cmdout, interactive, size); if (!interactive) { @@ -1312,6 +1311,7 @@ class ConsoleIOContext extends IOContext { private static class ProgrammaticInTerminal extends LineDisciplineTerminal { + protected static final int DEFAULT_WIDTH = 80; protected static final int DEFAULT_HEIGHT = 24; private final NonBlockingReader inputReader; @@ -1320,9 +1320,9 @@ class ConsoleIOContext extends IOContext { public ProgrammaticInTerminal(InputStream input, OutputStream output, boolean interactive, Size size) throws Exception { this(input, output, interactive ? "ansi" : "dumb", - size != null ? size : new Size(80, DEFAULT_HEIGHT), + size != null ? size : new Size(DEFAULT_WIDTH, DEFAULT_HEIGHT), size != null ? size - : interactive ? new Size(80, DEFAULT_HEIGHT) + : interactive ? new Size(DEFAULT_WIDTH, DEFAULT_HEIGHT) : new Size(Integer.MAX_VALUE - 1, DEFAULT_HEIGHT)); } @@ -1366,7 +1366,7 @@ class ConsoleIOContext extends IOContext { } catch (Throwable ex) { // ignore } - return new Size(80, h); + return new Size(DEFAULT_WIDTH, h); } public TestTerminal(InputStream input, OutputStream output) throws Exception { this(input, output, computeSize()); diff --git a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java index 0e9b3bf8bfb..2d06ffc529d 100644 --- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java +++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java @@ -80,6 +80,7 @@ import java.util.stream.StreamSupport; import jdk.internal.jshell.debug.InternalDebugControl; import jdk.internal.jshell.tool.IOContext.InputInterruptedException; +import jdk.internal.org.jline.terminal.Size; import jdk.jshell.DeclarationSnippet; import jdk.jshell.Diag; import jdk.jshell.EvalException; @@ -166,6 +167,7 @@ public class JShellTool implements MessageHandler { final Map envvars; final Locale locale; final boolean interactiveTerminal; + final Size windowSize; final Feedback feedback = new Feedback(); @@ -181,12 +183,13 @@ public class JShellTool implements MessageHandler { * @param prefs persistence implementation to use * @param envvars environment variable mapping to use * @param locale locale to use + * @param windowSize window size hint, or null */ JShellTool(InputStream cmdin, PrintStream cmdout, PrintStream cmderr, PrintStream console, InputStream userin, PrintStream userout, PrintStream usererr, PersistentStorage prefs, Map envvars, Locale locale, - boolean interactiveTerminal) { + boolean interactiveTerminal, Size windowSize) { this.cmdin = cmdin; this.cmdout = cmdout; this.cmderr = cmderr; @@ -203,6 +206,7 @@ public class JShellTool implements MessageHandler { this.envvars = envvars; this.locale = locale; this.interactiveTerminal = interactiveTerminal; + this.windowSize = windowSize; } private ResourceBundle versionRB = null; @@ -998,7 +1002,7 @@ public class JShellTool implements MessageHandler { }; Runtime.getRuntime().addShutdownHook(shutdownHook); // execute from user input - try (IOContext in = new ConsoleIOContext(this, cmdin, console, interactiveTerminal)) { + try (IOContext in = new ConsoleIOContext(this, cmdin, console, interactiveTerminal, windowSize)) { int indent; try { String indentValue = indent(); diff --git a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellToolBuilder.java b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellToolBuilder.java index 52e042d365a..8c787a6c294 100644 --- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellToolBuilder.java +++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellToolBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, 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 @@ -33,6 +33,7 @@ import java.util.Objects; import java.util.Set; import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; +import jdk.internal.org.jline.terminal.Size; import jdk.jshell.tool.JavaShellToolBuilder; /** @@ -53,6 +54,7 @@ public class JShellToolBuilder implements JavaShellToolBuilder { private Locale locale = Locale.getDefault(); private boolean interactiveTerminal; private boolean capturePrompt = false; + private Size windowSize = null; /** * Set the input channels. @@ -215,6 +217,16 @@ public class JShellToolBuilder implements JavaShellToolBuilder { return this; } + @Override + public JavaShellToolBuilder windowSize(int columns, int rows) { + if (columns <= 0) + throw new IllegalArgumentException("columns = " + columns); + if (rows <= 0) + throw new IllegalArgumentException("rows = " + rows); + this.windowSize = new Size(columns, rows); + return this; + } + /** * Create a tool instance for testing. Not in JavaShellToolBuilder. * @@ -228,7 +240,7 @@ public class JShellToolBuilder implements JavaShellToolBuilder { vars = System.getenv(); } JShellTool sh = new JShellTool(cmdIn, cmdOut, cmdErr, console, userIn, - userOut, userErr, prefs, vars, locale, interactiveTerminal); + userOut, userErr, prefs, vars, locale, interactiveTerminal, windowSize); sh.testPrompt = capturePrompt; return sh; } diff --git a/src/jdk.jshell/share/classes/jdk/jshell/tool/JavaShellToolBuilder.java b/src/jdk.jshell/share/classes/jdk/jshell/tool/JavaShellToolBuilder.java index c4b4bf66b33..06dd4d8ce1c 100644 --- a/src/jdk.jshell/share/classes/jdk/jshell/tool/JavaShellToolBuilder.java +++ b/src/jdk.jshell/share/classes/jdk/jshell/tool/JavaShellToolBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, 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 @@ -209,6 +209,24 @@ public interface JavaShellToolBuilder { return this; } + /** + * Provide a hint of the display window's dimensions when using an interactive terminal. + * + *

+ * When the input stream for this Java Shell is {@code System.in}, this setting is ignored. + * + * @implSpec Implementations may choose to ignore this method. The default implementation + * of this method returns {@code this}. + * + * @param columns number of displayed columns + * @param rows number of displayed rows + * @return the {@code JavaShellToolBuilder} instance + * @since 24 + */ + default JavaShellToolBuilder windowSize(int columns, int rows) { + return this; + } + /** * Run an instance of the Java shell tool as configured by the other methods * in this interface. This call is not destructive, more than one call of