From 6a2c1b8790e58ce0688507b5b1f8369aa621a665 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Mon, 17 Jul 2017 15:30:59 +0100 Subject: "complete" command and completion word break characters The linespec/locations/completer testcase added later in the series tests every completion with both TAB completion and the "complete" command. This exposed problems in the "complete" command, around determining the completion word point. First, the complete command has a too-simple approximation of what readline's TAB-completion code does to find the completion word point. Unfortunately, readline doesn't expose the functionality it uses internally, so to fix this this patch copies over the relevant code, and adjusts it a bit to better fit the use cases we need it for. (Specifically, our version avoids relying on the rl_word_break_characters, etc. globals, and instead takes those as arguments.) A following patch will want to use this function for TAB-completion too, but the "complete" command was a good excuse to split this to a separate patch. Then, notice how the complete_command does not call into the completer for the command being completed to determine the right set of word break characters. It always uses the default set. That is fixed by having the "complete" command call into complete_line_internal for a full handle_brkchars phase, just TAB-completion. gdb/ChangeLog: 2017-07-17 Pedro Alves * cli/cli-cmds.c (complete_command): Use a completion tracker along with completion_find_completion_word for handle_brkchars phase. * completer.c (RL_QF_SINGLE_QUOTE, RL_QF_DOUBLE_QUOTE) (RL_QF_BACKSLASH, RL_QF_OTHER_QUOTE): New. (struct gdb_rl_completion_word_info): New. (gdb_rl_find_completion_word): New. (completion_find_completion_word): New. * completer.h (completion_find_completion_word): Declare. --- gdb/cli/cli-cmds.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) (limited to 'gdb/cli') diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c index fa5dd4c..fb41e24 100644 --- a/gdb/cli/cli-cmds.c +++ b/gdb/cli/cli-cmds.c @@ -246,7 +246,6 @@ static void complete_command (char *arg_entry, int from_tty) { const char *arg = arg_entry; - int argpoint; dont_repeat (); @@ -264,36 +263,31 @@ complete_command (char *arg_entry, int from_tty) if (arg == NULL) arg = ""; - argpoint = strlen (arg); - - /* complete_line assumes that its first argument is somewhere - within, and except for filenames at the beginning of, the word to - be completed. The following crude imitation of readline's - word-breaking tries to accomodate this. */ - const char *point = arg + argpoint; - while (point > arg) - { - if (strchr (rl_completer_word_break_characters, point[-1]) != 0) - break; - point--; - } + completion_tracker tracker_handle_brkchars; completion_tracker tracker_handle_completions; + int quote_char = '\0'; + const char *word; + TRY { - complete_line (tracker_handle_completions, point, arg, strlen (arg)); + word = completion_find_completion_word (tracker_handle_brkchars, + arg, "e_char); + + /* Completers must be called twice. */ + complete_line (tracker_handle_completions, word, arg, strlen (arg)); } CATCH (ex, RETURN_MASK_ALL) { return; } - std::string arg_prefix (arg, point - arg); + std::string arg_prefix (arg, word - arg); completion_result result = (tracker_handle_completions.build_completion_result - (point, point - arg, strlen (arg))); + (word, word - arg, strlen (arg))); if (result.number_matches != 0) { @@ -308,16 +302,18 @@ complete_command (char *arg_entry, int from_tty) printf_unfiltered ("%s%s", arg_prefix.c_str (), result.match_list[i + 1]); + if (quote_char) + printf_unfiltered ("%c", quote_char); printf_unfiltered ("\n"); } } if (result.number_matches == max_completions) { - /* ARG_PREFIX and POINT are included in the output so that emacs + /* ARG_PREFIX and WORD are included in the output so that emacs will include the message in the output. */ printf_unfiltered (_("%s%s %s\n"), - arg_prefix.c_str (), point, + arg_prefix.c_str (), word, get_max_completions_reached_message ()); } } -- cgit v1.1