From 5b98d3badc3094b400408485aebfb26114164cda Mon Sep 17 00:00:00 2001 From: iff Date: Tue, 7 Jan 2025 01:46:29 +0100 Subject: [PATCH] feat: select placeholder --- module-runtime-rules/src/replaces.rs | 47 ++++++++++++++---- module-runtime-rules/src/rules.rs | 16 +++++-- parser/src/lib.rs | 12 ++--- parser/src/replaces.rs | 71 +++++++++++++++++++++------- rules/pr_general.toml | 2 +- 5 files changed, 109 insertions(+), 39 deletions(-) diff --git a/module-runtime-rules/src/replaces.rs b/module-runtime-rules/src/replaces.rs index 82e4ed5..ecce68c 100644 --- a/module-runtime-rules/src/replaces.rs +++ b/module-runtime-rules/src/replaces.rs @@ -182,14 +182,15 @@ pub fn typo(suggest: &mut String, split_command: &[String], executables: &[Strin } } -pub fn exes( +pub fn select( + shell: &str, suggest: &mut String, split_command: &[String], executables: &[String], - exes_list: &mut Vec, + select_list: &mut Vec, ) { - if suggest.contains("{{exes") { - let (placeholder, args) = eval_placeholder(suggest, "{{exes", "}}"); + if suggest.contains("{{select") { + let (placeholder, args) = eval_placeholder(suggest, "{{select", "}}"); let index = if suggest.contains('[') { let split = suggest[args.to_owned()] @@ -206,25 +207,51 @@ pub fn exes( }; index as usize } else { - unreachable!("Exes suggestion does not support range"); + unreachable!("Select suggestion does not support range"); } } else { - unreachable!("Exes suggestion must have a command index"); + unreachable!("Select suggestion must have a command index"); }; - let matches = { + let selection_list = if suggest.contains('(') { + let split = suggest[args.to_owned()] + .split_once("(") + .unwrap() + .1 + .rsplit_once(")") + .unwrap() + .0; + split.split(',').collect::>() + } else { + unreachable!("Select suggestion must have a match list"); + }; + + let selection_list = selection_list + .iter() + .map(|s| s.trim().to_string()) + .collect::>(); + + let selects = if selection_list[0].starts_with("{{shell") { + let function = selection_list.join(","); + let (_, args) = eval_placeholder(&function, "{{shell", "}}"); + let function = &function[args.to_owned()].trim_matches(|c| c == '(' || c == ')'); + eval_shell_command(shell, function) + } else if selection_list[0] == "path" { let res = best_matches_path(&split_command[index], executables); if let Some(res) = res { res } else { vec![split_command[index].clone()] } + } else { + selection_list }; - for match_ in matches { - exes_list.push(match_); + + for match_ in selects { + select_list.push(match_); } - let tag = "{{exes}}"; + let tag = "{{selection}}"; let placeholder = suggest[placeholder.clone()].to_owned(); *suggest = suggest.replace(&placeholder, tag); } diff --git a/module-runtime-rules/src/rules.rs b/module-runtime-rules/src/rules.rs index 2524206..a891098 100644 --- a/module-runtime-rules/src/rules.rs +++ b/module-runtime-rules/src/rules.rs @@ -140,19 +140,25 @@ fn eval_suggest( replaces::shell(&mut suggest, shell); replaces::typo(&mut suggest, &split_command, executables, shell); - let mut exes_list = Vec::new(); - replaces::exes(&mut suggest, &split_command, executables, &mut exes_list); + let mut select_list = Vec::new(); + replaces::select( + shell, + &mut suggest, + &split_command, + executables, + &mut select_list, + ); for (tag, value) in opt_list { suggest = suggest.replace(&tag, &value); } let mut suggests = vec![]; - if exes_list.is_empty() { + if select_list.is_empty() { suggests.push(suggest); } else { - for exe in exes_list { - let eval_suggest = suggest.clone().replace("{{exes}}", &exe); + for exe in select_list { + let eval_suggest = suggest.clone().replace("{{selection}}", &exe); suggests.push(eval_suggest); } } diff --git a/parser/src/lib.rs b/parser/src/lib.rs index 148c06d..34f4e3e 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -188,7 +188,7 @@ fn eval_suggest(suggest: &str) -> TokenStream2 { } let mut replace_list = Vec::new(); - let mut exes_list = Vec::new(); + let mut select_list = Vec::new(); let mut opt_list = Vec::new(); let mut cmd_list = Vec::new(); @@ -198,19 +198,19 @@ fn eval_suggest(suggest: &str) -> TokenStream2 { replaces::command(&mut suggest, &mut replace_list); replaces::shell(&mut suggest, &mut cmd_list); replaces::typo(&mut suggest, &mut replace_list); - replaces::exes(&mut suggest, &mut exes_list); + replaces::select(&mut suggest, &mut select_list); replaces::shell_tag(&mut suggest, &mut replace_list, &cmd_list); - let suggests = if exes_list.is_empty() { + let suggests = if select_list.is_empty() { quote! { candidates.push(format!{#suggest, #(#replace_list),*}); } } else { quote! { - #(#exes_list)* + #(#select_list)* let suggest = format!{#suggest, #(#replace_list),*}; - for match_ in exes_matches { - let suggest = suggest.replace("{{exes}}", &match_); + for select in selects { + let suggest = suggest.replace("{{selection}}", &select); candidates.push(suggest); } } diff --git a/parser/src/replaces.rs b/parser/src/replaces.rs index 5c26111..daef69e 100644 --- a/parser/src/replaces.rs +++ b/parser/src/replaces.rs @@ -237,9 +237,9 @@ pub fn typo(suggest: &mut String, replace_list: &mut Vec) { } } -pub fn exes(suggest: &mut String, exes_list: &mut Vec) { - if suggest.contains("{{exes") { - let (placeholder, args) = eval_placeholder(suggest, "{{exes", "}}"); +pub fn select(suggest: &mut String, select_list: &mut Vec) { + if suggest.contains("{{select") { + let (placeholder, args) = eval_placeholder(suggest, "{{select", "}}"); let index = if suggest.contains('[') { let split = suggest[args.to_owned()] @@ -255,25 +255,62 @@ pub fn exes(suggest: &mut String, exes_list: &mut Vec) { quote! {#command_index as usize} } } else { - unreachable!("Exes suggestion does not support range"); + unreachable!("Select suggestion does not support range"); } } else { - unreachable!("Exes suggestion must have a command index"); + unreachable!("Select suggestion must have a command index"); + }; + let selection_list = if suggest.contains('(') { + let split = suggest[args.to_owned()] + .split_once("(") + .unwrap() + .1 + .rsplit_once(")") + .unwrap() + .0; + split.split(',').collect::>() + } else { + unreachable!("Select suggestion must have a selection list"); }; - let command = quote! { - let exes_matches = { - let res = best_matches_path(&split[#index], executables); - if res.is_none() { - vec![split[#index].clone()] - } else { - res.unwrap() - } - }; - }; - exes_list.push(command); + let selection_list = selection_list + .iter() + .map(|s| s.trim().to_string()) + .collect::>(); - let tag = "{{{{exes}}}}"; + let command = if selection_list[0].starts_with("eval_shell_command(") { + let function = selection_list.join(","); + // add a " after first comma, and a " before last ) + let function = format!( + "{}\"{}{}", + &function[..function.find(',').unwrap() + 1], + &function[function.find(',').unwrap() + 1..function.len() - 1], + "\")" + ); + quote! { + let selects = #function; + } + } else if selection_list[0] == "path" { + quote! { + let selects = { + let res = best_matches_path(&split[#index], executables); + if res.is_none() { + vec![split[#index].clone()] + } else { + res.unwrap() + } + }; + } + } else { + let string_match_list = selection_list.join("\".to_string(), \""); + let string_match_list = format!("\"{}\".to_string()", string_match_list); + quote! { + let selects = vec![#string_match_list]; + } + }; + + select_list.push(command); + let tag = "{{{{selection}}}}"; let placeholder = suggest[placeholder.clone()].to_owned(); *suggest = suggest.replace(&placeholder, tag); } diff --git a/rules/pr_general.toml b/rules/pr_general.toml index 352c533..75afdaa 100644 --- a/rules/pr_general.toml +++ b/rules/pr_general.toml @@ -9,5 +9,5 @@ pattern = [ ] suggest = [ ''' -{{exes[0]}} {{command[1:]}} ''' +{{select[0](path)}} {{command[1:]}} ''' ]