rmux-server 0.1.1

Tokio daemon and request dispatcher for the RMUX terminal multiplexer.
Documentation
use rmux_core::{
    command_parser::CommandParser,
    formats::{
        FormatContext, FormatVariables, FORMAT_VARIABLES,
        TMUX_FORMAT_TABLE_NAMES as RMUX_FORMAT_TABLE_NAMES,
    },
};
use rmux_proto::{RmuxError, Target};

use crate::format_runtime::RuntimeFormatContext;
use crate::pane_terminals::{session_not_found, HandlerState};

pub(super) fn collect_parse_time_values(
    format_context: &dyn FormatVariables,
) -> Vec<(String, String)> {
    let mut values = Vec::new();

    if let Some(value) = format_context.format_value_by_name("current_file") {
        values.push(("current_file".to_owned(), value));
    }

    for variable in FORMAT_VARIABLES {
        if let Some(value) = format_context.format_value(variable) {
            values.push((variable.name().to_owned(), value));
        }
    }

    for name in RMUX_FORMAT_TABLE_NAMES {
        if let Some(value) = format_context.format_value_by_name(name) {
            values.push(((*name).to_owned(), value));
        }
    }

    values
}

pub(super) fn parser_with_parse_time_context(
    mut parser: CommandParser,
    format_context: &dyn FormatVariables,
) -> CommandParser {
    for (name, value) in collect_parse_time_values(format_context) {
        parser = parser.with_format_value(&name, value);
    }

    parser
}

pub(in super::super) fn format_context_for_target<'a>(
    state: &'a HandlerState,
    target: &Target,
    attached_count: usize,
) -> Result<RuntimeFormatContext<'a>, RmuxError> {
    let session_name = target.session_name();
    let session = state
        .sessions
        .session(session_name)
        .ok_or_else(|| session_not_found(session_name))?;
    let active_window = session.active_window_index();
    let last_window = session.last_window_index();

    match target {
        Target::Session(_) => {
            let window = session.window();
            let mut context = FormatContext::from_session(session)
                .with_session_attached(attached_count)
                .with_window(active_window, window, true, false);
            if let Some(pane) = window.active_pane() {
                context = context.with_window_pane(window, pane);
            }
            let mut runtime = RuntimeFormatContext::new(context)
                .with_state(state)
                .with_session(session)
                .with_window(active_window, window);
            if let Some(pane) = window.active_pane() {
                runtime = runtime.with_pane(pane);
            }
            Ok(runtime)
        }
        Target::Window(target) => {
            let window_index = target.window_index();
            let window = session.window_at(window_index).ok_or_else(|| {
                RmuxError::invalid_target(
                    target.to_string(),
                    "window index does not exist in session",
                )
            })?;
            let mut context = FormatContext::from_session(session)
                .with_session_attached(attached_count)
                .with_window(
                    window_index,
                    window,
                    window_index == active_window,
                    Some(window_index) == last_window,
                );
            if let Some(pane) = window.active_pane() {
                context = context.with_window_pane(window, pane);
            }
            let mut runtime = RuntimeFormatContext::new(context)
                .with_state(state)
                .with_session(session)
                .with_window(window_index, window);
            if let Some(pane) = window.active_pane() {
                runtime = runtime.with_pane(pane);
            }
            Ok(runtime)
        }
        Target::Pane(target) => {
            let window_index = target.window_index();
            let pane_index = target.pane_index();
            let window = session.window_at(window_index).ok_or_else(|| {
                RmuxError::invalid_target(
                    format!("{}:{window_index}", target.session_name()),
                    "window index does not exist in session",
                )
            })?;
            let pane = window.pane(pane_index).ok_or_else(|| {
                RmuxError::invalid_target(
                    target.to_string(),
                    "pane index does not exist in session",
                )
            })?;
            let context = FormatContext::from_session(session)
                .with_session_attached(attached_count)
                .with_window(
                    window_index,
                    window,
                    window_index == active_window,
                    Some(window_index) == last_window,
                )
                .with_pane(pane, pane_index == window.active_pane_index());
            Ok(RuntimeFormatContext::new(context)
                .with_state(state)
                .with_session(session)
                .with_window(window_index, window)
                .with_pane(pane))
        }
    }
}