1. 简介

JLine 是一个用于处理控制台输入的 Java 库,它提供了类似 GNU readline 库或 ZSH 行编辑器的功能。在本教程中,我们将深入探讨 JLine 3,了解其核心概念、能力以及实际用法。

2. 依赖配置

使用 JLine 前,需在构建文件中添加依赖(当前最新版本为 3.28.0)。对于 Maven 项目,在 pom.xml 中添加:

<dependency>
    <groupId>org.jline</groupId>
    <artifactId>jline</artifactId>
    <version>3.28.0</version>
</dependency>

⚠️ Windows 平台特殊要求:需额外添加终端提供库 JANSI:

<dependency>
    <groupId>org.jline</groupId>
    <artifactId>jline-terminal-jansi</artifactId>
    <version>3.28.0</version>
</dependency>

macOS/Linux 系统无需此依赖,JLine 会自动使用 FFM 或 JNI 绑定。

3. 终端(Terminal)

Terminal 是 JLine 的核心抽象,代表控制台或命令行接口,用于读写数据。通过 TerminalBuilder 创建实例:

try(Terminal terminal = TerminalBuilder.builder().build()) {
    // 使用终端
}

✅ 最佳实践:Terminal 实现了 Closeable,推荐使用 try-with-resources 确保正确关闭。

基本操作

获取输入输出流:

InputStream inputStream = terminal.input();
OutputStream outputStream = terminal.output();

Reader reader = terminal.reader();
PrintWriter writer = terminal.writer();

⚠️ 输出刷新:写入输出流后需手动刷新:

terminal.flush();

终端查询

Size size = terminal.getSize(); // 获取终端尺寸

注意:部分功能(如尺寸查询)在降级终端(dumb terminal)中可能不可用。

4. 行读取器(Line Reader)

LineReader 是 JLine 的核心价值所在,它配合 Terminal 实现复杂的输入处理和行编辑功能。

创建实例

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

基础用法

try {
    String line = lineReader.readLine("> ");
    terminal.writer().println("Read: " + line);
} catch (UserInterruptException e) {
    // Ctrl+C 触发
} catch (EndOfFileException e) {
    // Ctrl+D 或流关闭触发
}

行读取器演示

高级特性

  • 行内编辑:支持箭头键移动光标修改内容 行内编辑演示

  • 复杂输入:支持左右提示符、字符掩码、初始值:

    String line = lineReader.readLine("> ", " <", '#', "Password");
    

    复杂输入演示

5. 历史记录(History)

LineReader 自动提供历史记录功能,支持:

  • 上下箭头浏览历史
  • Ctrl+R 反向搜索
  • Ctrl+S 正向搜索

历史记录演示

配置历史记录

LineReader lineReader = LineReaderBuilder.builder()
  .terminal(terminal)
  .history(new DefaultHistory()) // 默认历史实现
  .option(LineReader.Option.HISTORY_IGNORE_DUPS, false) // 允许重复记录
  .variable(LineReader.HISTORY_FILE, Path.of("target/jline-history")) // 持久化文件
  .variable(LineReader.HISTORY_SIZE, 5) // 内存保留条数
  .build();

历史配置演示

6. 自动补全(Completion)

JLine 通过 Tab 键实现命令补全,需在构建时配置 Completer

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

常用补全器

  1. 字符串补全

    Completer completer = new StringsCompleter("foo", "bar", "baz");
    

    字符串补全演示

  2. 文件/目录补全

    new Completers.FilesCompleter(Path.of("/baseDir"))
    new Completers.DirectoriesCompleter(Path.of("/baseDir"))
    
  3. 组合补全

    Completer completer = new AggregateCompleter(
    new StringsCompleter("foo", "bar", "baz"),
    new Completers.FilesCompleter(Path.of("/baseDir")),
    new Completers.DirectoriesCompleter(Path.of("/baseDir"))
    );
    

    组合补全演示

高级补全器

  • ArgumentCompleter:按命令单词补全
  • RegexCompleter:正则匹配补全
  • TreeCompleter:树形命令结构补全

7. 总结

本文介绍了 JLine 3 的核心功能:终端操作、行读取、历史记录和自动补全。这个库远不止于此,下次开发命令行应用时,不妨试试它!


原始标题:Introduction to JLine 3 | Baeldung