summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2018-05-19 14:03:32 +1000
committerMaxime Coste <mawww@kakoune.org>2018-05-19 14:15:16 +1000
commitec0f8fe57483e72f45fba995f3e17870e4e30bec (patch)
treeb71bcac104c3565930e894d0530bb7c707f78b75 /src
parent243cfbc4aeb6bd0cccf185a68e926c225fd14af7 (diff)
Extend `try` command to support multiple catches.
If a catch command fails, and another catch is availabe following it, that following catch gets executed.
Diffstat (limited to 'src')
-rw-r--r--src/commands.cc36
1 files changed, 21 insertions, 15 deletions
diff --git a/src/commands.cc b/src/commands.cc
index e81528d6..7c41ba16 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -1958,31 +1958,37 @@ const CommandDesc info_cmd = {
const CommandDesc try_catch_cmd = {
"try",
nullptr,
- "try <cmds> [catch <error_cmds>]: execute <cmds> in current context.\n"
- "if an error is raised and <error_cmds> is specified, execute it; "
- "The error is not propagated further.",
- ParameterDesc{{}, ParameterDesc::Flags::None, 1, 3},
+ "try <cmds> [catch <error_cmds>]...: execute <cmds> in current context.\n"
+ "if an error is raised and <error_cmds> is specified, execute it and do\n"
+ "not propagate that error. If <error_cmds> raises an error and another\n"
+ "<error_cmds> is provided, execute this one and so-on\n",
+ ParameterDesc{{}, ParameterDesc::Flags::None, 1},
CommandFlags::None,
CommandHelper{},
CommandCompleter{},
[](const ParametersParser& parser, Context& context, const ShellContext& shell_context)
{
- if (parser.positional_count() == 2)
+ if ((parser.positional_count() % 2) != 1)
throw wrong_argument_count();
- const bool do_catch = parser.positional_count() == 3;
- if (do_catch and parser[1] != "catch")
- throw runtime_error("usage: try <commands> [catch <on error commands>]");
-
- CommandManager& command_manager = CommandManager::instance();
- try
+ for (size_t i = 1; i < parser.positional_count(); i += 2)
{
- command_manager.execute(parser[0], context, shell_context);
+ if (parser[i] != "catch")
+ throw runtime_error("usage: try <commands> [catch <on error commands>]...");
}
- catch (Kakoune::runtime_error& e)
+
+ CommandManager& command_manager = CommandManager::instance();
+ for (size_t i = 0; i < parser.positional_count(); i += 2)
{
- if (do_catch)
- command_manager.execute(parser[2], context, shell_context);
+ if (i == 0 or i < parser.positional_count() - 1)
+ {
+ try {
+ command_manager.execute(parser[i], context, shell_context);
+ return;
+ } catch (runtime_error&) {}
+ }
+ else
+ command_manager.execute(parser[i], context, shell_context);
}
}
};