Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- Fire the "search pattern contains a path separator" diagnostic for any pattern containing `/`, not just patterns that happen to name an existing directory. Preserves the legacy Windows behaviour that also flags native `\` separators when the pattern resolves to a real directory. See #1873.
- Also fire the "search pattern contains a path separator" diagnostic for `--and` patterns, not only the primary positional pattern. `--and` patterns are matched against the file name just like the primary pattern, so a path separator in them silently returned zero results. See #1873.
- Fix bug where passing "-" as a directory argument didn't actually search that directory, see #849 (@Sean-Kenneth-Doherty).
- Fix `--format`/`--exec` placeholders that are immediately followed by a literal `}` (e.g. `{}}` or `{.}}`). The placeholder is now expanded with the `}` kept as trailing literal text, instead of the whole sequence being treated as fixed text.

# 10.4.2

Expand Down
7 changes: 3 additions & 4 deletions src/exec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,10 +369,9 @@ mod tests {
fn tokens_with_literal_braces() {
let template =
CommandTemplate::new(vec!["{{}}", "{{", "{.}}"], ExecutionMode::OneByOne).unwrap();
assert_eq!(
generate_str(&template, "foo"),
vec!["{}", "{", "{.}", "foo"]
);
// `{{}}` and `{{` are literal-brace escapes, while `{.}}` expands the
// `{.}` placeholder and keeps the trailing `}` as a literal.
assert_eq!(generate_str(&template, "foo"), vec!["{}", "{", "foo}"]);
}

#[test]
Expand Down
39 changes: 31 additions & 8 deletions src/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,21 +73,19 @@ impl FormatTemplate {
buf += &remaining[..m.start() + BRACE_LEN];
remaining = &remaining[m.end()..];
}
id if !remaining[m.end()..].starts_with('}') => {
id => {
// We found a placeholder. Add any preceding text to the
// buffer, flush it, then push the placeholder token. A
// literal '}' following the placeholder (as in `{}}`) is
// left in `remaining` and handled as ordinary text on the
// next iteration.
buf += &remaining[..m.start()];
if !buf.is_empty() {
tokens.push(Token::Text(std::mem::take(&mut buf)));
}
tokens.push(token_from_pattern_id(id));
remaining = &remaining[m.end()..];
}
_ => {
// We got a normal pattern, but the final "}"
// is escaped, so add up to that to the buffer, then
// skip the final }
buf += &remaining[..m.end()];
remaining = &remaining[m.end() + BRACE_LEN..];
}
}
}
// Add the rest of the string to the buffer, and add the final buffer to the tokens
Expand Down Expand Up @@ -233,6 +231,31 @@ mod fmt_tests {
);
}

#[test]
fn parse_placeholder_followed_by_literal_brace() {
use Token::*;

// A placeholder immediately followed by a literal '}' should still be
// expanded, with the '}' kept as trailing literal text.
assert_eq!(
FormatTemplate::parse("{}}"),
FormatTemplate::Tokens(vec![Placeholder, Text("}".into())])
);
assert_eq!(
FormatTemplate::parse("{/}}"),
FormatTemplate::Tokens(vec![Basename, Text("}".into())])
);

let mut path = PathBuf::new();
path.push("a");
path.push("file.txt");
let expanded = FormatTemplate::parse("{}}")
.generate(&path, Some("/"))
.into_string()
.unwrap();
assert_eq!(expanded, "a/file.txt}");
}

#[test]
fn all_placeholders() {
use Token::*;
Expand Down
7 changes: 7 additions & 0 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1755,6 +1755,13 @@ fn format() {
parent=one/two/three
parent=one/two/three",
);

// A placeholder immediately followed by a literal '}' is still expanded,
// with the '}' kept as trailing literal text (see issue with `{}}`).
te.assert_output(
&["^a\\.foo$", "--format", "{}}", "--path-separator=/"],
"a.foo}",
);
}

/// Shell script execution (--exec)
Expand Down