diff --git a/CHANGELOG.md b/CHANGELOG.md index ca471d1b9..8a28a887e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ This section is for changes merged to the `major` branch that are not also merge - `read` now requires at least one var name (#4220). - `set x[1] x[2] a b` is no longer valid syntax (#4236). - For loop control variables are no longer local to the for block (#1935). +- A literal `{}` now expands to itself, rather than nothing. This makes working with `find -exec` easier. (#1109, #4632) ## Notable fixes and improvements - `wait` builtin is added for waiting on processes (#4498). diff --git a/doc_src/faq.hdr b/doc_src/faq.hdr index eefbe5eff..45756f77e 100644 --- a/doc_src/faq.hdr +++ b/doc_src/faq.hdr @@ -24,7 +24,6 @@ - I'm seeing weird output before each prompt when using screen. What's wrong? - How do I change the greeting message? - Why doesn't history substitution ("!$" etc.) work? -- Why do I get a missing argument error with `find ... {}`? - How can I use `-` as a shortcut for `cd -`? - How do I uninstall fish? - Where can I find extra tools for fish? @@ -244,21 +243,6 @@ Fish history recall is very simple yet effective: See documentation for more details about line editing in fish. -
-\section faq-find-braces Why do I get a missing argument error with `find ... {}`? - -Running `find ... -exec ... {}` produces an error: - - find: missing argument to '-exec' - -The problem is caused by the empty braces, which are subject to brace expansion. - -Quote the empty braces to achieve the desired effect: - -\fish{cli-dark} -find ... -exec ... '{{}}' -\endfish -
\section faq-cd-minus How can I use `-` as a shortcut for `cd -`? diff --git a/doc_src/index.hdr.in b/doc_src/index.hdr.in index ac4441629..5a398cc00 100644 --- a/doc_src/index.hdr.in +++ b/doc_src/index.hdr.in @@ -506,6 +506,14 @@ mv *.{c,h} src/ # Moves all files with the suffix '.c' or '.h' to the subdirectory src. \endfish +A literal "{}" will not be used as a brace expansion: + +\fish +echo foo-{} +# Outputs foo-{} + +echo foo-{$undefinedvar} +# Output is an empty line - see the cartesian product section \subsection expand-variable Variable expansion diff --git a/src/expand.cpp b/src/expand.cpp index d5e8e25b7..a37015c73 100644 --- a/src/expand.cpp +++ b/src/expand.cpp @@ -980,6 +980,15 @@ static expand_error_t expand_brackets(const wcstring &instr, expand_flags_t flag } } + // Expand a literal "{}" to itself because it is useless otherwise, + // and this eases e.g. `find -exec {}`. See #1109. + if (bracket_begin + 1 == bracket_end) { + wcstring newstr = instr; + newstr.at(bracket_begin - in) = L'{'; + newstr.at(bracket_end - in) = L'}'; + return expand_brackets(newstr, flags, out, errors); + } + if (syntax_error) { append_syntax_error(errors, SOURCE_LOCATION_UNKNOWN, _(L"Mismatched brackets")); return EXPAND_ERROR; diff --git a/tests/test1.in b/tests/test1.in index d14c11836..95d3ea8be 100644 --- a/tests/test1.in +++ b/tests/test1.in @@ -15,6 +15,10 @@ logmsg Bracket expansion echo x-{1} echo x-{1,2} echo foo-{1,2{3,4}} +echo foo-{} # literal "{}" expands to itself +echo foo-{{},{}} # the inner "{}" expand to themselves, the outer pair expands normally. +echo foo-{""} # still expands to foo- +echo foo-{$undefinedvar} # still expands to nothing logmsg Escaped newlines echo foo\ bar diff --git a/tests/test1.out b/tests/test1.out index 292238753..14b22a690 100644 --- a/tests/test1.out +++ b/tests/test1.out @@ -11,6 +11,11 @@ x-1 x-1 x-2 foo-1 foo-23 foo-24 +foo-{} +foo-{} foo-{} +foo- + +foo- foo- foo- foo- #################### # Escaped newlines