33 次重大发布

新增 0.34.0 2024 年 8 月 20 日
0.33.0 2024 年 7 月 23 日
0.32.0 2024 年 4 月 30 日
0.30.0 2024 年 3 月 5 日
0.1.0 2021 年 4 月 9 日

命令行界面 中排名 #22

Download history 10937/week @ 2024-05-02 10361/week @ 2024-05-09 7881/week @ 2024-05-16 7369/week @ 2024-05-23 9042/week @ 2024-05-30 7607/week @ 2024-06-06 8372/week @ 2024-06-13 9572/week @ 2024-06-20 8793/week @ 2024-06-27 8874/week @ 2024-07-04 8714/week @ 2024-07-11 8294/week @ 2024-07-18 9153/week @ 2024-07-25 8671/week @ 2024-08-01 8390/week @ 2024-08-08 12668/week @ 2024-08-15

40,566 次每月下载
用于 43 个 Crates (30 个直接使用)

MIT 许可协议

630KB
14K SLoC

功能丰富的行编辑器 - 驱动 Nushell

GitHub Crates.io docs.rs GitHub Workflow Status codecov Discord

简介

Reedline 是一个创建行编辑器(类似于 bash 的 readline 或 zsh 的 zle)的项目,它支持许多现代 CLI 的便利性,包括语法高亮、自动完成、多行支持、Unicode 支持,等等。它目前主要作为 nushell(从 v0.60 版本开始)的交互式编辑器进行开发,致力于提供愉快的交互体验。

概述

示例

有关完整文档,请访问 https://docs.rs/reedline。示例应突出显示如何启用最重要的功能或哪些特质可以用于特定语言的行为。

基本示例

// Create a default reedline object to handle user input

use reedline::{DefaultPrompt, Reedline, Signal};

let mut line_editor = Reedline::create();
let prompt = DefaultPrompt::default();

loop {
    let sig = line_editor.read_line(&prompt);
    match sig {
        Ok(Signal::Success(buffer)) => {
            println!("We processed: {}", buffer);
        }
        Ok(Signal::CtrlD) | Ok(Signal::CtrlC) => {
            println!("\nAborted!");
            break;
        }
        x => {
            println!("Event: {:?}", x);
        }
    }
}

与自定义快捷键集成

// Configure reedline with custom keybindings

//Cargo.toml
//    [dependencies]
//    crossterm = "*"

use {
  crossterm::event::{KeyCode, KeyModifiers},
  reedline::{default_emacs_keybindings, EditCommand, Reedline, Emacs, ReedlineEvent},
};

let mut keybindings = default_emacs_keybindings();
keybindings.add_binding(
    KeyModifiers::ALT,
    KeyCode::Char('m'),
    ReedlineEvent::Edit(vec![EditCommand::BackspaceWord]),
);
let edit_mode = Box::new(Emacs::new(keybindings));

let mut line_editor = Reedline::create().with_edit_mode(edit_mode);

History 集成

// Create a reedline object with history support, including history size limits

use reedline::{FileBackedHistory, Reedline};

let history = Box::new(
  FileBackedHistory::with_file(5, "history.txt".into())
    .expect("Error configuring history with file"),
);
let mut line_editor = Reedline::create()
  .with_history(history);

与自定义语法 Highlighter 集成

// Create a reedline object with highlighter support

use reedline::{ExampleHighlighter, Reedline};

let commands = vec![
  "test".into(),
  "hello world".into(),
  "hello world reedline".into(),
  "this is the reedline crate".into(),
];
let mut line_editor =
Reedline::create().with_highlighter(Box::new(ExampleHighlighter::new(commands)));

与自定义 tab 完成集成

// Create a reedline object with tab completions support

use reedline::{default_emacs_keybindings, ColumnarMenu, DefaultCompleter, Emacs, KeyCode, KeyModifiers, Reedline, ReedlineEvent, ReedlineMenu};

let commands = vec![
  "test".into(),
  "hello world".into(),
  "hello world reedline".into(),
  "this is the reedline crate".into(),
];
let completer = Box::new(DefaultCompleter::new_with_wordlen(commands.clone(), 2));
// Use the interactive menu to select options from the completer
let completion_menu = Box::new(ColumnarMenu::default().with_name("completion_menu"));
// Set up the required keybindings
let mut keybindings = default_emacs_keybindings();
keybindings.add_binding(
    KeyModifiers::NONE,
    KeyCode::Tab,
    ReedlineEvent::UntilFound(vec![
        ReedlineEvent::Menu("completion_menu".to_string()),
        ReedlineEvent::MenuNext,
    ]),
);

let edit_mode = Box::new(Emacs::new(keybindings));

let mut line_editor = Reedline::create()
    .with_completer(completer)
    .with_menu(ReedlineMenu::EngineCompleter(completion_menu))
    .with_edit_mode(edit_mode);

Hinter 集成以提供 fish 风格的历史自动提示

// Create a reedline object with in-line hint support

//Cargo.toml
//  [dependencies]
//  nu-ansi-term = "*"

use {
  nu_ansi_term::{Color, Style},
  reedline::{DefaultHinter, Reedline},
};

let mut line_editor = Reedline::create().with_hinter(Box::new(
  DefaultHinter::default()
  .with_style(Style::new().italic().fg(Color::LightGray)),
));

与自定义行完成 Validator 集成

// Create a reedline object with line completion validation support

use reedline::{DefaultValidator, Reedline};

let validator = Box::new(DefaultValidator);

let mut line_editor = Reedline::create().with_validator(validator);

使用自定义 EditMode

// Create a reedline object with custom edit mode
// This can define a keybinding setting or enable vi-emulation

use reedline::{
    default_vi_insert_keybindings, default_vi_normal_keybindings, EditMode, Reedline, Vi,
};

let mut line_editor = Reedline::create().with_edit_mode(Box::new(Vi::new(
    default_vi_insert_keybindings(),
    default_vi_normal_keybindings(),
)));

库功能

  • clipboard:启用使用 SystemClipboard 的支持。启用此功能将在调用 get_default_clipboard() 时返回 SystemClipboard 而不是本地剪贴板。
  • bashisms:启用对特殊文本序列的支持,可以从历史记录中召回组件。例如,!!!$。适用于 bashnushell 等外壳。
  • sqlite:提供 SqliteBackedHistory,用于在历史记录中存储更丰富的信息。静态链接所需的 sqlite 版本。
  • sqlite-dynlibsqlite 功能的替代方案。不会静态链接。需要 sqlite >= 3.38 以动态链接!
  • external_printer实验性:线程安全的 ExternalPrinter 处理程序,用于从并发运行的线程中打印行。

我们是否已经是提示符了?(开发状态)

Reedline 现在已具备所有基本功能,可以成为 nushell 的主要行编辑器。

  • 通用编辑功能,使用起来应该与来自其他外壳(例如 bash、fish、zsh)的感觉相似。
  • 可配置的键绑定(emacs 风格绑定和基本的 vi 风格)。
  • 可配置的提示符。
  • 内容感知语法高亮。
  • 自动完成(带有图形选择菜单或简单的行内循环)。
  • 具有交互式搜索选项的历史记录(可选地持久化到文件,可以支持多个会话访问同一文件)。
  • Fish 风格的历史自动建议提示。
  • 撤销支持。
  • 剪贴板集成。
  • 行完整性验证,以便无缝输入多行命令序列。
  • 视觉选择。

未来改进的区域。

  • 支持除简单从左到右脚本之外的 Unicode。
  • 更简单的键绑定配置。
  • 支持更多高级 vi 命令。
  • 如果完成或提示内容计算时间较长,则提供平滑的体验。
  • 支持从后台任务并发输出流以进行显示,同时输入提示符处于活动状态(“全双工”模式)。

有关更多想法,请参阅 功能讨论 或加入 nushell discord#reedline 频道。

替代方案

有关目前更成熟的 Rust 行编辑,请参阅

依赖关系

~5–21MB
~319K SLoC