aboutsummaryrefslogtreecommitdiff
path: root/gdb/completer.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2019-06-13 00:06:53 +0100
committerPedro Alves <palves@redhat.com>2019-06-13 00:21:29 +0100
commit272d4594343349a713f7d8967d90ae2413ecbc30 (patch)
tree25442ababced86788bc1bdd53f87be7d16daedde /gdb/completer.c
parente2a689da55d3feb7b79a141f69c4049112f59c91 (diff)
downloadgdb-272d4594343349a713f7d8967d90ae2413ecbc30.zip
gdb-272d4594343349a713f7d8967d90ae2413ecbc30.tar.gz
gdb-272d4594343349a713f7d8967d90ae2413ecbc30.tar.bz2
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.
Diffstat (limited to 'gdb/completer.c')
-rw-r--r--gdb/completer.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/gdb/completer.c b/gdb/completer.c
index 0f4e7f9..6892a62 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -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;