aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2014-11-20 11:12:19 -0800
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2014-11-20 11:12:19 -0800
commit04dc0aca5064b7424979c000a41676758aa8b1b6 (patch)
tree532b7a44a4ef8d81b492798600fe8bd28a824364
parent918d5595bdfc69bb2c6b90d77c8af882b9cb230c (diff)
Fix issue where tab completions could ignore command-specific completions
Fixes #1742
-rw-r--r--complete.cpp35
1 files changed, 26 insertions, 9 deletions
diff --git a/complete.cpp b/complete.cpp
index 173fc83f..76e8e4e8 100644
--- a/complete.cpp
+++ b/complete.cpp
@@ -1360,9 +1360,14 @@ static int complete_load_no_reload(wcstring *name)
}
/**
- Find completion for the argument str of command cmd_orig with
- previous option popt. Insert results into comp_out. Return 0 if file
- completion should be disabled, 1 otherwise.
+ complete_param: Given a command, find completions for the argument str of command cmd_orig with previous option popt.
+
+ Examples in format (cmd, popt, str):
+
+ echo hello world <tab> -> ("echo", "world", "")
+ echo hello world<tab> -> ("echo", "hello", "world")
+
+ Insert results into comp_out. Return true to perform file completion, false to disable it.
*/
struct local_options_t
{
@@ -1967,7 +1972,7 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> &comps
for (size_t i=0; i < all_arguments.size(); i++)
{
const parse_node_t *node = all_arguments.at(i);
- if (node->location_in_or_at_end_of_source_range(pos))
+ if (node->location_in_or_at_end_of_source_range(adjusted_pos))
{
matching_arg_index = i;
break;
@@ -1978,11 +1983,23 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> &comps
wcstring current_argument, previous_argument;
if (matching_arg_index != (size_t)(-1))
{
- /* Get the current argument and the previous argument, if we have one */
- current_argument = all_arguments.at(matching_arg_index)->get_source(cmd);
-
- if (matching_arg_index > 0)
- previous_argument = all_arguments.at(matching_arg_index - 1)->get_source(cmd);
+ const wcstring matching_arg = all_arguments.at(matching_arg_index)->get_source(cmd);
+
+ /* If the cursor is in whitespace, then the "current" argument is empty and the previous argument is the matching one. But if the cursor was in or at the end of the argument, then the current argument is the matching one, and the previous argument is the one before it. */
+ bool cursor_in_whitespace = (adjusted_pos < pos);
+ if (cursor_in_whitespace)
+ {
+ current_argument = L"";
+ previous_argument = matching_arg;
+ }
+ else
+ {
+ current_argument = matching_arg;
+ if (matching_arg_index > 0)
+ {
+ previous_argument = all_arguments.at(matching_arg_index - 1)->get_source(cmd);
+ }
+ }
/* Check to see if we have a preceding double-dash */
for (size_t i=0; i < matching_arg_index; i++)