diff --git a/Cargo.toml b/Cargo.toml index e31884b..df5d959 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dotree" -version = "0.7.0" +version = "0.8.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/README.md b/README.md index 6e95e47..f60fdf4 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,26 @@ menu brightnessctl { ... ``` +### Echoing Commands + +By default, dotree will echo the command it executes to stderr (this behavior change was introduced in 0.8.0). +If you don't like that, you can add `echo off` to the top of the file, like this: + +``` +echo off + +menu root { + n: "echo don\'t show me" + y: "echo 'show me' without echoing the command" - @"echo show me" +} +``` + +This will switch the default behavior to not echoing the executed command. Before a command, you can +add an `@`, which will toggle the default behavior, i.e. if you have an `echo off` at the top of +your file, then commands with `@` will be echoed. If you do not have `echo off` at the top of the file +`@` will supress echoing. + + ### Naming Menus You can also assign a different display name to a menu, like this: diff --git a/grammar.pest b/grammar.pest index 78fdd91..d25dc21 100644 --- a/grammar.pest +++ b/grammar.pest @@ -33,7 +33,9 @@ QUOTE = _{ "\"" } protected_string = ${(sep_start ~ protected_content ~ sep_end)} protected_content = @{ (!("\"" ~ PEEK ~ "!") ~ ANY)* } -quick_command = {(string ~ "-")? ~ string_expr} +quick_command = {command_name? ~ ECHO_TOGGLE_TOKEN? ~ string_expr} +command_name = { (string ~ "-") } +ECHO_TOGGLE_TOKEN = {"@"} sep_start = _{ EXCL ~ PUSH((!"\"" ~ ANY)*) ~ QUOTE} sep_end = _{ QUOTE ~ POP ~ EXCL } diff --git a/src/core.rs b/src/core.rs index 337ca3d..77e7f58 100644 --- a/src/core.rs +++ b/src/core.rs @@ -161,7 +161,7 @@ fn run_command( cmd.settings.contains(&CommandSetting::IgnoreResult), ) } else { - if rt_conf::settings().echo_by_default { + if rt_conf::settings().echo_by_default != cmd.toggle_echo_setting { eprintln!("{arg}"); } exec_cmd(&shell.name, args) diff --git a/src/parser.rs b/src/parser.rs index 51822e2..b39e0d5 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -34,6 +34,7 @@ pub struct Command { pub name: Option, pub shell: Option, pub env_vars: Vec, + pub toggle_echo_setting: bool, } #[derive(Debug, PartialEq, Eq, Clone, Copy)] @@ -225,13 +226,14 @@ fn parse_menu(name: &str, menus: &HashMap<&str, RawMenu<'_>>) -> Result { ) } Rule::quick_command => { - let (display_name, exec_str) = parse_quick_command(child_pair); + let (display_name, toggle_echo_setting, exec_str) = parse_quick_command(child_pair); Node::Command(Command { exec_str, name: display_name, settings: vec![], env_vars: vec![], shell: None, + toggle_echo_setting, }) } Rule::anon_command => Node::Command(parse_anon_command(child_pair)), @@ -283,13 +285,14 @@ impl CmdBodyParser { None } Rule::quick_command => { - let (display_name, exec_str) = parse_quick_command(p); + let (display_name, toggle_echo_setting, exec_str) = parse_quick_command(p); Some(Command { exec_str, settings: self.settings.take().unwrap_or_default(), name: display_name, env_vars: self.vars.take().unwrap_or_default(), shell: self.shell_def.take(), + toggle_echo_setting, }) } _ => panic!("unexpected rule: {p:#?}"), @@ -330,17 +333,21 @@ fn parse_vars_def(p: Pair<'_, Rule>) -> Vec { p.into_inner().map(parse_var_def).collect() } -fn parse_quick_command(pair: Pair<'_, Rule>) -> (Option, StringExpr) { +fn parse_quick_command(pair: Pair<'_, Rule>) -> (Option, bool, StringExpr) { assert!(pair.as_rule() == Rule::quick_command); - let elems: Vec<_> = pair.into_inner().collect(); - match elems.len() { - 1 => (None, parse_string_expr(elems[0].clone())), - 2 => ( - Some(from_string(elems[0].clone())), - parse_string_expr(elems[1].clone()), - ), - _ => panic!("unexpected amount of string"), + let mut name = None; + let mut toggle_echo = false; + let mut str_expr = None; + + for elem in pair.into_inner() { + match elem.as_rule() { + Rule::command_name => name = Some(from_string(elem.inext())), + Rule::ECHO_TOGGLE_TOKEN => toggle_echo = true, + Rule::string_expr => str_expr = Some(parse_string_expr(elem)), + _ => panic!("unexpected pair: {elem:#?}"), + } } + (name, toggle_echo, str_expr.unwrap()) } fn parse_string_expr(p: Pair<'_, Rule>) -> StringExpr { @@ -472,7 +479,7 @@ mod tests { menu custom_commands { h: "print hi" - !"echo hi"! - c: "echo ciao" + c: @"echo ciao" } "#; @@ -567,6 +574,7 @@ Config { name: None, shell: None, env_vars: [], + toggle_echo_setting: true, }, ), [ @@ -586,6 +594,7 @@ Config { ), shell: None, env_vars: [], + toggle_echo_setting: false, }, ), }, @@ -606,6 +615,7 @@ Config { name: None, shell: None, env_vars: [], + toggle_echo_setting: false, }, ), }, @@ -679,6 +689,7 @@ Ok( name: None, shell: None, env_vars: [], + toggle_echo_setting: false, }, ), }, @@ -730,6 +741,7 @@ Config { value: None, }, ], + toggle_echo_setting: false, }, ), }, @@ -780,6 +792,7 @@ Config { name: None, shell: None, env_vars: [], + toggle_echo_setting: false, }, ), }, @@ -826,6 +839,7 @@ Config { name: None, shell: None, env_vars: [], + toggle_echo_setting: false, }, ), }, @@ -870,6 +884,7 @@ Config { name: None, shell: None, env_vars: [], + toggle_echo_setting: false, }, ), }, diff --git a/tests/bash_tests/echo_setting_off.dt b/tests/bash_tests/echo_setting_off.dt index 39e544f..30e72d2 100644 --- a/tests/bash_tests/echo_setting_off.dt +++ b/tests/bash_tests/echo_setting_off.dt @@ -1,5 +1,6 @@ echo off menu root { - f: "echo foo" + n: "echo don\'t show me" + y: "echo 'show me' without echoing the command" - @"echo show me" } diff --git a/tests/bash_tests/echo_setting_on.dt b/tests/bash_tests/echo_setting_on.dt index 08f3ec6..6a59f98 100644 --- a/tests/bash_tests/echo_setting_on.dt +++ b/tests/bash_tests/echo_setting_on.dt @@ -1,5 +1,6 @@ echo on menu root { - f: "echo foo" + y: "echo show me" + n: @"echo don\'t show me" } diff --git a/tests/bash_tests/echo_settings.bash b/tests/bash_tests/echo_settings.bash index 6eae407..5ad0cfd 100644 --- a/tests/bash_tests/echo_settings.bash +++ b/tests/bash_tests/echo_settings.bash @@ -1,2 +1,4 @@ -$DT -c echo_setting_on.dt f -$DT -c echo_setting_off.dt f +$DT -c echo_setting_on.dt y +$DT -c echo_setting_on.dt n +$DT -c echo_setting_off.dt y +$DT -c echo_setting_off.dt n diff --git a/tests/bash_tests/echo_settings.out b/tests/bash_tests/echo_settings.out index f43b93c..7b42414 100644 --- a/tests/bash_tests/echo_settings.out +++ b/tests/bash_tests/echo_settings.out @@ -1,3 +1,6 @@ -[?25l[?25hecho foo -foo -[?25l[?25hfoo +[?25l[?25hecho show me +show me +[?25l[?25hdon't show me +[?25l[?25hecho show me +show me +[?25l[?25hdon't show me