Skip to content

Using line readers

mattirn edited this page Nov 9, 2021 · 6 revisions

Line readers are used to read an input line from the console, usually a command line that follow a known syntax that can be leveraged using a highlighter and parser.

Simple line reading

For REPL style programs, one can use a simple loop:

    LineReader reader = LineReaderBuilder.builder().build();
    String prompt = ...;
    while (true) {
        String line = null;
        try {
            line = reader.readLine(prompt);
        } catch (UserInterruptException e) {
            // Ignore
        } catch (EndOfFileException e) {
            return;
        }
        ...
    }

Various calls

There are a few overridden readLine methods that takes various parameters, depending on the use cases. They all delegate to the most generic one which is:

  String readLine(String prompt, String rightPrompt, Character mask, String buffer) throws UserInterruptException, EndOfFileException;
  • prompt is the unexpanded prompt pattern that will be displayed to the user on the left of the input line
  • rightPrompt is the unexpanded prompt pattern that will be displayed on the right of the first input line
  • mask is the character used to hide user input (when reading a password for example)
  • buffer is the initial content of the input line

Widgets and key mapping

JLine has a couple of builtin widgets: AutoPairWidgets, AutosuggestionWidgets and TailTipWidgets.

Example:

Create test-widget that read widget name from LineReader buffer and execute it. Bind the created widget to the keystroke ctrl-alt-x

    import static org.jline.keymap.KeyMap.ctrl;
    import static org.jline.keymap.KeyMap.alt;
    import org.jline.reader.LineReader;
    import org.jline.reader.Reference;

    public static class MyWidgets extends org.jline.widget.Widgets {
        
        public MyWidgets(LineReader reader) {
            super(reader);
            addWidget("test-widget", this::testWidget);
            getKeyMap().bind(new Reference("test-widget"), alt(ctrl('X')));
        }

        public boolean testWidget() {
            try {
                String name = buffer().toString().split('\\s+')[0]
                reader.callWidget(name);
            } catch (Exception e) {
                return false;
            }
            return true;
        }
    }

See the same example on REPL console using JLine builtin commands.