From 16b982958bdd648098fd433c5aec47158b7bc383 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Fri, 2 May 2014 01:22:39 -0700 Subject: [PATCH] Correctly complete redirections. Fixes #1296 --- complete.cpp | 52 ++++++++++++++++++++++++++++++++------------------ parse_tree.cpp | 2 +- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/complete.cpp b/complete.cpp index 73d3182e9..101faeec8 100644 --- a/complete.cpp +++ b/complete.cpp @@ -1976,28 +1976,42 @@ void complete(const wcstring &cmd_with_subcmds, std::vector &comps } } } - - bool do_file = false; - - wcstring current_command_unescape, previous_argument_unescape, current_argument_unescape; - if (unescape_string(current_command, ¤t_command_unescape, UNESCAPE_DEFAULT) && - unescape_string(previous_argument, &previous_argument_unescape, UNESCAPE_DEFAULT) && - unescape_string(current_argument, ¤t_argument_unescape, UNESCAPE_INCOMPLETE)) + + /* If we are not in an argument, we may be in a redirection */ + bool in_redirection = false; + if (matching_arg_index == (size_t)(-1)) { - do_file = completer.complete_param(current_command_unescape, - previous_argument_unescape, - current_argument_unescape, - !had_ddash); + const parse_node_t *redirection = tree.find_node_matching_source_location(symbol_redirection, pos, plain_statement); + in_redirection = (redirection != NULL); } - - /* If we have found no command specific completions at all, fall back to using file completions. */ - if (completer.empty()) - do_file = true; - - /* And if we're autosuggesting, and the token is empty, don't do file suggestions */ - if ((flags & COMPLETION_REQUEST_AUTOSUGGESTION) && current_argument_unescape.empty()) + + bool do_file = false; + if (in_redirection) { - do_file = false; + do_file = true; + } + else + { + wcstring current_command_unescape, previous_argument_unescape, current_argument_unescape; + if (unescape_string(current_command, ¤t_command_unescape, UNESCAPE_DEFAULT) && + unescape_string(previous_argument, &previous_argument_unescape, UNESCAPE_DEFAULT) && + unescape_string(current_argument, ¤t_argument_unescape, UNESCAPE_INCOMPLETE)) + { + do_file = completer.complete_param(current_command_unescape, + previous_argument_unescape, + current_argument_unescape, + !had_ddash); + } + + /* If we have found no command specific completions at all, fall back to using file completions. */ + if (completer.empty()) + do_file = true; + + /* And if we're autosuggesting, and the token is empty, don't do file suggestions */ + if ((flags & COMPLETION_REQUEST_AUTOSUGGESTION) && current_argument_unescape.empty()) + { + do_file = false; + } } /* This function wants the unescaped string */ diff --git a/parse_tree.cpp b/parse_tree.cpp index fe1e2527e..4825c6ebc 100644 --- a/parse_tree.cpp +++ b/parse_tree.cpp @@ -1351,7 +1351,7 @@ const parse_node_t *parse_node_tree_t::find_node_matching_source_location(parse_ continue; /* If a parent is given, it must be an ancestor */ - if (parent != NULL && node_has_ancestor(*this, node, *parent)) + if (parent != NULL && ! node_has_ancestor(*this, node, *parent)) continue; /* Found it */