///|
/// 表示一个可长期持有的行编辑上下文。
///
/// 同一个 `LineEditor` 的不同副本共享私有 owner 和编辑状态,不会创建额外的 native
/// 编辑器。
///
/// **Construction:**
///
/// 请使用 `LineEditor::open` 构造,也可以传入可重复使用的 `LineEditorConfig` 和
/// `History`。
///
/// **Lifecycle:**
///
/// 最后一个引用消失后,native 编辑器会被自动释放。调用者不需要也不能显式关闭
/// `LineEditor`,任一别名也不会使其他别名失效。
#warnings("-unused_field")
pub struct LineEditor {
priv owner : EditorOwner
priv history : History
}
///|
/// 基于进程的标准输入输出创建并完整配置一个行编辑器。
///
/// 配置按以下顺序应用:建立默认配置、读取所选 editrc、应用显式编辑模式、连接 History。
/// 默认 editrc 不存在时会被忽略;显式指定的文件不存在时会报告错误。
///
/// **Parameters:**
///
/// - `config`:不可变的构造选项。省略时,应用名称为 `readline.mbt`,存在默认 editrc
/// 时读取该文件,并且不使用显式编辑模式覆盖配置。
/// - `history`:要连接的 History。省略时创建容量为 1000 的空 History。
///
/// **Errors:**
///
/// - 应用名称或显式 editrc 路径包含 NUL 时抛出 `EmbeddedNul`。
/// - 无法创建线程局部的 UTF-8 locale 时抛出 `UnsupportedLocale`。
/// - 无法创建底层编辑器时抛出 `InitializationFailed`。
/// - 无法应用 editrc、显式编辑模式或 History 连接时抛出 `ConfigurationFailed`。
/// - 无法创建默认 History 时抛出相应的 History 构造错误。
///
/// **Lifecycle:**
///
/// 返回值的所有副本共享同一个私有 owner 和已连接的 History。editor owner 在底层编辑器
/// 存活期间强引用 History owner,并在释放底层编辑器后才释放该引用。两种资源都不提供
/// 公开的关闭操作。
///
/// **Side effects:**
///
/// 启用 editrc 时,构造过程会打开相应文件;此操作不会修改进程全局 locale。
///
/// **Thread safety:**
///
/// 当前不保证可以跨线程使用。同步终端读取的并发约束将在读取接口中说明。
///
/// **Examples:**
///
/// ```mbt check
/// test {
/// let config = LineEditorConfig::new(editrc=Disabled)
/// let history = History::new(capacity=100)
/// let editor = LineEditor::open(config~, history~)
/// inspect(editor.history().length(), content="0")
/// }
/// ```
pub fn LineEditor::open(
config? : LineEditorConfig = LineEditorConfig::new(),
history? : History,
) -> LineEditor raise ReadlineError {
let history = match history {
Some(history) => history
None => History::new()
}
let (editrc_kind, editrc_path) = match config.editrc {
Disabled => (0, "")
Default => (1, "")
File(path) => (2, path)
}
let editing_mode = match config.editing_mode {
None => 0
Some(Emacs) => 1
Some(Vi) => 2
}
let owner = EditorOwner::new(
@utf8.encode(config.application_name),
editrc_kind,
@utf8.encode(editrc_path),
editing_mode,
history.owner,
)
match owner.status() {
0 => { owner, history }
1 => raise EmbeddedNul
2 => raise UnsupportedLocale
3 => raise InitializationFailed
_ => raise ConfigurationFailed
}
}
///|
/// 返回当前连接的 History 共享 handle。
///
/// 返回值与构造时传入或默认创建的 History 共享同一个 owner。修改任一 handle 都会影响
/// 行编辑器后续使用的历史记录。
pub fn LineEditor::history(self : LineEditor) -> History {
self.history
}