diff --git a/src/buffer.cc b/src/buffer.cc index 17c4a34e..60dd5ba9 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -685,7 +685,7 @@ void Buffer::on_option_changed(const Option& option) m_flags &= ~Flags::ReadOnly; } run_hook_in_own_context(Hook::BufSetOption, - format("{}={}", option.name(), option.get_as_string(Quoting::Kakoune))); + format("{}={}", option.name(), option.get_as_string(Quoting::Raw))); } void Buffer::run_hook_in_own_context(Hook hook, StringView param, String client_name) diff --git a/src/command_manager.cc b/src/command_manager.cc index 64b12a32..36f03ec4 100644 --- a/src/command_manager.cc +++ b/src/command_manager.cc @@ -286,7 +286,7 @@ Token parse_percent_token(Reader& reader, bool throw_on_unterminated) auto expand_option(Option& opt, std::true_type) { - return opt.get_as_string(Quoting::Kakoune); + return opt.get_as_string(Quoting::Raw); } auto expand_option(Option& opt, std::false_type) diff --git a/src/normal.cc b/src/normal.cc index 565f0472..2fb66e49 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -1330,8 +1330,8 @@ void select_object(Context& context, NormalParams params) EnvVarMap env_vars = { { "count", to_string(params.count) }, { "register", String{¶ms.reg, 1} }, - { "select_mode", option_to_string(mode) }, - { "object_flags", option_to_string(flags) } + { "select_mode", option_to_string(mode, Quoting::Raw) }, + { "object_flags", option_to_string(flags, Quoting::Raw) } }; command(context, std::move(env_vars)); return; diff --git a/src/option.hh b/src/option.hh index bf838c71..3c114b30 100644 --- a/src/option.hh +++ b/src/option.hh @@ -10,6 +10,7 @@ namespace Kakoune { class String; +enum class Quoting; // Forward declare functions that wont get found by ADL inline String option_to_string(int opt); @@ -27,10 +28,10 @@ option_from_strings(Meta::Type, ConstArrayView strs) } template -Vector()))> +Vector(), Quoting{}))> option_to_strings(const T& opt) { - return Vector{option_to_string(opt)}; + return Vector{option_to_string(opt, Quoting{})}; } template @@ -42,12 +43,6 @@ option_add_from_strings(T& opt, ConstArrayView strs) return option_add(opt, strs[0]); } -template -constexpr bool option_needs_quoting(Meta::Type) -{ - return not std::is_integral::value; -} - template struct PrefixedList { diff --git a/src/option_types.hh b/src/option_types.hh index c6798ef5..5c7b2a9f 100644 --- a/src/option_types.hh +++ b/src/option_types.hh @@ -25,20 +25,6 @@ option_to_string(const T& value, Quoting) return option_to_string(value); } -template -constexpr bool option_needs_quoting(Meta::Type type, Meta::Type... rest) -{ - return option_needs_quoting(type) or option_needs_quoting(rest...); -} - -template -String quote_ifn(String str, Quoting quoting) -{ - if (option_needs_quoting(Meta::Type{}...)) - return quoter(quoting)(std::move(str)); - return str; -} - template constexpr decltype(T::option_type_name) option_type_name(Meta::Type) { @@ -79,7 +65,7 @@ inline bool option_from_string(Meta::Type, StringView str) } constexpr StringView option_type_name(Meta::Type) { return "bool"; } -inline String option_to_string(Codepoint opt) { return to_string(opt); } +inline String option_to_string(Codepoint opt, Quoting quoting) { return quoter(quoting)(to_string(opt)); } inline Codepoint option_from_string(Meta::Type, StringView str) { if (str.char_length() != 1) @@ -87,18 +73,17 @@ inline Codepoint option_from_string(Meta::Type, StringView str) return str[0_char]; } constexpr StringView option_type_name(Meta::Type) { return "codepoint"; } -constexpr bool option_needs_quoting(Meta::Type) { return true; } template Vector option_to_strings(const Vector& opt) { - return opt | transform([](const T& t) { return option_to_string(t); }) | gather>(); + return opt | transform([](const T& t) { return option_to_string(t, Quoting::Raw); }) | gather>(); } template String option_to_string(const Vector& opt, Quoting quoting) { - return join(opt | transform([=](const T& t) { return quote_ifn(option_to_string(t), quoting); }), ' ', false); + return join(opt | transform([=](const T& t) { return option_to_string(t, quoting); }), ' ', false); } template @@ -136,8 +121,8 @@ Vector option_to_strings(const HashMap& opt) { return opt | transform([](auto&& item) { return format("{}={}", - escape(option_to_string(item.key), '=', '\\'), - escape(option_to_string(item.value), '=', '\\')); + escape(option_to_string(item.key, Quoting::Raw), '=', '\\'), + escape(option_to_string(item.value, Quoting::Raw), '=', '\\')); }) | gather>(); } @@ -145,10 +130,10 @@ template String option_to_string(const HashMap& opt, Quoting quoting) { return join(opt | transform([=](auto&& item) { - return quote_ifn( + return quoter(quoting)( format("{}={}", - escape(option_to_string(item.key), '=', '\\'), - escape(option_to_string(item.value), '=', '\\')), quoting); + escape(option_to_string(item.key, Quoting::Raw), '=', '\\'), + escape(option_to_string(item.value, Quoting::Raw), '=', '\\'))); }), ' ', false); } @@ -187,15 +172,15 @@ String option_type_name(Meta::Type>) constexpr char tuple_separator = '|'; template -String option_to_string_impl(const std::tuple& opt, std::index_sequence) +String option_to_string_impl(Quoting quoting, const std::tuple& opt, std::index_sequence) { - return join(make_array({option_to_string(std::get(opt))...}), tuple_separator); + return join(make_array({option_to_string(std::get(opt), quoting)...}), tuple_separator); } template -String option_to_string(const std::tuple& opt) +String option_to_string(const std::tuple& opt, Quoting quoting) { - return option_to_string_impl(opt, std::make_index_sequence()); + return option_to_string_impl(quoting, opt, std::make_index_sequence()); } template @@ -335,7 +320,7 @@ EnableIfWithBitOps option_add(Flags& opt, StringView str) template inline Vector option_to_strings(const PrefixedList& opt) { - Vector res{option_to_string(opt.prefix)}; + Vector res{option_to_string(opt.prefix, Quoting::Raw)}; auto list = option_to_strings(opt.list); res.insert(res.end(), std::make_move_iterator(list.begin()), std::make_move_iterator(list.end())); return res; diff --git a/src/scope.cc b/src/scope.cc index fab7ed0d..79da998c 100644 --- a/src/scope.cc +++ b/src/scope.cc @@ -19,7 +19,7 @@ void GlobalScope::on_option_changed(const Option& option) { Context empty_context{Context::EmptyContextFlag{}}; hooks().run_hook(Hook::GlobalSetOption, - format("{}={}", option.name(), option.get_as_string(Quoting::Kakoune)), + format("{}={}", option.name(), option.get_as_string(Quoting::Raw)), empty_context); } diff --git a/src/string_utils.hh b/src/string_utils.hh index 92714a0d..224dffc2 100644 --- a/src/string_utils.hh +++ b/src/string_utils.hh @@ -65,10 +65,6 @@ Vector wrap_lines(StringView text, ColumnCount max_width); int str_to_int(StringView str); // throws on error Optional str_to_int_ifp(StringView str); -inline String option_to_string(StringView opt) { return opt.str(); } -inline String option_from_string(Meta::Type, StringView str) { return str.str(); } -inline bool option_add(String& opt, StringView val) { opt += val; return not val.empty(); } - template struct InplaceString { @@ -142,15 +138,27 @@ inline String shell_quote(StringView s) enum class Quoting { + Raw, Kakoune, Shell }; inline auto quoter(Quoting quoting) { - return quoting == Quoting::Kakoune ? "e : &shell_quote; + switch (quoting) + { + case Quoting::Kakoune: return "e; + case Quoting::Shell: return &shell_quote; + case Quoting::Raw: + default: + return +[](StringView s) { return s.str(); }; + } } +inline String option_to_string(StringView opt, Quoting quoting) { return quoter(quoting)(opt); } +inline Vector option_to_strings(StringView opt) { return {opt.str()}; } +inline String option_from_string(Meta::Type, StringView str) { return str.str(); } +inline bool option_add(String& opt, StringView val) { opt += val; return not val.empty(); } } diff --git a/src/window.cc b/src/window.cc index f44ea92b..29ac73de 100644 --- a/src/window.cc +++ b/src/window.cc @@ -338,7 +338,7 @@ void Window::clear_display_buffer() void Window::on_option_changed(const Option& option) { run_hook_in_own_context(Hook::WinSetOption, format("{}={}", option.name(), - option.get_as_string(Quoting::Kakoune))); + option.get_as_string(Quoting::Raw))); // an highlighter might depend on the option, so we need to redraw force_redraw(); }