JLine Architecture
This page provides a high-level overview of JLine's architecture and how its components interact with each other.
Component Overview
JLine is organized into several core components that work together to provide a complete terminal handling and line editing solution:
┌─────────────────────────────────────────────────────────────────┐
│ JLine Architecture │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Terminal │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────┐ │
│ │ Jansi │ │ JNA │ │ FFM │ │ Exec │ │
│ │ Provider │ │ Provider │ │ Provider │ │ Provider│ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ LineReader │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────┐ │
│ │ Parser │ │ Completer │ │ History │ │ Widgets │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Higher-Level APIs │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ ┌──────────┐ │
│ │ Style │ │ Builtins │ │ Console │ │Console UI│ │
│ └─────────────┘ └─────────────┘ └────────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────────┘
Core Components
Terminal
The Terminal
component is the foundation of JLine. It provides:
- Access to the underlying terminal device
- Raw mode for character-by-character input
- ANSI escape sequence handling
- Terminal size information
- Signal handling (e.g., window resize, Ctrl+C)
The Terminal layer uses different providers (Jansi, JNA, FFM, etc.) to interact with the native terminal capabilities on different platforms.
LineReader
The LineReader
builds on top of the Terminal to provide:
- Line editing capabilities
- History management
- Tab completion
- Key binding
- Widget system for custom functionality
- Multi-line editing
- Syntax highlighting
Higher-Level APIs
JLine includes several higher-level modules that provide additional functionality:
- Style: Styling API for terminal output
- Builtins: Ready-to-use commands and utilities
- Console: Framework for building interactive console applications
- Console UI: UI components like progress bars, tables, and forms
Data Flow
Here's how data flows through the JLine system:
- The
Terminal
captures raw input from the user - Input is processed through key bindings and widgets
- The
LineReader
applies editing operations based on the input - When the user presses Enter, the
LineReader
returns the completed line - The application processes the line and may use higher-level APIs for output
Module Dependencies
The modules have the following dependency relationships:
jline-terminal
↑
jline-reader
↑
jline-style
↑
jline-builtins
↑
jline-console
↑
jline-console-ui
Key Interfaces
JLine defines several key interfaces that you'll work with:
Terminal
: Represents the terminal deviceLineReader
: Reads lines of input with editing capabilitiesCompleter
: Provides tab completion suggestionsHistory
: Manages command historyParser
: Parses input lines into tokensWidget
: Implements custom functionality for the line reader
Customization Points
JLine is highly customizable through several extension points:
- Terminal Providers: Choose or implement different terminal backends
- Completers: Create custom completion logic
- Widgets: Add new editing functions
- Key Bindings: Map keys to specific actions
- Highlighters: Implement syntax highlighting
- History: Customize history storage and retrieval
Common Usage Patterns
Basic Terminal and LineReader
// Create a terminal
Terminal terminal = TerminalBuilder.builder()
.system(true)
.build();
// Create a line reader
LineReader reader = LineReaderBuilder.builder()
.terminal(terminal)
.build();
// Read input
String line = reader.readLine("prompt> ");
Adding Tab Completion
// Create a completer
Completer completer = new StringsCompleter("command1", "command2", "help", "quit");
// Create a line reader with completion
LineReader reader = LineReaderBuilder.builder()
.terminal(terminal)
.completer(completer)
.build();
Using History
// Create a history file
Path historyFile = Paths.get(System.getProperty("user.home"), ".myapp_history");
// Create a line reader with history
LineReader reader = LineReaderBuilder.builder()
.terminal(terminal)
.variable(LineReader.HISTORY_FILE, historyFile)
.build();
Conclusion
JLine's architecture provides a flexible and powerful foundation for building command-line applications. By understanding how the components interact, you can leverage JLine's capabilities to create sophisticated terminal interfaces.
For more detailed information about each component, refer to the specific documentation pages.