Refactor option_to_string quoting support, introduce Quoting::Raw
This commit is contained in:
parent
59e43c8f0c
commit
8b2906a14d
|
@ -685,7 +685,7 @@ void Buffer::on_option_changed(const Option& option)
|
||||||
m_flags &= ~Flags::ReadOnly;
|
m_flags &= ~Flags::ReadOnly;
|
||||||
}
|
}
|
||||||
run_hook_in_own_context(Hook::BufSetOption,
|
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)
|
void Buffer::run_hook_in_own_context(Hook hook, StringView param, String client_name)
|
||||||
|
|
|
@ -286,7 +286,7 @@ Token parse_percent_token(Reader& reader, bool throw_on_unterminated)
|
||||||
|
|
||||||
auto expand_option(Option& opt, std::true_type)
|
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)
|
auto expand_option(Option& opt, std::false_type)
|
||||||
|
|
|
@ -1330,8 +1330,8 @@ void select_object(Context& context, NormalParams params)
|
||||||
EnvVarMap env_vars = {
|
EnvVarMap env_vars = {
|
||||||
{ "count", to_string(params.count) },
|
{ "count", to_string(params.count) },
|
||||||
{ "register", String{¶ms.reg, 1} },
|
{ "register", String{¶ms.reg, 1} },
|
||||||
{ "select_mode", option_to_string(mode) },
|
{ "select_mode", option_to_string(mode, Quoting::Raw) },
|
||||||
{ "object_flags", option_to_string(flags) }
|
{ "object_flags", option_to_string(flags, Quoting::Raw) }
|
||||||
};
|
};
|
||||||
command(context, std::move(env_vars));
|
command(context, std::move(env_vars));
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
class String;
|
class String;
|
||||||
|
enum class Quoting;
|
||||||
|
|
||||||
// Forward declare functions that wont get found by ADL
|
// Forward declare functions that wont get found by ADL
|
||||||
inline String option_to_string(int opt);
|
inline String option_to_string(int opt);
|
||||||
|
@ -27,10 +28,10 @@ option_from_strings(Meta::Type<T>, ConstArrayView<String> strs)
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Vector<decltype(option_to_string(std::declval<T>()))>
|
Vector<decltype(option_to_string(std::declval<T>(), Quoting{}))>
|
||||||
option_to_strings(const T& opt)
|
option_to_strings(const T& opt)
|
||||||
{
|
{
|
||||||
return Vector<String>{option_to_string(opt)};
|
return Vector<String>{option_to_string(opt, Quoting{})};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -42,12 +43,6 @@ option_add_from_strings(T& opt, ConstArrayView<String> strs)
|
||||||
return option_add(opt, strs[0]);
|
return option_add(opt, strs[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr bool option_needs_quoting(Meta::Type<T>)
|
|
||||||
{
|
|
||||||
return not std::is_integral<T>::value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename P, typename T>
|
template<typename P, typename T>
|
||||||
struct PrefixedList
|
struct PrefixedList
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,20 +25,6 @@ option_to_string(const T& value, Quoting)
|
||||||
return option_to_string(value);
|
return option_to_string(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename... Rest>
|
|
||||||
constexpr bool option_needs_quoting(Meta::Type<T> type, Meta::Type<Rest>... rest)
|
|
||||||
{
|
|
||||||
return option_needs_quoting(type) or option_needs_quoting(rest...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Ts>
|
|
||||||
String quote_ifn(String str, Quoting quoting)
|
|
||||||
{
|
|
||||||
if (option_needs_quoting(Meta::Type<Ts>{}...))
|
|
||||||
return quoter(quoting)(std::move(str));
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr decltype(T::option_type_name) option_type_name(Meta::Type<T>)
|
constexpr decltype(T::option_type_name) option_type_name(Meta::Type<T>)
|
||||||
{
|
{
|
||||||
|
@ -79,7 +65,7 @@ inline bool option_from_string(Meta::Type<bool>, StringView str)
|
||||||
}
|
}
|
||||||
constexpr StringView option_type_name(Meta::Type<bool>) { return "bool"; }
|
constexpr StringView option_type_name(Meta::Type<bool>) { 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<Codepoint>, StringView str)
|
inline Codepoint option_from_string(Meta::Type<Codepoint>, StringView str)
|
||||||
{
|
{
|
||||||
if (str.char_length() != 1)
|
if (str.char_length() != 1)
|
||||||
|
@ -87,18 +73,17 @@ inline Codepoint option_from_string(Meta::Type<Codepoint>, StringView str)
|
||||||
return str[0_char];
|
return str[0_char];
|
||||||
}
|
}
|
||||||
constexpr StringView option_type_name(Meta::Type<Codepoint>) { return "codepoint"; }
|
constexpr StringView option_type_name(Meta::Type<Codepoint>) { return "codepoint"; }
|
||||||
constexpr bool option_needs_quoting(Meta::Type<Codepoint>) { return true; }
|
|
||||||
|
|
||||||
template<typename T, MemoryDomain domain>
|
template<typename T, MemoryDomain domain>
|
||||||
Vector<String> option_to_strings(const Vector<T, domain>& opt)
|
Vector<String> option_to_strings(const Vector<T, domain>& opt)
|
||||||
{
|
{
|
||||||
return opt | transform([](const T& t) { return option_to_string(t); }) | gather<Vector<String>>();
|
return opt | transform([](const T& t) { return option_to_string(t, Quoting::Raw); }) | gather<Vector<String>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, MemoryDomain domain>
|
template<typename T, MemoryDomain domain>
|
||||||
String option_to_string(const Vector<T, domain>& opt, Quoting quoting)
|
String option_to_string(const Vector<T, domain>& opt, Quoting quoting)
|
||||||
{
|
{
|
||||||
return join(opt | transform([=](const T& t) { return quote_ifn<T>(option_to_string(t), quoting); }), ' ', false);
|
return join(opt | transform([=](const T& t) { return option_to_string(t, quoting); }), ' ', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, MemoryDomain domain>
|
template<typename T, MemoryDomain domain>
|
||||||
|
@ -136,8 +121,8 @@ Vector<String> option_to_strings(const HashMap<Key, Value, domain>& opt)
|
||||||
{
|
{
|
||||||
return opt | transform([](auto&& item) {
|
return opt | transform([](auto&& item) {
|
||||||
return format("{}={}",
|
return format("{}={}",
|
||||||
escape(option_to_string(item.key), '=', '\\'),
|
escape(option_to_string(item.key, Quoting::Raw), '=', '\\'),
|
||||||
escape(option_to_string(item.value), '=', '\\'));
|
escape(option_to_string(item.value, Quoting::Raw), '=', '\\'));
|
||||||
}) | gather<Vector<String>>();
|
}) | gather<Vector<String>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,10 +130,10 @@ template<typename Key, typename Value, MemoryDomain domain>
|
||||||
String option_to_string(const HashMap<Key, Value, domain>& opt, Quoting quoting)
|
String option_to_string(const HashMap<Key, Value, domain>& opt, Quoting quoting)
|
||||||
{
|
{
|
||||||
return join(opt | transform([=](auto&& item) {
|
return join(opt | transform([=](auto&& item) {
|
||||||
return quote_ifn<Key, Value>(
|
return quoter(quoting)(
|
||||||
format("{}={}",
|
format("{}={}",
|
||||||
escape(option_to_string(item.key), '=', '\\'),
|
escape(option_to_string(item.key, Quoting::Raw), '=', '\\'),
|
||||||
escape(option_to_string(item.value), '=', '\\')), quoting);
|
escape(option_to_string(item.value, Quoting::Raw), '=', '\\')));
|
||||||
}), ' ', false);
|
}), ' ', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,15 +172,15 @@ String option_type_name(Meta::Type<HashMap<K, V, D>>)
|
||||||
constexpr char tuple_separator = '|';
|
constexpr char tuple_separator = '|';
|
||||||
|
|
||||||
template<typename... Types, size_t... I>
|
template<typename... Types, size_t... I>
|
||||||
String option_to_string_impl(const std::tuple<Types...>& opt, std::index_sequence<I...>)
|
String option_to_string_impl(Quoting quoting, const std::tuple<Types...>& opt, std::index_sequence<I...>)
|
||||||
{
|
{
|
||||||
return join(make_array({option_to_string(std::get<I>(opt))...}), tuple_separator);
|
return join(make_array({option_to_string(std::get<I>(opt), quoting)...}), tuple_separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Types>
|
template<typename... Types>
|
||||||
String option_to_string(const std::tuple<Types...>& opt)
|
String option_to_string(const std::tuple<Types...>& opt, Quoting quoting)
|
||||||
{
|
{
|
||||||
return option_to_string_impl(opt, std::make_index_sequence<sizeof...(Types)>());
|
return option_to_string_impl(quoting, opt, std::make_index_sequence<sizeof...(Types)>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Types, size_t... I>
|
template<typename... Types, size_t... I>
|
||||||
|
@ -335,7 +320,7 @@ EnableIfWithBitOps<Flags, bool> option_add(Flags& opt, StringView str)
|
||||||
template<typename P, typename T>
|
template<typename P, typename T>
|
||||||
inline Vector<String> option_to_strings(const PrefixedList<P, T>& opt)
|
inline Vector<String> option_to_strings(const PrefixedList<P, T>& opt)
|
||||||
{
|
{
|
||||||
Vector<String> res{option_to_string(opt.prefix)};
|
Vector<String> res{option_to_string(opt.prefix, Quoting::Raw)};
|
||||||
auto list = option_to_strings(opt.list);
|
auto list = option_to_strings(opt.list);
|
||||||
res.insert(res.end(), std::make_move_iterator(list.begin()), std::make_move_iterator(list.end()));
|
res.insert(res.end(), std::make_move_iterator(list.begin()), std::make_move_iterator(list.end()));
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -19,7 +19,7 @@ void GlobalScope::on_option_changed(const Option& option)
|
||||||
{
|
{
|
||||||
Context empty_context{Context::EmptyContextFlag{}};
|
Context empty_context{Context::EmptyContextFlag{}};
|
||||||
hooks().run_hook(Hook::GlobalSetOption,
|
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);
|
empty_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,10 +65,6 @@ Vector<StringView> wrap_lines(StringView text, ColumnCount max_width);
|
||||||
int str_to_int(StringView str); // throws on error
|
int str_to_int(StringView str); // throws on error
|
||||||
Optional<int> str_to_int_ifp(StringView str);
|
Optional<int> str_to_int_ifp(StringView str);
|
||||||
|
|
||||||
inline String option_to_string(StringView opt) { return opt.str(); }
|
|
||||||
inline String option_from_string(Meta::Type<String>, StringView str) { return str.str(); }
|
|
||||||
inline bool option_add(String& opt, StringView val) { opt += val; return not val.empty(); }
|
|
||||||
|
|
||||||
template<size_t N>
|
template<size_t N>
|
||||||
struct InplaceString
|
struct InplaceString
|
||||||
{
|
{
|
||||||
|
@ -142,15 +138,27 @@ inline String shell_quote(StringView s)
|
||||||
|
|
||||||
enum class Quoting
|
enum class Quoting
|
||||||
{
|
{
|
||||||
|
Raw,
|
||||||
Kakoune,
|
Kakoune,
|
||||||
Shell
|
Shell
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto quoter(Quoting quoting)
|
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<String> option_to_strings(StringView opt) { return {opt.str()}; }
|
||||||
|
inline String option_from_string(Meta::Type<String>, StringView str) { return str.str(); }
|
||||||
|
inline bool option_add(String& opt, StringView val) { opt += val; return not val.empty(); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -338,7 +338,7 @@ void Window::clear_display_buffer()
|
||||||
void Window::on_option_changed(const Option& option)
|
void Window::on_option_changed(const Option& option)
|
||||||
{
|
{
|
||||||
run_hook_in_own_context(Hook::WinSetOption, format("{}={}", option.name(),
|
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
|
// an highlighter might depend on the option, so we need to redraw
|
||||||
force_redraw();
|
force_redraw();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user