Skip to main content

Line Reading

The LineReader is one of JLine's core components, providing sophisticated line editing capabilities for your command-line applications. It allows reading lines from a terminal, with full input/line editing.

Creating a LineReader

Use the LineReaderBuilder to create a LineReader instance:

Terminal terminal = ...;
LineReader lineReader = LineReaderBuilder.builder()
.terminal(terminal)
.build();

Loading snippet: LineReaderCreationExample...

LineReader Building Options

The builder can be customized to create more suitable line readers:

LineReader lineReader = LineReaderBuilder.builder()
.terminal(terminal)
.completer(new MyCompleter())
.highlighter(new MyHighlighter())
.parser(new MyParser())
.build();

Here are the main options available:

OptionDescription
terminalThe Terminal to use
appNameThe application name
variablesA Map<String, Object> containing variables
completerThe Completer component to use
historyThe History component to use
highlighterThe Highlighter component to use
parserThe Parser component to use
expanderThe Expander component to use

Reading Input

The basic method for reading input is readLine():

Loading snippet: LineReaderInputExample...

Line Reader Options

JLine's LineReader supports numerous options to customize behavior:

Loading snippet: LineReaderOptionsExample...

Common options include:

  • CASE_INSENSITIVE: Case-insensitive completion
  • AUTO_FRESH_LINE: Automatically add a newline if the cursor isn't at the start of a line
  • HISTORY_BEEP: Beep when navigating past the end of history
  • HISTORY_IGNORE_DUPS: Don't add duplicate entries to history
  • HISTORY_IGNORE_SPACE: Don't add entries starting with space to history
  • MENU_COMPLETE: Cycle through completions on tab

Customizing Prompts

JLine supports rich prompt customization:

Loading snippet: CustomPromptExample...

Handling Special Keys

You can customize how the LineReader responds to key presses:

Loading snippet: KeyBindingExample...

Line Editing Features

JLine's LineReader provides numerous line editing features:

  • Navigation: Move by character, word, or line
  • Editing: Insert, delete, cut, paste, transpose
  • History: Navigate, search, and filter command history
  • Completion: Tab completion with customizable behavior
  • Search: Incremental search through current line or history

Advanced Usage

Multi-line Input

JLine supports multi-line input with proper continuation:

Loading snippet: MultiLineInputExample...

Custom Highlighters

JLine can highlight input as it's typed:

Loading snippet: HighlighterExample...

Simple Line Reading

For REPL style programs, you 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;
}
// Process the line
...
}

Various ReadLine Methods

There are a few overridden readLine methods that take 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 built-in widgets: AutoPairWidgets, AutosuggestionWidgets and TailTipWidgets.

You can create custom widgets and bind them to keystrokes:

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;
}
}

Simple Line Reading

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

Loading snippet: SimpleLineReadingExample...

Various ReadLine Methods

There are a few overridden readLine methods that take 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 built-in widgets: AutoPairWidgets, AutosuggestionWidgets and TailTipWidgets.

You can create custom widgets and bind them to keystrokes:

Loading snippet: CustomWidgetExample...

You can also create a custom widgets class that extends the base Widgets class:

Loading snippet: CustomWidgetsClassExample...

Best Practices

  • Always close the terminal when your application exits
  • Use try-with-resources for automatic resource management
  • Configure history appropriately for your application
  • Consider using a parser for complex command syntax
  • Provide helpful completion options for better user experience
  • Handle exceptions like UserInterruptException and EndOfFileException appropriately
  • Save history on application exit
  • Use widgets to extend functionality