delta-gitu 0.1.9

An experimental fork of gitu (a git client inspired by Magit), published as a library for delta to embed
Documentation
use super::{Action, OpTrait};
use crate::{
    Res,
    app::{App, PromptParams, State},
    error::Error,
    item_data::ItemData,
    screen::SearchDirection,
    term::Term,
};
use std::rc::Rc;

pub(crate) struct Search;
impl OpTrait for Search {
    fn get_action(&self, _target: &ItemData) -> Option<Action> {
        Some(Rc::new(|app, term| {
            prompt_search(app, term, SearchDirection::Forward)
        }))
    }

    fn display(&self, _state: &State) -> String {
        "Search".into()
    }
}

pub(crate) struct SearchBackward;
impl OpTrait for SearchBackward {
    fn get_action(&self, _target: &ItemData) -> Option<Action> {
        Some(Rc::new(|app, term| {
            prompt_search(app, term, SearchDirection::Backward)
        }))
    }

    fn display(&self, _state: &State) -> String {
        "Search backward".into()
    }
}

pub(crate) struct SearchNext;
impl OpTrait for SearchNext {
    fn get_action(&self, _target: &ItemData) -> Option<Action> {
        Some(Rc::new(|app, _term| app.screen_mut().search_repeat(false)))
    }

    fn display(&self, _state: &State) -> String {
        "Next match".into()
    }
}

pub(crate) struct SearchPrevious;
impl OpTrait for SearchPrevious {
    fn get_action(&self, _target: &ItemData) -> Option<Action> {
        Some(Rc::new(|app, _term| app.screen_mut().search_repeat(true)))
    }

    fn display(&self, _state: &State) -> String {
        "Previous match".into()
    }
}

fn prompt_search(app: &mut App, term: &mut Term, direction: SearchDirection) -> Res<()> {
    let prompt = match direction {
        SearchDirection::Forward => "Search",
        SearchDirection::Backward => "Search backward",
    };

    let query = match app.prompt(
        term,
        &PromptParams {
            prompt,
            ..Default::default()
        },
    ) {
        Ok(query) if query.is_empty() => {
            app.screen_mut().clear_search();
            return Ok(());
        }
        Ok(query) => query,
        Err(Error::PromptAborted) => {
            app.screen_mut().clear_search();
            return Ok(());
        }
        Err(err) => return Err(err),
    };

    app.screen_mut().search(&query, direction)
}