rsvim_core 0.1.3-alpha.2

The core library for RSVIM text editor.
Documentation
//! Command-line operations.

use crate::cmdltext::CmdlineText;
use crate::prelude::*;
use crate::ui::tree::Inodify;
use crate::ui::tree::Tree;
use crate::ui::viewport::CursorViewport;
use crate::ui::viewport::Viewport;
use compact_str::ToCompactString;

fn _set_message_impl(
  tree: &mut Tree,
  cmdline_text: &mut CmdlineText,
  payload: Option<String>,
) {
  debug_assert!(tree.cmdline_id().is_some());

  let message_text = cmdline_text.message_mut();
  message_text.clear();
  if let Some(payload) = payload {
    message_text.insert(0, 0, payload.to_compact_string());
  }

  let opts = *tree.cmdline().unwrap().options();
  let actual_size = tree.cmdline_message().unwrap().actual_shape().size();

  let new_message_viewport =
    Viewport::to_arc(Viewport::view(&opts, message_text, &actual_size, 0, 0));

  tree.set_cmdline_message_viewport(new_message_viewport);
}

pub fn cmdline_set_last_pending_message_on_initialize(
  tree: &mut Tree,
  cmdline_text: &mut CmdlineText,
) {
  // If message history contains some payload. This means before we actually
  // running the event loop, there's already some messages wait for print.
  let last_msg = cmdline_text.message_history().last().cloned();
  trace!("|cmdline_flush_pending_message| last_msg:{:?}", last_msg);
  if let Some(last_msg) = last_msg {
    // Current "command-line-message" widget can only print 1 single-line
    // message, multi-line messages are not support yet.
    //
    // FIXME: Fix me once our "command-line-message" widget support
    // multi-line messages.
    _set_message_impl(tree, cmdline_text, Some(last_msg));
  }
}

pub fn cmdline_set_message(
  tree: &mut Tree,
  cmdline_text: &mut CmdlineText,
  payload: String,
) {
  _set_message_impl(tree, cmdline_text, Some(payload.clone()));

  // Also append message history:
  let cmdline_hist = cmdline_text.message_history_mut();
  cmdline_hist.push_overwrite(payload);
}

pub fn cmdline_clear_message(tree: &mut Tree, cmdline_text: &mut CmdlineText) {
  debug_assert!(tree.cmdline_id().is_some());
  _set_message_impl(tree, cmdline_text, None);
}

pub fn cmdline_clear_input(tree: &mut Tree, cmdline_text: &mut CmdlineText) {
  debug_assert!(tree.cmdline_id().is_some());

  let input_text = cmdline_text.input_mut();
  input_text.clear();

  let opts = *tree.cmdline().unwrap().options();
  let actual_size = tree.cmdline_input().unwrap().actual_shape().size();

  let new_input_viewport =
    Viewport::view(&opts, input_text, &actual_size, 0, 0);
  let new_input_cursor_viewport = CursorViewport::from_top_left(
    &new_input_viewport,
    input_text,
    &actual_size,
  );
  let new_input_viewport = Viewport::to_arc(new_input_viewport);
  let new_input_cursor_viewport =
    CursorViewport::to_arc(new_input_cursor_viewport);

  tree.set_editable_viewport(tree.cmdline_id().unwrap(), new_input_viewport);
  tree.set_editable_cursor_viewport(
    tree.cmdline_id().unwrap(),
    new_input_cursor_viewport,
  );
}