public inbox for gdb-cvs@sourceware.org
help / color / mirror / Atom feed
* [binutils-gdb] Introduce complete_nested_command_line
@ 2019-06-12 23:29 Pedro Alves
  0 siblings, 0 replies; only message in thread
From: Pedro Alves @ 2019-06-12 23:29 UTC (permalink / raw)
  To: gdb-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=272d4594343349a713f7d8967d90ae2413ecbc30

commit 272d4594343349a713f7d8967d90ae2413ecbc30
Author: Pedro Alves <palves@redhat.com>
Date:   Thu Jun 13 00:06:53 2019 +0100

    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.

Diff:
---
 gdb/ChangeLog   |  6 ++++++
 gdb/completer.c | 36 ++++++++++++++++++++++++++++++++++++
 gdb/completer.h | 12 ++++++++++++
 3 files changed, 54 insertions(+)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index c21a5eb..08d038b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,11 @@
 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.
 	(backtrace_command): Use it.
 	(backtrace_command_completer): Complete on qualifiers.
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;
diff --git a/gdb/completer.h b/gdb/completer.h
index 58fe84f..9f8ec47 100644
--- a/gdb/completer.h
+++ b/gdb/completer.h
@@ -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 *);


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2019-06-12 23:29 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-12 23:29 [binutils-gdb] Introduce complete_nested_command_line Pedro Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).