Skip to main content

fm/modes/menu/
tui_menu.rs

1use anyhow::Result;
2use serde_yaml_ng::Mapping;
3
4use crate::app::Status;
5use crate::common::{is_in_path, TUIS_PATH};
6use crate::io::External;
7use crate::modes::{Execute, TerminalApplications};
8use crate::{impl_content, impl_draw_menu_with_char, impl_selectable, log_info};
9
10/// Directly open a a TUI application
11/// The TUI application shares the same window as fm.
12/// If the user picked "shell", we use the environment variable `$SHELL` or `bash` if it's not set.
13pub fn open_tui_program<P>(program: &str, current_path: P) -> Result<()>
14where
15    P: AsRef<std::path::Path>,
16{
17    if program == "shell" {
18        External::open_shell_in_window(current_path)
19    } else if is_in_path(program) {
20        log_info!("Tui menu execute {program}");
21        External::open_command_in_window(&[program], current_path)
22    } else {
23        log_info!("Tui menu program {program} isn't in path");
24        Ok(())
25    }
26}
27
28impl Execute<()> for String {
29    fn execute(&self, status: &Status) -> Result<()> {
30        open_tui_program(self, status.current_tab().directory_of_selected()?)
31    }
32}
33
34/// Tui applications which requires a new terminal for interaction.
35#[derive(Clone)]
36pub struct TuiApplications {
37    pub content: Vec<String>,
38    index: usize,
39}
40
41impl TuiApplications {
42    pub fn setup(&mut self) {
43        self.update_from_config(TUIS_PATH);
44    }
45
46    pub fn is_not_set(&self) -> bool {
47        self.content.len() == 1
48    }
49}
50
51impl Default for TuiApplications {
52    fn default() -> Self {
53        let index = 0;
54        let content = vec!["shell".to_owned()];
55        Self { content, index }
56    }
57}
58
59impl TerminalApplications<String, ()> for TuiApplications {
60    fn parse_yaml(&mut self, yaml: &Mapping) {
61        for (key, _) in yaml {
62            let Some(command) = key.as_str() else {
63                continue;
64            };
65            if is_in_path(command) {
66                self.content.push(command.to_owned());
67            }
68        }
69    }
70}
71
72impl_content!(TuiApplications, String);
73impl_draw_menu_with_char!(TuiApplications, String);