summaryrefslogtreecommitdiff
path: root/src/command_manager.cc
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2018-05-30 23:23:38 +1000
committerMaxime Coste <mawww@kakoune.org>2018-07-05 07:54:28 +1000
commitb548dd3a6f369e5a244fdcdca55061513026f82a (patch)
tree1ca672c1d6f976a74f34d37f75fd68a83933fbe1 /src/command_manager.cc
parent5eeec8bd4d24882ea443c4441f696257b8cb68c4 (diff)
Change option lists to be specified as separate arguments on commands line
Option lists and maps are specified using separate arguments, avoiding the need for additional escaping of their separator and reusing the existing command line spliting logic instead. As discussed on #2087, this should make it much easier to work with list options, and make the general option system feel cleaner.
Diffstat (limited to 'src/command_manager.cc')
-rw-r--r--src/command_manager.cc56
1 files changed, 41 insertions, 15 deletions
diff --git a/src/command_manager.cc b/src/command_manager.cc
index dd904bf4..c3dfc7c4 100644
--- a/src/command_manager.cc
+++ b/src/command_manager.cc
@@ -253,9 +253,31 @@ Token parse_percent_token(Reader& reader, bool throw_on_unterminated)
}
}
-String expand_token(const Token& token, const Context& context,
- const ShellContext& shell_context)
+auto expand_option(Option& opt, std::true_type)
{
+ return opt.get_as_string();
+}
+
+auto expand_option(Option& opt, std::false_type)
+{
+ return opt.get_as_strings();
+}
+
+String expand_arobase(ConstArrayView<String> params, std::true_type)
+{
+ return join(params, ' ', false);
+}
+
+Vector<String> expand_arobase(ConstArrayView<String> params, std::false_type)
+{
+ return {params.begin(), params.end()};
+}
+
+template<bool single>
+std::conditional_t<single, String, Vector<String>>
+expand_token(const Token& token, const Context& context, const ShellContext& shell_context)
+{
+ using IsSingle = std::integral_constant<bool, single>;
auto& content = token.content;
switch (token.type)
{
@@ -273,35 +295,35 @@ String expand_token(const Token& token, const Context& context,
++trailing_eol_count;
}
str.resize(str.length() - trailing_eol_count, 0);
- return str;
+ return {str};
}
case Token::Type::RegisterExpand:
- return context.main_sel_register_value(content).str();
+ return {context.main_sel_register_value(content).str()};
case Token::Type::OptionExpand:
- return context.options()[content].get_as_string();
+ return expand_option(context.options()[content], IsSingle{});
case Token::Type::ValExpand:
{
auto it = shell_context.env_vars.find(content);
if (it != shell_context.env_vars.end())
- return it->value;
- return ShellManager::instance().get_val(content, context);
+ return {it->value};
+ return {ShellManager::instance().get_val(content, context)};
}
case Token::Type::ArgExpand:
{
auto& params = shell_context.params;
if (content == '@')
- return join(params, ' ');
+ return expand_arobase(params, IsSingle{});
const int arg = str_to_int(content)-1;
if (arg < 0)
throw runtime_error("invalid argument index");
- return arg < params.size() ? params[arg] : String{};
+ return {arg < params.size() ? params[arg] : String{}};
}
case Token::Type::RawEval:
- return expand(content, context, shell_context);
+ return {expand(content, context, shell_context)};
case Token::Type::Raw:
case Token::Type::RawQuoted:
- return content;
+ return {content};
default: kak_assert(false);
}
return {};
@@ -378,8 +400,7 @@ String expand_impl(StringView str, const Context& context,
else
{
res += reader.substr_from(beg);
- res += postprocess(expand_token(parse_percent_token(reader, true),
- context, shell_context));
+ res += postprocess(expand_token<true>(parse_percent_token(reader, true), context, shell_context));
beg = reader.pos;
}
}
@@ -483,7 +504,12 @@ void CommandManager::execute(StringView command_line,
params.insert(params.end(), shell_context.params.begin(),
shell_context.params.end());
else
- params.push_back(expand_token(token, context, shell_context));
+ {
+ auto tokens = expand_token<false>(token, context, shell_context);
+ params.insert(params.end(),
+ std::make_move_iterator(tokens.begin()),
+ std::make_move_iterator(tokens.end()));
+ }
}
execute_single_command(params, context, shell_context, command_coord);
}
@@ -640,7 +666,7 @@ Completions CommandManager::complete(const Context& context,
context, flags, params, tokens.size() - 2,
cursor_pos_in_token), start);
- if (token.type != Token::Type::RawQuoted)
+ if (not completions.quoted and token.type != Token::Type::RawQuoted)
{
StringView to_escape = token.type == Token::Type::Raw ? "% \t;" : "%";
for (auto& candidate : completions.candidates)