JLine Documentation

repository·master·Indexed 23 days ago

https://github.com/jline/jline3

A Java library for handling console input, providing features such as line editing (Emacs/Vi), history management, tab completion, and syntax highlighting. It includes a modular architecture with core components for terminal handling, reading, and styling, as well as the jline-prompt API for creating interactive console interfaces with elements like checkboxes, lists, and search prompts.

Tokens
57.3K
Snippets
128
Records
309
Agent score
83%

What's inside JLine

  1. Overview of JLine features

    master

    JLine is a Java library for advanced console input handling, providing features similar to BSD editline and GNU readline. Key capabilities include:

    • Editing: Rich command-line editing, multi-line editing, and advanced movement (cut/paste, word movement).
    • Input/Output: Customizable tab completion, syntax highlighting, and Unicode support.
    • Management: History management with search and flexible keyboard mapping.
    • Environment: Platform-independent implementation.
  2. Use the JLine Style module for terminal formatting

    master

    The JLine Style module provides a framework for adding colors and formatting to command-line applications. It is built around three core components:

    1. Style Expressions: Concise, string-based definitions of styles.
    2. Style Resolver: A component that converts Style Expressions into AttributedStyle objects.
    3. Styler: A high-level component that combines Style Expressions with text to apply styling.

    This module allows you to move away from manual ANSI escape code management and toward a more declarative styling system.

  3. Understand JLine thread safety and stability

    master

    Thread Safety

    Most JLine classes are not thread-safe. To avoid undefined behavior:

    • Call Terminal methods from a single dedicated thread.
    • Call LineReader methods from a single dedicated thread.
    • History can be accessed concurrently only if you implement your own synchronization.

    API Stability

    JLine follows semantic versioning:

    • Major: May include breaking changes.
    • Minor: Backward-compatible new functionality.
    • Patch: Backward-compatible bug fixes.
    • Note: Methods marked @Deprecated may be removed in future major versions.
  4. How JLine architecture works

    master

    JLine is organized into a layered architecture where each layer builds upon the capabilities of the one below it.

    1. Terminal Layer: The foundation. It handles raw input, ANSI escape sequences, terminal size, and signals (like Ctrl+C). It uses various providers (JNI, FFM, Exec, Dumb) to interface with native terminal capabilities.
    2. LineReader Layer: Built on top of the Terminal. It provides the user-facing editing experience, including history management, tab completion, key bindings, and syntax highlighting.
    3. Higher-Level APIs: Modules that provide specialized functionality like styling (Style), command utilities (Builtins), application frameworks (Console), and UI components (Console UI).

    Data Flow: User Input (Raw) $\rightarrow$ Terminal $\rightarrow$ Key Bindings/Widgets $\rightarrow$ LineReader (Editing) $\rightarrow$ Completed Line $\rightarrow$ Application Logic.

  5. How widgets work in JLine

    master
    Widgets are reusable components in JLine that extend the functionality of the LineReader. They can be triggered programmatically or bound to specific key combinations to perform actions like text manipulation, navigation, or history searching. Widgets can be composed into 'chains' where one widget calls others to perform complex operations.
  6. How JLine's core components work together

    master

    JLine's API is built around a hierarchy of components that manage the lifecycle of a command-line interaction:

    1. Terminal: The foundation. It handles the raw connection to the terminal device, reading/writing bytes, and managing terminal attributes like raw mode or window size.
    2. LineReader: The high-level interaction layer. It uses a Terminal to provide an interactive editing experience, managing history, completion, and syntax highlighting.
    3. Completer, History, Parser, and Highlighter: These are specialized components used by the LineReader to enhance the user experience (e.g., providing tab completion, remembering previous commands, or coloring text).

    To build a CLI, you typically start by creating a Terminal via TerminalBuilder and then creating a LineReader via LineReaderBuilder using that terminal.

  7. Implement syntax highlighting with the Highlighter interface

    master

    JLine supports syntax highlighting via the Highlighter interface. To use it, you must implement the highlight method, which is called during input. The method receives the current LineReader, the input buffer, and a list of candidates. You then add highlighted versions of the input to this list.

    Basic Highlighting

    The simplest implementation involves applying a single style to the entire input buffer.

    Keyword Highlighting

    You can use regular expressions within your highlight implementation to identify specific keywords (e.g., SQL commands) and apply distinct styles like bold or specific colors to them.

    Full Syntax Highlighting

    For complex languages, your implementation can use multiple regex patterns to differentiate between keywords, strings, numbers, and comments, applying unique styles to each category.

  8. Use variables and variable expansion in the REPL

    master

    The REPL provides a variable system for storing and manipulating data. You can reference variables using the $ prefix.

    Variable Expansion

    • Simple expansion: prnt $user
    • Object notation: prnt ${user}.name
    • JSON/Groovy notation: Command parameters can be passed directly using JSON or Groovy object syntax.

    Variable Naming Conventions

    • Temporary variables: Names starting with an underscore _ (e.g., _args, _buffer) are temporary and deleted automatically at the end of the REPL loop.
    • Persistent variables: Names in CAMEL_CASE are not deleted when using wildcard deletions like del *.
  9. Understand JLine native access strategies

    master

    To provide advanced terminal functionality (like raw mode, terminal size detection, and signal handling), JLine uses different strategies for native access depending on your environment and Java version:

    • FFM (Foreign Function & Memory): The recommended approach for Java 22+. It uses the Java FFM API to call native code without pre-compiled libraries. Requires --enable-native-access on JDK 24+.
    • JNI (Java Native Interface): Uses the jline-terminal-jni module to call platform-specific native code via pre-compiled libraries. Works on all supported Java versions but requires --enable-native-access on JDK 24+.
    • Exec: Spawns external commands (such as stty) to interact with the terminal.
    • Dumb: A fallback mode with no native access, used when advanced terminal capabilities are unavailable. In this mode, the terminal only shows text and takes input without local processing.
  10. Handle terminal resize events

    master
    To create a responsive terminal application, you should listen for terminal resize events. JLine allows you to register a handler for the WINCH signal (Window Change), which is triggered whenever the terminal window is resized. This allows your application to redraw its UI or adjust its layout dynamically.