From f91c725ff0e27c6daec514dfe0aa0c7785e96688 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Fri, 4 Oct 2019 20:28:47 +0200 Subject: [PATCH] Fix caret position of invalid expansion in command position Fixes #5812 --- src/parse_execution.cpp | 6 ++++++ tests/checks/expansion.fish | 13 +++++++++++++ tests/expansion.err | 2 +- tests/expansion.in | 1 - 4 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 tests/checks/expansion.fish diff --git a/src/parse_execution.cpp b/src/parse_execution.cpp index 847396187..d0df9a682 100644 --- a/src/parse_execution.cpp +++ b/src/parse_execution.cpp @@ -753,12 +753,18 @@ parse_execution_result_t parse_execution_context_t::expand_command( // Get the unexpanded command string. We expect to always get it here. wcstring unexp_cmd = *command_for_plain_statement(statement, pstree->src); + size_t pos_of_command_token = statement.child<0>().source_range()->start; // Expand the string to produce completions, and report errors. expand_result_t expand_err = expand_to_command_and_args(unexp_cmd, parser->vars(), out_cmd, out_args, &errors); if (expand_err == expand_result_t::error) { parser->set_last_statuses(statuses_t::just(STATUS_ILLEGAL_CMD)); + // Issue #5812 - the expansions were done on the command token, + // excluding prefixes such as " " or "if ". + // This means that the error positions are relative to the beginning + // of the token; we need to make them relative to the original source. + for (auto &error : errors) error.source_start += pos_of_command_token; return report_errors(errors); } else if (expand_err == expand_result_t::wildcard_no_match) { return report_unmatched_wildcard_error(statement); diff --git a/tests/checks/expansion.fish b/tests/checks/expansion.fish new file mode 100644 index 000000000..d7b7c7805 --- /dev/null +++ b/tests/checks/expansion.fish @@ -0,0 +1,13 @@ +# RUN: %fish -C 'set -g fish %fish' %s + +# caret position (#5812) +printf '<%s>\n' ($fish -c ' $f[a]' 2>&1) + +# CHECK: +# CHECK: < $f[a]> +# CHECK: < ^> + +printf '<%s>\n' ($fish -c 'if $f[a]; end' 2>&1) +# CHECK: +# CHECK: +# CHECK: < ^> diff --git a/tests/expansion.err b/tests/expansion.err index 678e91d37..de28e0563 100644 --- a/tests/expansion.err +++ b/tests/expansion.err @@ -41,4 +41,4 @@ echo {}} fish: Command substitutions not allowed command (asd) -^ + ^ diff --git a/tests/expansion.in b/tests/expansion.in index e36c8ff0f..da7d8da92 100644 --- a/tests/expansion.in +++ b/tests/expansion.in @@ -153,6 +153,5 @@ logmsg Test fatal syntax errors ../test/root/bin/fish -c 'echo $,foo' ../test/root/bin/fish -c 'echo {' ../test/root/bin/fish -c 'echo {}}' -# The output for this is wrong in non-interactive mode and will need fixing when #5812 is fixed ../test/root/bin/fish -c 'command (asd)' true