diff options
-rw-r--r-- | config_files/fm/tuis.yaml | 2 | ||||
-rw-r--r-- | src/cli_info.rs | 63 | ||||
-rw-r--r-- | src/event_exec.rs | 2 | ||||
-rw-r--r-- | src/main.rs | 14 | ||||
-rw-r--r-- | src/preview.rs | 6 | ||||
-rw-r--r-- | src/skim.rs | 10 |
6 files changed, 63 insertions, 34 deletions
diff --git a/config_files/fm/tuis.yaml b/config_files/fm/tuis.yaml index b880ecc..c393a9d 100644 --- a/config_files/fm/tuis.yaml +++ b/config_files/fm/tuis.yaml @@ -8,3 +8,5 @@ btop: cwd: false glances: cwd: false +mocp: + cwd: true diff --git a/src/cli_info.rs b/src/cli_info.rs index f8ca04a..a32a955 100644 --- a/src/cli_info.rs +++ b/src/cli_info.rs @@ -1,31 +1,74 @@ -use anyhow::{Context, Result}; +use std::collections::HashMap; +use std::process::{Command, Stdio}; + +use anyhow::{anyhow, Context, Result}; +use log::info; use crate::impl_selectable_content; -use crate::opener::execute_and_capture_output; -use crate::status::Status; use crate::utils::is_program_in_path; +/// Holds the command line commands we can run and display +/// without leaving FM. +/// Those are non interactive commands displaying some info about the current +/// file tree or setup. #[derive(Clone)] pub struct CliInfo { - pub content: Vec<String>, + pub content: Vec<&'static str>, + commands: HashMap<&'static str, Vec<&'static str>>, index: usize, } impl Default for CliInfo { fn default() -> Self { let index = 0; - let content = vec!["duf".to_owned(), "inxi".to_owned()]; - Self { content, index } + let commands = HashMap::from([ + ("duf", vec!["duf"]), + ("inxi", vec!["inxi", "-Fxxxcz"]), + ("neofetch", vec!["neofetch"]), + ("lsusb", vec!["lsusb"]), + ]); + let content: Vec<&'static str> = commands + .keys() + .filter(|s| is_program_in_path(s)) + .copied() + .collect(); + + Self { + content, + index, + commands, + } } } impl CliInfo { - pub fn execute(&self, status: &Status) -> Result<String> { - let exe = self.selected().context("no cli selected")?; - let output = execute_and_capture_output(exe, &vec![])?; + /// Run the selected command and capture its output. + /// Some environement variables are first set to ensure the colored output. + /// Long running commands may freeze the display. + pub fn execute(&self) -> Result<String> { + let key = self.selected().context("no cli selected")?; + let output = { + let args = self.commands.get(key).context("no arguments for exe")?; + info!("execute. executable: {key}, arguments: {args:?}",); + let child = Command::new(args[0]) + .args(&args[1..]) + .env("CLICOLOR_FORCE", "1") + .env("COLORTERM", "ansi") + .stdin(Stdio::null()) + .stdout(Stdio::piped()) + .stderr(Stdio::null()) + .spawn()?; + let output = child.wait_with_output()?; + if output.status.success() { + Ok(String::from_utf8(output.stdout)?) + } else { + Err(anyhow!("execute: command didn't finished correctly",)) + } + }?; Ok(output) } } -impl_selectable_content!(String, CliInfo); +type StaticStr = &'static str; +impl_selectable_content!(StaticStr, CliInfo); diff --git a/src/event_exec.rs b/src/event_exec.rs index 5dec13b..ffe20a0 100644 --- a/src/event_exec.rs +++ b/src/event_exec.rs @@ -269,7 +269,7 @@ impl EventExec { } pub fn exec_cli_info(status: &mut Status) -> Result<()> { - let output = status.cli_info.execute(status)?; + let output = status.cli_info.execute()?; info!("output\n{output}"); status.selected().set_mode(Mode::Preview); let preview = Preview::cli_info(&output); diff --git a/src/main.rs b/src/main.rs index 4d96b18..f6ec13a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -67,17 +67,3 @@ fn main() -> Result<()> { info!("fm is shutting down"); Ok(()) } - -fn main2() -> Result<()> { - let term = Arc::new(init_term()?); - // CLICOLOR_FORCE=1 COLORTERM="truecolor" duf > duf.txt - let s = std::fs::read_to_string("/home/quentin/duf.txt")?; - - for (row, line) in s.lines().enumerate() { - fm::skim::print_ansi_str(line, &term, Some(0), Some(row))?; - } - term.present()?; - while let Ok(_ev) = term.poll_event() {} - - Ok(()) -} diff --git a/src/preview.rs b/src/preview.rs index f739c30..7fa0721 100644 --- a/src/preview.rs +++ b/src/preview.rs @@ -187,7 +187,7 @@ impl Preview { Self::Text(TextContent::log(log)) } - pub fn cli_info(output: &String) -> Self { + pub fn cli_info(output: &str) -> Self { Self::ColoredText(ColoredText::new(output)) } @@ -672,6 +672,10 @@ impl ColoredText { self.len } + pub fn is_empty(&self) -> bool { + self.len == 0 + } + /// Make a new previewed colored text. pub fn new(output: &str) -> Self { let content: Vec<String> = output.lines().map(|line| line.to_owned()).collect(); diff --git a/src/skim.rs b/src/skim.rs index ea7335b..f35b0eb 100644 --- a/src/skim.rs +++ b/src/skim.rs @@ -104,14 +104,8 @@ pub fn print_ansi_str( col: Option<usize>, row: Option<usize>, ) -> anyhow::Result<()> { - let mut col = match col { - Some(col) => col, - None => 0, - }; - let row = match row { - Some(row) => row, - None => 0, - }; + let mut col = col.unwrap_or(0); + let row = row.unwrap_or(0); for (chr, attr) in skim::AnsiString::parse(text).iter() { col += term.print_with_attr(row, col, &chr.to_string(), attr)?; } |