From d1e19727ff9d3ae9c90609e4b6a1671f43b15dd6 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Wed, 31 Mar 2021 17:15:31 +1100 Subject: [PATCH] Tweak completion quoting behaviour once again Quote by wrapping in quotes if we are replacing the whole token, using backspaces if the completion only adds to it. This ensure that the inserted completion will be correctly parsed once validated. Fixes #4121 --- src/command_manager.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/command_manager.cc b/src/command_manager.cc index 1e1f2035..cb7ddf82 100644 --- a/src/command_manager.cc +++ b/src/command_manager.cc @@ -669,16 +669,18 @@ Completions CommandManager::complete(const Context& context, const auto& token = tokens.back(); auto requote = [](Completions completions, Token::Type token_type) { - if ((completions.flags & Completions::Flags::Quoted) or - completions.start != 0) + if (completions.flags & Completions::Flags::Quoted) return completions; if (token_type == Token::Type::Raw) { - for (auto& c : completions.candidates) + const bool at_token_start = completions.start == 0; + for (auto& candidate : completions.candidates) { - if (c.substr(0_byte, 1_byte) == "%" or any_of(c, [](auto i) { return contains("; \t'\"", i); })) - c = quote(c); + const StringView to_escape = ";\n \t"; + if ((at_token_start and candidate.substr(0_byte, 1_byte) == "%") or + any_of(candidate, [&](auto c) { return contains(to_escape, c); })) + candidate = at_token_start ? quote(candidate) : escape(candidate, to_escape, '\\'); } } else if (token_type == Token::Type::RawQuoted)