GithubHelp home page GithubHelp logo

beryx / text-io Goto Github PK

View Code? Open in Web Editor NEW
338.0 338.0 46.0 9.77 MB

A library for creating interactive console applications in Java

Home Page: http://text-io.beryx.org/

License: Apache License 2.0

HTML 0.50% Java 78.40% Groovy 11.43% Shell 0.29% CSS 0.31% JavaScript 9.07%
console text-based

text-io's People

Contributors

hart-james avatar mattco98 avatar siordache avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

text-io's Issues

Error Message Provider for EnumInputReader with Numbered Values

It would be great if we had the possibility to replace the standard "Enter a value between 1 and X" error message in the EnumInputReader. I'm developing an application in Portuguese, so the default english message doesn't fit well.

By debugging i found that there isn't any checks for a Message Provider in the method getValueFromIndex of class InputReader:

private T getValueFromIndex(String sVal, TextTerminal<?> textTerminal) {
        try {
            int optIndex = Integer.parseInt(sVal);
            if (optIndex > 0 && optIndex <= this.possibleValues.size()) {
                return this.possibleValues.get(optIndex - 1);
            }
        } catch (NumberFormatException var4) {
        }

        textTerminal.executeWithPropertiesPrefix("error", (t) -> {
            textTerminal.print(this.getDefaultErrorMessage(sVal));
            textTerminal.println(" Enter a value between 1 and " + this.possibleValues.size() + ".");
        });
        textTerminal.println();
        return null;
}

Allow cumulative possible values and properties configurators

Hi.
At the moment, the methods with[Numbered]PossibleValues and withPropertiesConfigurator only apply globally, aka to all the possible choices.
It would be nice to be able to to define the possible values in a cumulative way and also pass the configurator to just that subset of possible values so to render them differently.
I know I can print all the properties manually and use an int reader as workaround to have the same behaviour, but it's quite ugly.

Does this feature make sense to you?

Cheers

Cookies on WebTextTerminal

Hello,

Was able to make progress quickly, the command line app is looking great thanks to Text-IO.

What is now missing is persistent memory. This can be done on the swing and command line interfaces very easily using files on disk for storage to remember a user that is logged, but not so trivial for the WebTextTerminal because the ContextHandlers don't seem to be exposed for usage. Otherwise would be possible to solve this by extracting URL paths and cookies.

Perhaps exposing the Context object from Ratpack is the simplest way? I imagine it is not easy to create a common mechanism for both spark and ratpack, on this case just needed for RatPack.

How would you recommend that we can access cookies and the URL from within Text-IO for the purpose of persistent user-memory? (to know who is logged inside the app).

Again: many, many thanks. Really good library.

Provide TextTerminal.printf

The example shows the output with String concatenation
TextTerminal terminal = textIO.getTextTerminal();
terminal.println("\nUser " + user + " is " + age + " years old, " +
"was born in " + month + " and has the password " + password + ".");

It would be easier to read if there is a printf method
TextTerminal terminal = textIO.getTextTerminal();
terminal.printf(
"\nUser %s is %s years old, was born in %s and has the password %s.",
user, age, month, password
);

how to save a history of previous input ?

Thanks to #17 that I now have the autocomplete setup for my program.

There are times that I would like to reenter the same input that I made in the past.

Is there an elegant way to program the Left and Right arrow keys to scroll backward and forward the input ?

I come up with this in SwingHandler but fall short of what to do next ?

    private static final String KEY_STROKE_LEFT = "pressed LEFT";
    private static final String KEY_STROKE_RIGHT = "pressed RIGHT";
    private String historyInput = "";
    private int historyIndex = -1;
    private String[] history = {};

  public SwingHandler(SwingTextTerminal terminal) {
        this.terminal = terminal;
        terminal.registerHandler(KEY_STROKE_LEFT, t -> {
            if (historyIndex >= 0) {
                historyIndex--;
                String text = (historyIndex < 0) ? historyInput : choices[historyIndex ];
                t.replaceInput(text, false);
            }
            return new ReadHandlerData(ReadInterruptionStrategy.Action.CONTINUE);
        });

Enhancement request: NullTerminal

It would be useful for testing purposes to have a terminal type that just throws away all output. Similar to /dev/null in Unix/Linux world.

Thanks,

-Tony

Timed Wait for Input

Hi,

I looked at APIs for text io and did not find timed wait for input. Did I miss it or is this something not supported in text io?

Thanks,
Brian

Print empty line/whitespace

How would you do this? I am using println("") but this leads to an issues where the next line of code is not executed so the terminal just lets you ype in input without any possible validation (Enter skips a line)

java.lang.UnsatisfiedLinkError: /root/wag_inst/tools/jre-linux/lib/libawt_xawt.so: libXrender.so.1: cannot open shared object file: No such file or directory

Ubuntu 22.04.3 LTS (minimal server)
Linux x64 JRE https://adoptium.net/de/temurin/releases/?version=17 use as portable (extract java archiv and set JAVA_HOME)

if we call final TextIO term = TextIoFactory.getTextIO(); we get the following Exception

Exception in thread "main" java.lang.UnsatisfiedLinkError: /root/wag_inst/tools/jre-linux/lib/libawt_xawt.so: libXrender.so.1: cannot open shared object file: No such file or directory
        at java.base/jdk.internal.loader.NativeLibraries.load(Native Method)
        at java.base/jdk.internal.loader.NativeLibraries$NativeLibraryImpl.open(Unknown Source)
        at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(Unknown Source)
        at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(Unknown Source)
        at java.base/java.lang.ClassLoader.loadLibrary(Unknown Source)
        at java.base/java.lang.Runtime.load0(Unknown Source)
        at java.base/java.lang.System.load(Unknown Source)
        at java.base/jdk.internal.loader.NativeLibraries.load(Native Method)
        at java.base/jdk.internal.loader.NativeLibraries$NativeLibraryImpl.open(Unknown Source)
        at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(Unknown Source)
        at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(Unknown Source)
        at java.base/jdk.internal.loader.NativeLibraries.findFromPaths(Unknown Source)
        at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(Unknown Source)
        at java.base/java.lang.ClassLoader.loadLibrary(Unknown Source)
        at java.base/java.lang.Runtime.loadLibrary0(Unknown Source)
        at java.base/java.lang.System.loadLibrary(Unknown Source)
        at java.desktop/java.awt.Toolkit$2.run(Unknown Source)
        at java.desktop/java.awt.Toolkit$2.run(Unknown Source)
        at java.base/java.security.AccessController.doPrivileged(Unknown Source)
        at java.desktop/java.awt.Toolkit.loadLibraries(Unknown Source)
        at java.desktop/java.awt.Toolkit.initStatic(Unknown Source)
        at java.desktop/java.awt.Toolkit.<clinit>(Unknown Source)
        at java.desktop/java.awt.Color.<clinit>(Unknown Source)
        at org.beryx.textio.jline.JLineTextTerminal.<clinit>(JLineTextTerminal.java:67)
        at org.beryx.textio.jline.JLineTextTerminalProvider.getTextTerminal(JLineTextTerminalProvider.java:32)
        at org.beryx.textio.TextIoFactory$Holder.getDefaultTerminal(TextIoFactory.java:95)
        at org.beryx.textio.TextIoFactory$Holder.<init>(TextIoFactory.java:65)
        at org.beryx.textio.TextIoFactory$Holder.<clinit>(TextIoFactory.java:54)
        at org.beryx.textio.TextIoFactory.getTextIO(TextIoFactory.java:111)

The TextConsole should work on a headless system. I think the problem is the use of awt classes (like java.awt.Color) in the text console.

workaround: apt-get install libxi6 libxtst6 libxext6 libxrender1

Disable Event Expansion for Strings Containing Exclamation Marks '!'

I've found text-io to be very useful while building a console based application but have run into an issue when using StringInputReader().

If a string is entered which contains '!' e.g. 'sometext!somemoretext', then jline.console.ConsoleReader attempts to expand events from the string which raises an exception...

java.lang.IllegalArgumentException: !somemoretext: event not found

...is it possible to disable event expansion for a StringInputReader, as this is not required for my application?

Submitted input can be deleted

So I noticed that I create a simple string input reader to get the user's name, after they've submitted the input they can backspace and it'll delete the submitted input.

Welcome, please enter your username:
Evan [Enter]

// Cursor is now on this line, however, I can backspace back to the beginning of the second line before typing input, yet you can't resubmit input.

Shouldn't submitting input be treated like a new line?

Making System console as default instead of JLint based console.

I am building a console application using text-io in intellij ide. I have added text-io:2.7.2 dependency in pom. I am creating terminal as TextIO textIO = TextIoFactory.getTextIO(). When I run this application in IDE, it opens a JLint based terminal.

Then I am using maven-shade plugin to create an uber jar. When I run this jar on mac terminal, it is throwing below error -

Exception in thread "main" java.lang.NoClassDefFoundError: javafx/scene/paint/Color
	at org.beryx.textio.jline.JLineTextTerminal.<clinit>(JLineTextTerminal.java:64)
	at org.beryx.textio.jline.JLineTextTerminalProvider.getTextTerminal(JLineTextTerminalProvider.java:32)
	at org.beryx.textio.TextIoFactory$Holder.getDefaultTerminal(TextIoFactory.java:95)
	at org.beryx.textio.TextIoFactory$Holder.<init>(TextIoFactory.java:65)
	at org.beryx.textio.TextIoFactory$Holder.<clinit>(TextIoFactory.java:54)
	at org.beryx.textio.TextIoFactory.getTextIO(TextIoFactory.java:111)
	at com.javastreets.jeegen.Main.main(Main.java:12)
Caused by: java.lang.ClassNotFoundException: javafx.scene.paint.Color
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 7 more

I want to use the standard console/terminal, how to default the TextIOFactory to use console instead of JLint.

Using below gets me what I wanted but just wondering if there is better way of doing that with TextIOFactory -

TextIO textIO = new TextIO(new ConsoleTextTerminalProvider().getTextTerminal());

And, thanks for this cool libarby 👍 !

How to restart gracefully

How do I restart a SwingTextTerminal gracefully without quitting the application ?

I have a main application running side-by-side with a SwingTextTerminal console in Windows.

e.g. I have a while loop that set up a menu for querying things.

		while (keepRunning) {
			     
		    BiConsumer<TextIO, RunnerData> menu = chooseMenu(textIO);
		    terminal.printf(System.lineSeparator());
	       
		    // Set up the prompt for the menu
		    menu.accept(textIO, null);
	        
		    // if the sim is being saved, enter this while loop
			while (masterClock.isSavingSimulation()) {
		    	delay(500L);
		    }
		}
	}
   /**
     * Presents choices in the console menu
     * 
     * @param textIO
     * @return {@link BiConsumer}
     */
    private static BiConsumer<TextIO, RunnerData> chooseMenu(TextIO textIO) {
        List<BiConsumer<TextIO, RunnerData>> apps = Arrays.asList(
        		chatMenu,
                new AutosaveMenu(),
                new SaveMenu(),
                new TimeRatioMenu(),
                new LogMenu(),
                new ExitMenu()
        );
       
        BiConsumer<TextIO, RunnerData> app = textIO.<BiConsumer<TextIO, RunnerData>>newGenericInputReader(null)
            .withNumberedPossibleValues(apps)
            .read(System.lineSeparator() 
            		+ "-------------------  C O N S O L E   M E N U  -------------------" 
            		+ System.lineSeparator());
        String propsFileName = app.getClass().getSimpleName() + ".properties";
        System.setProperty(AbstractTextTerminal.SYSPROP_PROPERTIES_FILE_LOCATION, propsFileName);
//        profile.term().moveToLineStart();	    
        return app;
    }

Previously, when I call terminal.dispose(null) to end the SwingTextTerminal instance, it would crash.

So I end up always calling system.exit(0) to end everything (the main application and the beryx terminal).

But what if I simply want to quit the existing terminal that has been corrupted and restart it since I want to keep the main application running ?

How do I do that ?

Specific Maven example for WebTextTerminal

Hallo Serban,

Many thanks for making available text-io, I think it is fantastic and the best tool in the java world for providing a command line regardless of the interface.

Both the console and swing versions worked great out of the box, was possible to learn how to use them very quickly. My difficulty is with the WebTexTerminal. I'm struggling to get it working under Maven without success so far. I'm able to compile the Gradle demo, but unable to port this into the maven project. The documentation available on this part I'm unfortunately unable to follow and understand what is missing.

Would it be possible to ask for a quick demo specifically written in Maven just for the WebTextTerminal?

Many thanks in advance.

refresh line

Is there a way to go beyond changing the value on the whole screen or the value on, say, the 5th line from the bottom of the screen ?

I can see in the Weather that it calls terminal.resetLine() and terminal.moveToLineStart() to refresh the value of the very last line on the screen.

In TextTerminal, there is :

    @Override
    public boolean resetLine() {
        return resetToOffset(startLineOffset);
    }

    @Override
    public boolean moveToLineStart() {
        overwriteOffset = startLineOffset;
        return true;
    }

We can literally build a game out of the text terminal if we can give the ability to change the value of a text with, say, overwrite(x,y), where x being the x-th position from the left, y being the y-th line from the bottom.

How to change the prompt for a EnumInputReader?

  private static Operacao escolherUmaOperacao() {
      return IO.getTextIO().newEnumInputReader(Operacao.class)
              .withInvalidIndexErrorMessagesProvider((s, s1, i, i1) ->
                      Collections.singletonList("Opção inválida. Digite um número de " + i + " até " + i1))
              .withValueFormatter(Operacao::getNome)
              .read("Escolha uma operação: ");
  }

I'd like to change this text right here:
image

I've tried accessing the method printPrompt which is inherited from org.beryx.textio.InputReader but it cannot be accessed.

3.4.1 version is installed

Any way to get TextTerminal.print method to handle \r ?

I would like to use the print method of TextTerminal to output a line that is continually updated. In past, I was able to accomplish this using \r at the end of printf format string. So far, I have been unable to get this working with TextIO. Is there any way to accomplish this?

Thanks again,

-Tony

Shutdown CTRL+C

It seems that the console is not responding to the regular CTRL+C event(both System.console and swing terminal ), this is a limitation?

prompt input

How do I programmatically input something in a prompt ?

Say, I want to run a demo of how to make an input in a prompt.

Is there something in SwingHandler that I can use in order to simulate manually typing in something and hit the enter ?

Thanks !

Input masking doesn't work with SystemTextTerminal

Sample code:

import org.beryx.textio.TextIO;
import org.beryx.textio.system.SystemTextTerminal;

public class Test
{
    public static void main(String[] args)
    {
        final SystemTextTerminal terminal = new SystemTextTerminal();
        final TextIO             textIO   = new TextIO(terminal);

        final String password = textIO.newStringInputReader()
            .withMinLength(1)
            .withInputMasking(true)
            .read("Password");
    }
}

Result:

textio-input-masking

Java version:

C:\tmp\textio>java -version
openjdk version "17.0.1" 2021-10-19
OpenJDK Runtime Environment Temurin-17.0.1+12 (build 17.0.1+12)
OpenJDK 64-Bit Server VM Temurin-17.0.1+12 (build 17.0.1+12, mixed mode, sharing)

Expected result is for the input to be masked and the typed characters to be invisible.

Add registerHandler for key 'TAB'

It's very usefull register TAB for special command in registerHandler.
For example as in linux terminal, TAB tips for commands.
Now I cannot register simple "TAB" or "TAB TAB".

May be add method of add special "key sequence" by hand and check it in registerHandler.

Change error messages

Hi,
I'm still clueless to change error message when using text-io, do I need to call withParseErrorMessagesProvider for every input reader that have been made?

Thanks.

Clear the console

Is there a way or a feature to clear the console using this library?
Standard way using System.out.print("\033[H\033[2J"); is not working.

TextTerminal is a raw type. References to generic type TextTerminal<T> should be parameterized

I see a Java compiler warning when declaring a variable of type TextTerminal:

TextTerminal is a raw type. References to generic type TextTerminal should be parameterized

I can get around the issue by declaring the variable like this:

TextTerminal<?> terminal = textIO.getTextTerminal();

I'm curious why you chose to make this type generic. In other words, what benefit is there?

Thanks in advance.

-Tony

Java 21 breaks the terminal font

Hey!
I am using the textio library in one of my projects, where I create a terminal using this code:

private final TextIO textIO;
private final TextTerminal<?> terminal;
//...
this.textIO = TextIoFactory.getTextIO();
this.terminal = textIO.getTextTerminal();

But since upgrading to Java 21 the terminal has a new font and isn't monofont.
Is this a known bug, or is my configuration lacking?

Note: It worked perfectly fine in java 18 and this only happens on Windows.

How it looks now

image

How it looked before

image

autocomplete using up and down arrow key

how do I even begin to implement some sort of autocomplete at the input cursor by using up and down arrow keys ?

I suppose this will be a nice feature for text-io that others are interested in.

Say I have List<String> names = Arrays.asList("albert", "alice", "ava", "betty", "cathy");

So when asked about inputting a name, at the input prompt, if I type in the first letter as "a", (but before typing in the second letter), and I hit the up arrow key, I would like the word "albert" to pop up at the input prompt.

I suppose I'll need to write my own methods to implement the nitty gritty.

Can someone show me first on how to capture the input before hitting enter ?

How do I make use of the up and down arrow keys. Is it by registering handlers and how ?

Thanks!

MockTextTerminal strips out new lines

On calling org.beryx.textio.mock.MockTextTerminal#getOutput the returned string has all the new lines and leading/trailing spaces removed because org.beryx.textio.mock.MockTextTerminal#stripAll is called on the stored string before returning it.

Given that the output is joined using the new line as separator, I assume this has been done in order to have a uniform and linear output.
Unfortunately, this doesn't allow to test certain scenarios, like "Does the output ends with a new line?".

In my opinion, stripping should be an option that the consumer of the class can decide to use or not.
A simple overload of getOutput() with a boolean flag would be enough :)

How to use MockTextTerminal

Hi.
Can you please provide some documentation or guidance on how to use the MockTextTerminal?
I would like to unit-test my business logic and the example in the repository with the Robot is not really adequate for unit tests (given the definition of unit test).

Kind regards and thanks in advance.

Add ability to print from another thread

My usecase:
By default I'm waiting for some input from user. But sometimes my program's background thread needs to print some output. If I do this — this outputs is being inserted as answer into console and, of course, it's not correct behaviour.
Minimalistic example:

        fun main(args: Array<String>) {
            thread {
                Thread.sleep(3000)
                textio.textTerminal.println("Some text here")
                Thread.sleep(1000)
                textio.textTerminal.println("Some text here")
            }
            textio
                    .newStringInputReader()
                    .withMaxLength(2)
                    .read("some input")
        }

Is it possible to make terminal redraw question if another thread is trying to print something?

Multi-line paste use case

I have a use case where I'm attempting to use text-io to accept some command line input where I expect the user to paste in a multi-line block of text. Is there a graceful way to handle this?

Suggestion logger

I think it would be awesome to have a function allowing change the logger from debug to any other mode. For example, I would like to change the standard debug mode to something like error or even off.

Thanks,

how to prevent cursor from moving

Hi,

How do I defensively "fix" the position of the blinking cursor right at the line of the most recent input ?

Currently, the up, down, left, right arrow key can move the cursor key elsewhere on the terminal, which is undesirable, especially that the user may not know that the cursor key needs to be returned to that same spot in order to continue to type the input.

Thanks much for this great API !

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.