diff --git a/.gitignore b/.gitignore index 0d379eafe..c3b46be68 100644 --- a/.gitignore +++ b/.gitignore @@ -117,3 +117,6 @@ fabric.properties /use-assembly/target **/.DS_Store + +# Claude Code +.claude/ diff --git a/INSTALL b/INSTALL index c060eda80..b2d2769db 100644 --- a/INSTALL +++ b/INSTALL @@ -29,16 +29,13 @@ Otherwise, a simple "mvn compile" or "mwn verify" should compile the whole USE package. "mvn verify" will run all tests whereas "mvn compile" just compiles. -Interaction with USE is done via a command line interface. This will -be much more comfortable if you have the GNU readline library -available on your system. USE provides an interface to the readline -library. For example, it allows bash or emacs-like editing of lines -and keeps a history file of recent input. Since the readline library -is platform dependent, the interface has to be compiled on your -system. Changes to the build file may be necessary for your -environment. If you don't have the readline library - don't worry. -USE will fall back to a simple input mechanism if it cannot find or -load the readline library at runtime. +Interaction with USE is done via a command line interface. It uses the +pure-Java JLine library to provide comfortable line editing (bash or +emacs-like) and to keep a history file of recent input. JLine works out +of the box on Linux, macOS and Windows, so no platform-dependent native +library has to be built or installed. When USE is run without an +interactive terminal (for example with piped input), it automatically +falls back to a simple input mechanism. diff --git a/NEWS b/NEWS index 95c0f3365..12f557a62 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,10 @@ Please see the file `README' for a description of how to report bugs. ** Changes between version 7.1.0 and X.X.X * USE now supports data types +* The interactive command line now uses the pure-Java JLine library for line + editing and history instead of the native GNU readline library. This removes + the native build step and provides command-line editing on Windows, macOS + and Linux out of the box. ** Changes between version 5.2.0 and 6.0.0 * New OCL complexity plugin diff --git a/README.md b/README.md index 323637266..7974f96f0 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,7 @@ the web. - The [ANTLR parser generator tool](http://www.antlr.org) - The [JUnit library](http://www.junit.org) +- The [JLine library](https://github.com/jline/jline2) for command-line editing and history ## Reporting bugs diff --git a/use-core/src/main/java/module-info.java b/use-core/src/main/java/module-info.java index 350e9e572..4413df9d9 100644 --- a/use-core/src/main/java/module-info.java +++ b/use-core/src/main/java/module-info.java @@ -8,6 +8,7 @@ requires java.scripting; requires org.jruby.dist; requires combinatoricslib; + requires jline; requires java.datatransfer; requires java.desktop; exports org.tzi.use.config; diff --git a/use-core/src/main/java/org/tzi/use/config/Options.java b/use-core/src/main/java/org/tzi/use/config/Options.java index 9064cdb5e..e14948684 100644 --- a/use-core/src/main/java/org/tzi/use/config/Options.java +++ b/use-core/src/main/java/org/tzi/use/config/Options.java @@ -117,9 +117,7 @@ public static String getIconPath(String iconName) { * Otherwise, only the shell is available. */ public static boolean doGUI = true; - - public static boolean suppressWarningsAboutMissingReadlineLibrary = false; - + public static boolean quiet = false; private static boolean debug = false; @@ -246,7 +244,7 @@ private static void printHelp() { System.out.println(" -noplugins do not use plugins"); System.out.println(" -h print help"); System.out.println(" -H=path home of use installation"); - System.out.println(" -nr suppress warnings about missing readline library"); + System.out.println(" -nr deprecated, ignored (kept for backward compatibility)"); System.out.println(" -q reads spec_file, executes cmd_file, and checks constraints"); System.out.println(" exit code is 1 if constraints fail, otherwise 0"); System.out.println(" -qv like -q but with verbose output of constraint check"); @@ -306,7 +304,6 @@ public static void resetOptions() { compileOnly = false; compileAndPrint = false; doGUI = true; - suppressWarningsAboutMissingReadlineLibrary = false; quiet = false; debug = false; quietAndVerboseConstraintCheck = false; @@ -356,8 +353,9 @@ public static void processArgs(String[] args) { System.err.println("Invalid path " + StringUtil.inQuotes(arg.substring(2)) + " for home directory specified."); System.exit(1); } - } else if (arg.equals("nr")) { - suppressWarningsAboutMissingReadlineLibrary = true; + } else if (arg.equals("nr")) { + // Deprecated: the GNU readline library is no longer used. + // Accepted as a no-op for backward compatibility. } else if (arg.equals("q")) { Options.quiet = true; Options.doGUI = false; diff --git a/use-core/src/main/java/org/tzi/use/util/input/GNUReadline.java b/use-core/src/main/java/org/tzi/use/util/input/GNUReadline.java deleted file mode 100644 index bc73cac61..000000000 --- a/use-core/src/main/java/org/tzi/use/util/input/GNUReadline.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * USE - UML based specification environment - * Copyright (C) 1999-2004 Mark Richters, University of Bremen - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -package org.tzi.use.util.input; - -import java.io.IOException; - -/** - * Native wrapper for the GNU Readline Library. - * - * Don't use this directly since it may no be available on all - * platforms. Use LineInput.getReadline() to get an appropriate - * implementation instead. - * - * @author Mark Richters - */ -public class GNUReadline implements Readline { - - static { - System.loadLibrary("natGNUReadline"); - } - - public native String readline(String prompt); - public native void usingHistory(); - public native void readHistory(String filename) throws IOException; - public native void writeHistory(String filename) throws IOException; - public native void close(); - public boolean doEcho() { - return false; - } -} diff --git a/use-core/src/main/java/org/tzi/use/util/input/JLineReadline.java b/use-core/src/main/java/org/tzi/use/util/input/JLineReadline.java new file mode 100644 index 000000000..aa957a00f --- /dev/null +++ b/use-core/src/main/java/org/tzi/use/util/input/JLineReadline.java @@ -0,0 +1,95 @@ +/* + * USE - UML based specification environment + * Copyright (C) 1999-2004 Mark Richters, University of Bremen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +package org.tzi.use.util.input; + +import jline.console.ConsoleReader; +import jline.console.history.FileHistory; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * A {@link Readline} implementation backed by the pure-Java + * JLine library. It provides + * line editing and a persistent command history on all platforms (Linux, + * macOS and Windows) without requiring a platform-dependent native library. + * + *

This replaces the former JNI binding to the native GNU readline library + * and removes the corresponding native build steps.

+ * + * @author Mark Richters + */ +public class JLineReadline implements Readline { + + private final ConsoleReader reader; + private FileHistory history; + + public JLineReadline() throws IOException { + this(null, null); + } + + /** + * Package-private constructor used by tests to supply explicit streams + * instead of attaching to the real terminal. + */ + JLineReadline(InputStream in, OutputStream out) throws IOException { + reader = (in != null && out != null) + ? new ConsoleReader(in, out) + : new ConsoleReader(); + // USE uses '!' and '!!' to start SOIL statements. Disable JLine's + // history expansion so these characters are passed through verbatim. + reader.setExpandEvents(false); + } + + @Override + public String readline(String prompt) throws IOException { + return reader.readLine(prompt); + } + + @Override + public void usingHistory() { + reader.setHistoryEnabled(true); + } + + @Override + public void readHistory(String filename) throws IOException { + history = new FileHistory(new File(filename)); + reader.setHistory(history); + } + + @Override + public void writeHistory(String filename) throws IOException { + if (history != null) { + history.flush(); + } + } + + @Override + public void close() throws IOException { + reader.shutdown(); + } + + @Override + public boolean doEcho() { + return false; + } +} diff --git a/use-core/src/main/java/org/tzi/use/util/input/LineInput.java b/use-core/src/main/java/org/tzi/use/util/input/LineInput.java index 729a483b1..16a20ef2d 100644 --- a/use-core/src/main/java/org/tzi/use/util/input/LineInput.java +++ b/use-core/src/main/java/org/tzi/use/util/input/LineInput.java @@ -20,47 +20,45 @@ package org.tzi.use.util.input; import java.io.BufferedReader; +import java.io.IOException; import java.io.InputStreamReader; /** - * Interface for getting a suitable platform-dependent readline - * implementation. The GNU readline library is preferably used if - * installed. - * - * @author Mark Richters + * Factory for obtaining a suitable {@link Readline} implementation. + * + *

For interactive use the pure-Java {@link JLineReadline} is returned, + * providing line editing and command history on all platforms. When no + * interactive terminal is available (e.g. the input is piped or USE runs in + * a headless environment) a plain {@link StreamReadline} reading from + * {@code System.in} is used instead.

+ * + * @author Mark Richters */ public class LineInput { // utility class private LineInput() {} - + /** - * Returns a readline implementation. If the native GNU readline - * library is available, return that. Otherwise, a stream readline - * implementation with System.in as source is returned. - * - * @param errorMessage if not null print a message when the native - * GNU readline library is not available, otherwise - * fail silently. + * Returns a {@link Readline} implementation for reading interactive user + * input. A JLine-backed implementation is used when a terminal is + * available; otherwise a simple stream-based implementation reading from + * {@code System.in} is returned. */ - public static Readline getUserInputReadline(String errorMessage) { - Readline rl = null; - try { - System.loadLibrary("natGNUReadline"); - rl = new GNUReadline(); - } catch (UnsatisfiedLinkError ex) { - if (errorMessage != null ) { - System.out.println(ex.toString()); - System.out.println(errorMessage); + public static Readline getUserInputReadline() { + if (System.console() != null) { + try { + return new JLineReadline(); + } catch (IOException ex) { + // JLine could not attach to the terminal; fall back below. } - BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); - // no echo, do protocol - rl = new StreamReadline(reader, false); } - return rl; + BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + // no echo, do protocol + return new StreamReadline(reader, false); } - public static Readline getStreamReadline(BufferedReader reader, boolean doEcho, String string) { - return new StreamReadline(reader, doEcho, string); + public static Readline getStreamReadline(BufferedReader reader, boolean doEcho, String prompt) { + return new StreamReadline(reader, doEcho, prompt); } } diff --git a/use-core/src/main/java/org/tzi/use/util/input/Readline_test.java b/use-core/src/main/java/org/tzi/use/util/input/Readline_test.java index 38863288f..b4c002230 100644 --- a/use-core/src/main/java/org/tzi/use/util/input/Readline_test.java +++ b/use-core/src/main/java/org/tzi/use/util/input/Readline_test.java @@ -29,7 +29,7 @@ class Readline_test { public static void main(String[] args) { - Readline rl = LineInput.getUserInputReadline("readline library not found"); + Readline rl = LineInput.getUserInputReadline(); String line; try { do { diff --git a/use-core/src/main/java/org/tzi/use/util/input/natGNUReadline.c b/use-core/src/main/java/org/tzi/use/util/input/natGNUReadline.c deleted file mode 100644 index 7a4d73f42..000000000 --- a/use-core/src/main/java/org/tzi/use/util/input/natGNUReadline.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * USE - UML based specification environment - * Copyright (C) 1999-2004 Mark Richters, University of Bremen - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* $ProjectHeader: use 0.393 Wed, 16 May 2007 14:10:28 +0200 opti $ */ - -#include -#include "org_tzi_use_util_input_GNUReadline.h" -#include -#include -#include -#include - -/* - * Class: org_tzi_use_util_input_GNUReadline - * Method: prepareClose - * Signature: ()V - */ -JNIEXPORT void JNICALL -Java_org_tzi_use_util_input_GNUReadline_close(JNIEnv *env, - jobject obj) -{ - - rl_done = 1; - rl_free_line_state(); - rl_deprep_terminal(); -} - -/* - * Class: org_tzi_use_util_input_GNUReadline - * Method: readline - * Signature: (Ljava/lang/String;)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL -Java_org_tzi_use_util_input_GNUReadline_readline(JNIEnv *env, - jobject obj, - jstring prompt) -{ - jstring result; - char *line; - const char *cprompt = (*env)->GetStringUTFChars(env, prompt, 0); - - /* Get a line from the user. */ - line = readline((char *) cprompt); - - /* If the line has any text in it, save it on the history. */ - if ( line && *line) - add_history(line); - - /* Create the Java result string object. */ - result = (*env)->NewStringUTF(env, line); - - /* Free memory. */ - (*env)->ReleaseStringUTFChars(env, prompt, cprompt); - free(line); - - return result; -} - -/* - * Class: org_tzi_use_util_input_GNUReadline - * Method: usingHistory - * Signature: ()V - */ -JNIEXPORT void JNICALL -Java_org_tzi_use_util_input_GNUReadline_usingHistory(JNIEnv *env, - jobject obj) -{ - using_history(); -} - -/* - * Class: org_tzi_use_util_input_GNUReadline - * Method: readHistory - * Signature: (Ljava/lang/String;)V - */ -JNIEXPORT void JNICALL -Java_org_tzi_use_util_input_GNUReadline_readHistory(JNIEnv *env, - jobject obj, - jstring filename) -{ - const char *cfilename = (*env)->GetStringUTFChars(env, filename, 0); - int res = read_history((char *) cfilename); - if ( res ) { - /* Could not read file, res == errno */ - char *msg = strerror(res); - jclass io_exception = (*env)->FindClass(env, "java/io/IOException"); - (*env)->ThrowNew(env, io_exception, msg); - } - return; -} - -/* - * Class: org_tzi_use_util_input_GNUReadline - * Method: writeHistory - * Signature: (Ljava/lang/String;)V - */ -JNIEXPORT void JNICALL -Java_org_tzi_use_util_input_GNUReadline_writeHistory(JNIEnv *env, - jobject obj, - jstring filename) -{ - const char *cfilename = (*env)->GetStringUTFChars(env, filename, 0); - int res = write_history((char *) cfilename); - if ( res ) { - /* Could not write file, res == errno */ - char *msg = strerror(res); - jclass io_exception = (*env)->FindClass(env, "java/io/IOException"); - (*env)->ThrowNew(env, io_exception, msg); - } - return; -} diff --git a/use-core/src/test/java/org/tzi/use/util/input/JLineReadlineTest.java b/use-core/src/test/java/org/tzi/use/util/input/JLineReadlineTest.java new file mode 100644 index 000000000..13734b3e8 --- /dev/null +++ b/use-core/src/test/java/org/tzi/use/util/input/JLineReadlineTest.java @@ -0,0 +1,94 @@ +/* + * USE - UML based specification environment + * Copyright (C) 1999-2004 Mark Richters, University of Bremen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +package org.tzi.use.util.input; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.file.Path; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Tests for the new JLine-backed {@link JLineReadline}. + * + *

A package-private constructor accepting explicit streams is used so the + * tests never need to attach to a real terminal.

+ */ +class JLineReadlineTest { + + private static JLineReadline readingFrom(String input) throws IOException { + return new JLineReadline(new ByteArrayInputStream(input.getBytes()), new ByteArrayOutputStream()); + } + + @Test + void readline_returnsInputLine() throws IOException { + try (var rl = readingFrom("hello\n")) { + assertEquals("hello", rl.readline("prompt> ")); + } + } + + @Test + void readline_returnsNullAtEndOfStream() throws IOException { + try (var rl = readingFrom("")) { + assertNull(rl.readline("prompt> ")); + } + } + + @Test + void doEcho_returnsFalse() throws IOException { + try (var rl = readingFrom("")) { + assertFalse(rl.doEcho()); + } + } + + @Test + void usingHistory_doesNotThrow() throws IOException { + try (var rl = readingFrom("")) { + assertDoesNotThrow(rl::usingHistory); + } + } + + @Test + void writeHistory_persistsEnteredCommandsToFile(@TempDir Path tmp) throws IOException { + Path histFile = tmp.resolve(".use_history_test"); + + try (var rl = new JLineReadline( + new ByteArrayInputStream("cmd1\ncmd2\n".getBytes()), new ByteArrayOutputStream())) { + rl.usingHistory(); + rl.readHistory(histFile.toString()); + rl.readline("> "); + rl.readline("> "); + rl.writeHistory(histFile.toString()); + } + + assertTrue(histFile.toFile().exists(), "history file should be created"); + assertTrue(histFile.toFile().length() > 0, "history file should not be empty"); + } + + @Test + void close_doesNotThrow() throws IOException { + var rl = readingFrom(""); + assertDoesNotThrow(rl::close); + } +} diff --git a/use-core/src/test/java/org/tzi/use/util/input/LineInputTest.java b/use-core/src/test/java/org/tzi/use/util/input/LineInputTest.java new file mode 100644 index 000000000..25991794e --- /dev/null +++ b/use-core/src/test/java/org/tzi/use/util/input/LineInputTest.java @@ -0,0 +1,70 @@ +/* + * USE - UML based specification environment + * Copyright (C) 1999-2004 Mark Richters, University of Bremen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +package org.tzi.use.util.input; + +import org.junit.jupiter.api.Test; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Characterization (safety-net) tests for the {@link LineInput} factory. + * + *

These cover the stable {@code getStreamReadline} factory method whose + * behaviour must be preserved across the migration to JLine.

+ */ +class LineInputTest { + + @Test + void getStreamReadline_returnsReadlineThatReadsTheStream() throws IOException { + BufferedReader reader = new BufferedReader(new StringReader("test line\n")); + try (Readline rl = LineInput.getStreamReadline(reader, false, "")) { + assertEquals("test line", rl.readline("> ")); + } + } + + @Test + void getStreamReadline_withoutEcho_doEchoIsFalse() { + BufferedReader reader = new BufferedReader(new StringReader("")); + Readline rl = LineInput.getStreamReadline(reader, false, ""); + assertFalse(rl.doEcho()); + } + + @Test + void getStreamReadline_withEcho_doEchoIsTrue() { + BufferedReader reader = new BufferedReader(new StringReader("")); + Readline rl = LineInput.getStreamReadline(reader, true, ""); + assertTrue(rl.doEcho()); + } + + @Test + void getUserInputReadline_returnsNonNullNonEchoingReadline() { + // The interactive factory must always yield a usable, non-echoing + // Readline. Whether that is a JLineReadline (interactive terminal) + // or the StreamReadline fallback (headless/piped) depends on the + // environment, but the behavioural contract is the same. + Readline rl = LineInput.getUserInputReadline(); + assertNotNull(rl); + assertFalse(rl.doEcho()); + } +} diff --git a/use-core/src/test/java/org/tzi/use/util/input/StreamReadlineTest.java b/use-core/src/test/java/org/tzi/use/util/input/StreamReadlineTest.java new file mode 100644 index 000000000..04b1c2359 --- /dev/null +++ b/use-core/src/test/java/org/tzi/use/util/input/StreamReadlineTest.java @@ -0,0 +1,100 @@ +/* + * USE - UML based specification environment + * Copyright (C) 1999-2004 Mark Richters, University of Bremen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +package org.tzi.use.util.input; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.nio.file.Path; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Characterization (safety-net) tests for {@link StreamReadline} — the + * fallback {@link Readline} implementation used when no interactive terminal + * is available. + * + *

These tests pin down the behaviour of the existing implementation so we + * can be confident the migration from native GNU readline to JLine does not + * change the contract every {@link Readline} must satisfy.

+ */ +class StreamReadlineTest { + + private static StreamReadline from(String input) { + return new StreamReadline(new BufferedReader(new StringReader(input)), false); + } + + @Test + void readline_returnsInputLineWithoutLineTerminator() throws IOException { + try (var rl = from("hello\n")) { + assertEquals("hello", rl.readline("prompt> ")); + } + } + + @Test + void readline_returnsNullAtEndOfStream() throws IOException { + try (var rl = from("")) { + assertNull(rl.readline("prompt> ")); + } + } + + @Test + void readline_handlesMultipleLinesThenEof() throws IOException { + try (var rl = from("first\nsecond\n")) { + assertEquals("first", rl.readline("> ")); + assertEquals("second", rl.readline("> ")); + assertNull(rl.readline("> ")); + } + } + + @Test + void doEcho_isFalseByDefault() { + assertFalse(from("").doEcho()); + } + + @Test + void doEcho_isTrueWhenConstructedWithEcho() { + var rl = new StreamReadline(new BufferedReader(new StringReader("")), true); + assertTrue(rl.doEcho()); + } + + @Test + void usingHistory_isANoOp() { + assertDoesNotThrow(() -> from("").usingHistory()); + } + + @Test + void readHistory_isANoOp(@TempDir Path tmp) { + assertDoesNotThrow(() -> from("").readHistory(tmp.resolve("history").toString())); + } + + @Test + void writeHistory_isANoOp(@TempDir Path tmp) { + assertDoesNotThrow(() -> from("").writeHistory(tmp.resolve("history").toString())); + } + + @Test + void close_doesNotThrow() { + assertDoesNotThrow(() -> from("").close()); + } +} diff --git a/use-gui/src/main/java/org/tzi/use/main/shell/Shell.java b/use-gui/src/main/java/org/tzi/use/main/shell/Shell.java index ce5c49d93..4afcdfb4c 100644 --- a/use-gui/src/main/java/org/tzi/use/main/shell/Shell.java +++ b/use-gui/src/main/java/org/tzi/use/main/shell/Shell.java @@ -268,18 +268,7 @@ private void setupReadline() { return; } - String GNUReadlineNotAvailable; - if (Options.suppressWarningsAboutMissingReadlineLibrary) { - GNUReadlineNotAvailable = null; - } else { - GNUReadlineNotAvailable = "Apparently, the GNU readline library is not available on your system." - + Options.LINE_SEPARATOR - + "The program will continue using a simple readline implementation." - + Options.LINE_SEPARATOR - + "You can turn off this warning message by using the switch -nr"; - } - - fReadline = LineInput.getUserInputReadline(GNUReadlineNotAvailable); + fReadline = LineInput.getUserInputReadline(); fReadline.usingHistory(); // Read command history from previous sessions diff --git a/use-gui/src/main/resources/bin/start_use.bat b/use-gui/src/main/resources/bin/start_use.bat index 3b07f5c16..30c7131ad 100644 --- a/use-gui/src/main/resources/bin/start_use.bat +++ b/use-gui/src/main/resources/bin/start_use.bat @@ -21,9 +21,9 @@ IF NOT EXIST %USE_JAR% ( REM Check if first argument is "jfx" (/I makes the comparison case-insensitive) IF /I "%1"=="-jfx" ( - java %VMARGS% --module-path %JAVAFX_LIB% --add-modules javafx.controls,javafx.fxml,javafx.web,javafx.graphics,javafx.swing --add-opens javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED --add-exports javafx.base/com.sun.javafx.event=ALL-UNNAMED -jar %USE_JAR% -nr %* + java %VMARGS% --module-path %JAVAFX_LIB% --add-modules javafx.controls,javafx.fxml,javafx.web,javafx.graphics,javafx.swing --add-opens javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED --add-exports javafx.base/com.sun.javafx.event=ALL-UNNAMED -jar %USE_JAR% %* ) ELSE ( - java %VMARGS% -jar %USE_JAR% -nr %* + java %VMARGS% -jar %USE_JAR% %* ) if "%OS%"=="Windows_NT" @endlocal diff --git a/use-gui/src/main/resources/bin/use b/use-gui/src/main/resources/bin/use index ce8c0b78b..cde6bb5e1 100755 --- a/use-gui/src/main/resources/bin/use +++ b/use-gui/src/main/resources/bin/use @@ -16,7 +16,5 @@ if [ ! -f "$USE_JAR" ]; then exit 1 fi -export LD_LIBRARY_PATH="$USE_HOME/lib:$LD_LIBRARY_PATH" - # set cmd for running USE java $VMARGS -jar "$USE_JAR" "$@"