Introduce complete_nested_command_line

This adds a completion helper routine that makes it possible for a
command that takes another command as argument, such as "frame apply
all COMMAND" as "thread apply all COMMAND", to complete on COMMAND,
and have the completion machinery recurse and complete COMMAND as if
you tried to complete "(gdb) COMMAND".  I.e., we'll be able to
complete like this, for example:

 (gdb) thread apply all -[TAB]
 -c           -ascending   -q           -s
 (gdb) thread apply all -ascending frame apply all -[TAB]
 -c           -limit       -past-entry  -past-main   -q           -s
 (gdb) thread apply all -ascending frame apply all -past-main print -[TAB]
 -address         -elements        -pretty          -symbol
 -array           -null-stop       -repeats         -union
 -array-indexes   -object          -static-members  -vtbl
 (gdb) thread apply all -ascending frame apply all -past-main print glo[TAB]
 global1         global2

Above, the completer function understands that "thread apply all" is a
command, and then parses "-ascending" successfully and understand that
the rest of the string is "thread apply all"'s operand.  And then, the
process repeats for the "frame apply" command, and on and on.

gdb/ChangeLog:
2019-06-13  Pedro Alves  <palves@redhat.com>

	* completer.c (complete_nested_command_line): New.
	(gdb_completion_word_break_characters_throw): Add assertion.
	* completer.h (complete_nested_command_line): Declare.
This commit is contained in:
Pedro Alves 2019-06-13 00:06:53 +01:00
parent e2a689da55
commit 272d459434
3 changed files with 54 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2019-06-13 Pedro Alves <palves@redhat.com>
* completer.c (complete_nested_command_line): New.
(gdb_completion_word_break_characters_throw): Add assertion.
* completer.h (complete_nested_command_line): Declare.
2019-06-13 Pedro Alves <palves@redhat.com>
* stack.c (parse_backtrace_qualifiers): New.

View File

@ -423,6 +423,39 @@ completion_tracker::completes_to_completion_word (const char *word)
return false;
}
/* See completer.h. */
void
complete_nested_command_line (completion_tracker &tracker, const char *text)
{
/* Must be called from a custom-word-point completer. */
gdb_assert (tracker.use_custom_word_point ());
/* Disable the custom word point temporarily, because we want to
probe whether the command we're completing itself uses a custom
word point. */
tracker.set_use_custom_word_point (false);
size_t save_custom_word_point = tracker.custom_word_point ();
int quote_char = '\0';
const char *word = completion_find_completion_word (tracker, text,
&quote_char);
if (tracker.use_custom_word_point ())
{
/* The command we're completing uses a custom word point, so the
tracker already contains the matches. We're done. */
return;
}
/* Restore the custom word point settings. */
tracker.set_custom_word_point (save_custom_word_point);
tracker.set_use_custom_word_point (true);
/* Run the handle_completions completer phase. */
complete_line (tracker, word, text, strlen (text));
}
/* Complete on linespecs, which might be of two possible forms:
file:line
@ -1894,6 +1927,9 @@ gdb_completion_word_break_characters_throw ()
{
gdb_assert (tracker.custom_word_point () > 0);
rl_point = tracker.custom_word_point () - 1;
gdb_assert (rl_point >= 0 && rl_point < strlen (rl_line_buffer));
gdb_custom_word_point_brkchars[0] = rl_line_buffer[rl_point];
rl_completer_word_break_characters = gdb_custom_word_point_brkchars;
rl_completer_quote_characters = NULL;

View File

@ -611,6 +611,18 @@ extern completion_list complete_source_filenames (const char *text);
extern void complete_expression (completion_tracker &tracker,
const char *text, const char *word);
/* Called by custom word point completers that want to recurse into
the completion machinery to complete a command. Used to complete
COMMAND in "thread apply all COMMAND", for example. Note that
unlike command_completer, this fully recurses into the proper
completer for COMMAND, so that e.g.,
(gdb) thread apply all print -[TAB]
does the right thing and show the print options. */
extern void complete_nested_command_line (completion_tracker &tracker,
const char *text);
extern const char *skip_quoted_chars (const char *, const char *,
const char *);