Skip to content

Commit

Permalink
Brute force attempt at clap-rs#1596
Browse files Browse the repository at this point in the history
 * This escapes everything that comes up in the reproducer from the
   above issue. NB: this means possible_value only.

missing:

 * possible_value(...).about
 * Arg(...).value_name[s]
 * Arg(...).about
 * Arg(...).long
  • Loading branch information
pseyfert committed Oct 8, 2021
1 parent 00f7fe5 commit cc6e5a4
Showing 1 changed file with 34 additions and 5 deletions.
39 changes: 34 additions & 5 deletions clap_generate/src/generators/shells/zsh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ fn value_completion(arg: &Arg) -> Option<String> {
} else {
Some(format!(
r#"{name}\:"{about}""#,
name = escape_value(value.get_name()),
name = escape_value(value.get_name(), true),
about = value.get_about().map(escape_help).unwrap_or_default()
))
}
Expand All @@ -371,7 +371,15 @@ fn value_completion(arg: &Arg) -> Option<String> {
"({})",
values
.iter()
.filter_map(ArgValue::get_visible_name)
// .filter_map(ArgValue::get_visible_name)
.filter_map(|value| {
if value.is_hidden() {
None
} else {
Some(format!("{}", escape_value(value.get_name(), false)
))
}
})
.collect::<Vec<_>>()
.join(" ")
))
Expand Down Expand Up @@ -411,13 +419,34 @@ fn escape_help(string: &str) -> String {
}

/// Escape value string inside single quotes and parentheses
fn escape_value(string: &str) -> String {
fn escape_value(string: &str, for_about: bool) -> String {
string
.replace("\\", "\\\\")
.replace("'", "'\\''")
// .replace("\\", "\\\\")
// .replace("\\", "\\\\\\\\") // ':: :((\\\\\:"some descr"))' \
.replace("\\", if for_about {"\\\\\\\\"} else {"\\\\"})
.replace("'", "'\\\\\\''")
.replace("(", "\\(")
.replace(")", "\\)")
.replace("[", "\\[")
.replace("]", "\\]")
.replace(" ", "\\ ")
.replace("$", "\\$")
.replace("`", "\\`")
.replace("\"", "\\\"")
.replace("&", "\\&")
.replace("#", "\\#")
.replace("{", "\\{")
.replace("|", "\\|")
.replace("}", "\\}")
.replace("~", "\\~")
.replace("?", "\\?")
.replace("^", "\\^")
.replace("*", "\\*")
.replace(";", "\\;")
.replace("<", "\\<")
.replace(">", "\\>")
.replace("=", "\\=") // ':: :((\=\:"some descr"))' \
.replace(":", if for_about {"\\\\\\:"} else {":"}) // ':: :((\\\:\:"some descr"))' \
}

fn write_opts_of(p: &App, p_global: Option<&App>) -> String {
Expand Down

0 comments on commit cc6e5a4

Please sign in to comment.