///|
/// 表示一个可长期持有的行编辑上下文。
///
/// 同一个 `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
}