diff --git a/src/command_manager.cc b/src/command_manager.cc index 6e61d55d..82fcea46 100644 --- a/src/command_manager.cc +++ b/src/command_manager.cc @@ -86,7 +86,6 @@ private: using TokenList = std::vector; -using TokenPosList = std::vector>; bool is_command_separator(char c) { @@ -356,7 +355,8 @@ CommandManager::find_command(const String& name) const } void CommandManager::execute_single_command(CommandParameters params, - Context& context) const + Context& context, + CharCoord pos) const { if (params.empty()) return; @@ -366,9 +366,37 @@ void CommandManager::execute_single_command(CommandParameters params, if (command_it == m_commands.end()) throw command_not_found(params[0]); - ParametersParser parameter_parser(param_view, - command_it->second.param_desc); - command_it->second.command(parameter_parser, context); + try + { + ParametersParser parameter_parser(param_view, + command_it->second.param_desc); + command_it->second.command(parameter_parser, context); + } + catch (runtime_error& error) + { + String info = to_string(pos.line+1) + ":" + to_string(pos.column+1) + + ": '" + command_it->first + "' " + error.what(); + throw runtime_error(std::move(info)); + } +} + +static CharCoord find_coord(StringView str, ByteCount offset) +{ + CharCoord res; + auto it = str.begin(); + auto line_start = it; + while (it != str.end() and offset > 0) + { + if (*it == '\n') + { + line_start = it + 1; + ++res.line; + } + ++it; + --offset; + } + res.column = utf8::distance(line_start, it); + return res; } void CommandManager::execute(StringView command_line, @@ -380,12 +408,16 @@ void CommandManager::execute(StringView command_line, if (tokens.empty()) return; + CharCoord command_coord; std::vector params; for (auto it = tokens.begin(); it != tokens.end(); ++it) { + if (params.empty()) + command_coord = find_coord(command_line, it->begin()); + if (it->type() == Token::Type::CommandSeparator) { - execute_single_command(params, context); + execute_single_command(params, context, command_coord); params.clear(); } // Shell expand are retokenized @@ -407,7 +439,7 @@ void CommandManager::execute(StringView command_line, params.push_back(eval_token(*it, context, shell_params, env_vars)); } - execute_single_command(params, context); + execute_single_command(params, context, command_coord); } CommandInfo CommandManager::command_info(StringView command_line) const diff --git a/src/command_manager.hh b/src/command_manager.hh index 59f7a55b..ea577d00 100644 --- a/src/command_manager.hh +++ b/src/command_manager.hh @@ -1,6 +1,7 @@ #ifndef command_manager_hh_INCLUDED #define command_manager_hh_INCLUDED +#include "coord.hh" #include "completion.hh" #include "memoryview.hh" #include "shell_manager.hh" @@ -87,7 +88,7 @@ public: private: void execute_single_command(CommandParameters params, - Context& context) const; + Context& context, CharCoord pos) const; struct CommandDescriptor { diff --git a/src/commands.cc b/src/commands.cc index 8b3e6de8..e3437dfa 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -743,8 +743,7 @@ const CommandDesc source_cmd = { } catch (Kakoune::runtime_error& err) { - write_debug("error while executing commands in file '" + parser[0] - + "'\n " + err.what()); + write_debug(parser[0] + ":" + err.what()); throw; } } diff --git a/src/main.cc b/src/main.cc index e8963e44..a48051ae 100644 --- a/src/main.cc +++ b/src/main.cc @@ -367,7 +367,7 @@ int kakoune(const ParametersParser& parser) } catch (Kakoune::runtime_error& error) { - write_debug("error while parsing kakrc: "_str + error.what()); + write_debug("error while parsing kakrc:\n "_str + error.what()); } catch (Kakoune::client_removed&) {