mirror of
https://github.com/TECHNOFAB11/pay-respects.git
synced 2026-02-02 15:45:11 +01:00
feat: regex matching
This commit is contained in:
parent
a5762bf121
commit
3e367a09dd
8 changed files with 85 additions and 93 deletions
|
|
@ -6,4 +6,4 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
colored = "2.0"
|
colored = "2.0"
|
||||||
rule_parser = { path = "rule_parser" }
|
rule_parser = { path = "rule_parser" }
|
||||||
regex = "1.0"
|
regex-lite = "0.1"
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ The placeholder is evaluated as following:
|
||||||
- `{{command[1]}}`: The first argument of the command (the command itself has index of 0)
|
- `{{command[1]}}`: The first argument of the command (the command itself has index of 0)
|
||||||
- `{{command[2:5]}}`: The second to fifth arguments. If any of the side is not specified, them it defaults to the start (if it is left) or the end (if it is right).
|
- `{{command[2:5]}}`: The second to fifth arguments. If any of the side is not specified, them it defaults to the start (if it is left) or the end (if it is right).
|
||||||
- `{{typo[2](fix1, fix2)}}`: This will try to change the second argument to candidates in the parenthesis. The argument in parentheses must have at least 2 values. Single arguments are reserved for specific matches, for instance, `path` to search all commands found in the `$PATH` environment.
|
- `{{typo[2](fix1, fix2)}}`: This will try to change the second argument to candidates in the parenthesis. The argument in parentheses must have at least 2 values. Single arguments are reserved for specific matches, for instance, `path` to search all commands found in the `$PATH` environment.
|
||||||
- `{{opt(fix1, -*)}}`: Optional patterns that are found in the command. Note that all patterns matching this placeholder will not take a place when indexing (for example, in `rm {{opt(-r)}} file` the index of the file is always 1 regardless where `-r` was placed by the user).
|
- `{{opt::<Regular Expression>}}`: Optional patterns that are found in the command with RegEx (see RegEx crate for syntax). Note that all patterns matching this placeholder will not take a place when indexing.
|
||||||
|
|
||||||
The suggestion can have additional conditions to check. To specify the conditions, add a `#[...]` at the first line (just like derive macros in Rust). Available conditions:
|
The suggestion can have additional conditions to check. To specify the conditions, add a `#[...]` at the first line (just like derive macros in Rust). Available conditions:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,9 +55,9 @@ fn gen_string_hashmap(rules: Vec<Rule>) -> String {
|
||||||
.map(|x| x.to_lowercase())
|
.map(|x| x.to_lowercase())
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
string_hashmap.push_str(&format!(
|
string_hashmap.push_str(&format!(
|
||||||
"(vec![\"{}\"], vec![\"{}\"]),",
|
"(vec![\"{}\"], vec![r###\"{}\"###]),",
|
||||||
pattern.join("\", \""),
|
pattern.join("\", \""),
|
||||||
suggest.join("\", \"")
|
suggest.join("\"###, r###\"")
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
string_hashmap.push_str("]),");
|
string_hashmap.push_str("]),");
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,6 @@ pattern = [
|
||||||
]
|
]
|
||||||
suggest = [
|
suggest = [
|
||||||
'''
|
'''
|
||||||
{{typo[0](path)}} {{command[1:]}}'''
|
{{typo[0](path)}} {{command[1:]}}
|
||||||
|
'''
|
||||||
]
|
]
|
||||||
|
|
|
||||||
114
rules/git.toml
114
rules/git.toml
|
|
@ -6,62 +6,62 @@ pattern = [
|
||||||
]
|
]
|
||||||
suggest = [
|
suggest = [
|
||||||
"""
|
"""
|
||||||
{{command[0]}} {{typo[1](\
|
{{command[0]}} {{typo[1](
|
||||||
add,\
|
add,
|
||||||
am,\
|
am,
|
||||||
archive,\
|
archive,
|
||||||
bisect,\
|
bisect,
|
||||||
branch,\
|
branch,
|
||||||
bundle,\
|
bundle,
|
||||||
checkout,\
|
checkout,
|
||||||
cherry-pick,\
|
cherry-pick,
|
||||||
citool,\
|
citool,
|
||||||
clean,\
|
clean,
|
||||||
clone,\
|
clone,
|
||||||
commit,\
|
commit,
|
||||||
describe,\
|
describe,
|
||||||
diff,\
|
diff,
|
||||||
fetch,\
|
fetch,
|
||||||
format-patch,\
|
format-patch,
|
||||||
gc,\
|
gc,
|
||||||
gitk,\
|
gitk,
|
||||||
grep,\
|
grep,
|
||||||
gui,\
|
gui,
|
||||||
init,\
|
init,
|
||||||
log,\
|
log,
|
||||||
maintenance,\
|
maintenance,
|
||||||
merge,\
|
merge,
|
||||||
mv,\
|
mv,
|
||||||
notes,\
|
notes,
|
||||||
pull,\
|
pull,
|
||||||
push,\
|
push,
|
||||||
range-diff,\
|
range-diff,
|
||||||
rebase,\
|
rebase,
|
||||||
reset,\
|
reset,
|
||||||
restore,\
|
restore,
|
||||||
revert
|
revert
|
||||||
rm,\
|
rm,
|
||||||
scalar,\
|
scalar,
|
||||||
shortlog,\
|
shortlog,
|
||||||
show,\
|
show,
|
||||||
sparse-checkout,\
|
sparse-checkout,
|
||||||
stash,\
|
stash,
|
||||||
status,\
|
status,
|
||||||
submodule,\
|
submodule,
|
||||||
switch,\
|
switch,
|
||||||
tag,\
|
tag,
|
||||||
worktree,\
|
worktree,
|
||||||
config,\
|
config,
|
||||||
fast-export,\
|
fast-export,
|
||||||
fast-import,\
|
fast-import,
|
||||||
filter-branch,\
|
filter-branch,
|
||||||
mergetool,\
|
mergetool,
|
||||||
pack-refs,\
|
pack-refs,
|
||||||
prune,\
|
prune,
|
||||||
reflog,\
|
reflog,
|
||||||
remote,\
|
remote,
|
||||||
repack,\
|
repack,
|
||||||
replace,\
|
replace,
|
||||||
)}} \
|
)}} {{command[2:]}}
|
||||||
{{command[2:]}}"""
|
"""
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,10 @@ pattern = [
|
||||||
suggest = [
|
suggest = [
|
||||||
'''
|
'''
|
||||||
#[executable(sudo)]
|
#[executable(sudo)]
|
||||||
sudo {{command}}''',
|
sudo {{command}}
|
||||||
|
''',
|
||||||
'''
|
'''
|
||||||
#[executable(doas)]
|
#[executable(doas)]
|
||||||
doas {{command}}''',
|
doas {{command}}
|
||||||
|
''',
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,15 @@ command = "rm"
|
||||||
pattern = [ "is a directory", ]
|
pattern = [ "is a directory", ]
|
||||||
suggest = [
|
suggest = [
|
||||||
'''
|
'''
|
||||||
{{command}} --recursive'''
|
{{command}} --recursive
|
||||||
|
'''
|
||||||
]
|
]
|
||||||
|
|
||||||
[[match_err]]
|
[[match_err]]
|
||||||
pattern = [ "no such file or directory", ]
|
pattern = [ "no such file or directory", ]
|
||||||
suggest = [
|
suggest = [
|
||||||
'''
|
'''
|
||||||
{{command[0}} {{opt(-*)}} {{typo[-1](file)}}'''
|
{{command[0}} {{opt::(?:\s)-[\w]+}} {{typo[-1](file)}}
|
||||||
|
'''
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use regex_lite::Regex;
|
||||||
|
|
||||||
use rule_parser::parse_rules;
|
use rule_parser::parse_rules;
|
||||||
|
|
||||||
|
|
@ -118,8 +119,8 @@ fn eval_suggest(suggest: &str, last_command: &str) -> String {
|
||||||
suggest = suggest.replace("{{command}}", &last_command);
|
suggest = suggest.replace("{{command}}", &last_command);
|
||||||
}
|
}
|
||||||
|
|
||||||
while suggest.contains("{{opt") {
|
while suggest.contains("{{opt::") {
|
||||||
let placeholder_start = "{{opt";
|
let placeholder_start = "{{opt::";
|
||||||
let placeholder_end = "}}";
|
let placeholder_end = "}}";
|
||||||
|
|
||||||
let start_index = suggest.find(placeholder_start).unwrap();
|
let start_index = suggest.find(placeholder_start).unwrap();
|
||||||
|
|
@ -130,31 +131,18 @@ fn eval_suggest(suggest: &str, last_command: &str) -> String {
|
||||||
let placeholder = start_index..end_index;
|
let placeholder = start_index..end_index;
|
||||||
|
|
||||||
let args = start_index + placeholder_start.len()..end_index - placeholder_end.len();
|
let args = start_index + placeholder_start.len()..end_index - placeholder_end.len();
|
||||||
let range = suggest[args.to_owned()].trim_matches(|c| c == '(' || c == ')');
|
let opt = &suggest[args.to_owned()];
|
||||||
let candidates = range.split(',').collect::<Vec<&str>>();
|
let regex = opt.trim();
|
||||||
let mut opts = Vec::new();
|
let regex = Regex::new(regex).unwrap();
|
||||||
let mut split_command = split_command(&last_command);
|
let opts = regex
|
||||||
for opt in candidates {
|
.find_iter(&last_command)
|
||||||
let opt = opt.trim();
|
.map(|cap| cap.as_str().to_owned())
|
||||||
if opt.ends_with('*') {
|
.collect::<Vec<String>>();
|
||||||
let opt = opt.trim_end_matches('*');
|
|
||||||
for split in split_command.iter_mut() {
|
|
||||||
if split.starts_with(opt) {
|
|
||||||
opts.push(split.to_owned());
|
|
||||||
split.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for split in split_command.iter_mut() {
|
|
||||||
if split == opt {
|
|
||||||
opts.push(split.to_owned());
|
|
||||||
split.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
last_command = split_command.join(" ");
|
|
||||||
suggest.replace_range(placeholder, &opts.join(" "));
|
suggest.replace_range(placeholder, &opts.join(" "));
|
||||||
|
for opt in opts {
|
||||||
|
last_command = last_command.replace(&opt, "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let split_command = split_command(&last_command);
|
let split_command = split_command(&last_command);
|
||||||
|
|
@ -243,7 +231,6 @@ fn eval_suggest(suggest: &str, last_command: &str) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn split_command(command: &str) -> Vec<String> {
|
pub fn split_command(command: &str) -> Vec<String> {
|
||||||
use regex::Regex;
|
|
||||||
let regex = r#"([^\s"\\]+|"(?:\\.|[^"\\])*"|\\.)+"#;
|
let regex = r#"([^\s"\\]+|"(?:\\.|[^"\\])*"|\\.)+"#;
|
||||||
let regex = Regex::new(regex).unwrap();
|
let regex = Regex::new(regex).unwrap();
|
||||||
let split_command = regex
|
let split_command = regex
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue