aboutsummaryrefslogtreecommitdiff
path: root/gdb/completer.h
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2017-07-17 20:08:02 +0100
committerPedro Alves <palves@redhat.com>2017-07-17 20:29:37 +0100
commitc45ec17c07d8aa4554b0b2ca67a5f4dc2c87acc4 (patch)
treea57b4007fe95470fca71df4958c9285141033c52 /gdb/completer.h
parentbe966d4207ff8df6572a23b911e5a69a2ab9370f (diff)
downloadbinutils-c45ec17c07d8aa4554b0b2ca67a5f4dc2c87acc4.zip
binutils-c45ec17c07d8aa4554b0b2ca67a5f4dc2c87acc4.tar.gz
binutils-c45ec17c07d8aa4554b0b2ca67a5f4dc2c87acc4.tar.bz2
A smarter linespec completer
Continuing the theme of the explicit locations patch, this patch gets rid of the need for quoting function names in linespec TAB completion. To recap, when you have overloads in your program, and you want to set a breakpoint in one of them: void function(int); // set breakpoint here. void function(long); (gdb) b function(i[TAB] <all the symbols in the program that start with "i" are uselessly shown...> This patch gets rid of the need for quoting by switching the linespec completer to use the custom completion word point mechanism added in the previous explicit location patch (extending it as needed), to correctly determine the right completion word point. In the case above, we want the completer to figure out that it's completing a function name that starts with "function(i", and it now does. We also want the completer to know when it's potentially completing a source file name, for: (gdb) break source.[TAB] -> source.c: (gdb) break source.c: # Type line number or function name now And we want it to know to complete label names, which it doesn't today: (gdb) break function:lab[TAB] etc., etc. So what we want is for completion to grok the input string as closely to how the linespec parser groks it. With that in mind, the solution suggests itself - make the linespec completer use the same parsing code as normal linespec parsing. That's what the patch does. The old completer is replaced by one that reuses the actual linespec parser as much as possible. This (ideally) eliminate differences between what completion understands and actually setting breakpoints understands by design. The completer now offers sensible completion candidates depending on which component of the linespec is being completed, source filename, function, line number, expression, and (a new addition), labels. For example, when completing the function part, we now show the full name of the method as completion candidates, instead of showing whatever comes after what readline considered the word break character: (gdb) break klass::method[TAB] klass:method1(int) klass:method2() If input is past the function, then we now offer keyword condidates: (gdb) b function(int) [TAB] if task thread If input is past a keyword, we offer expression completion, which is different from linespec completion: (gdb) b main if 1 + glo[TAB] global (e.g., completes on types, struct data fields, etc.) As mentioned, this teaches the linespec completer about completing label symbols too: (gdb) b source.c:function:lab[TAB] A nice convenience is that when completion uniquely matches a source name, gdb adds the ":" automatically for you: (gdb) b filenam[TAB] (gdb) b filename.c: # ':' auto-added, cursor right after it. It's the little details. :-) I worked on this patch in parallel with writing the (big) testcase added closer to the end of the series, which exercises many many tricky cases around quoting and whitespace insertion placement. In general, I think it now all Just Works. gdb/ChangeLog: 2017-07-17 Pedro Alves <palves@redhat.com> * completer.c (complete_source_filenames): New function. (complete_address_and_linespec_locations): New function. (location_completer): Use complete_address_and_linespec_locations. (completion_tracker::build_completion_result): Honor the tracker's request to suppress append. * completer.h (completion_tracker::suppress_append_ws) (completion_tracker::set_suppress_append_ws): New methods. (completion_tracker::m_suppress_append_ws): New field. (complete_source_filenames): New declaration. * linespec.c (linespec_complete_what): New. (struct ls_parser) <complete_what, completion_word, completion_quote_char, completion_quote_end, completion_tracker>: New fields. (string_find_incomplete_keyword_at_end): New. (linespec_lexer_lex_string): Record quote char. If in completion mode, don't throw. (linespec_lexer_consume_token): Advance the completion word point. (linespec_lexer_peek_token): Save/restore completion info. (save_stream_and_consume_token): New. (set_completion_after_number): New. (linespec_parse_basic): Set what to complete next depending on token. Handle function and label completions specially. (parse_linespec): Disable objc shortcut in completion mode. Set what to complete next depending on token type. Skip keyword if in completion mode. (complete_linespec_component, linespec_complete): New. * linespec.h (linespec_complete): Declare. gdb/testsuite/ChangeLog: 2017-07-17 Pedro Alves <palves@redhat.com> * gdb.base/completion.exp: Adjust expected output. * gdb.linespec/ls-errs.exp: Don't send tab characters, now that the completer works.
Diffstat (limited to 'gdb/completer.h')
-rw-r--r--gdb/completer.h28
1 files changed, 28 insertions, 0 deletions
diff --git a/gdb/completer.h b/gdb/completer.h
index 40d2f58..f68c6dc 100644
--- a/gdb/completer.h
+++ b/gdb/completer.h
@@ -192,6 +192,16 @@ public:
/* Advance the custom word point by LEN. */
void advance_custom_word_point_by (size_t len);
+ /* Whether to tell readline to skip appending a whitespace after the
+ completion. See m_suppress_append_ws. */
+ bool suppress_append_ws () const
+ { return m_suppress_append_ws; }
+
+ /* Set whether to tell readline to skip appending a whitespace after
+ the completion. See m_suppress_append_ws. */
+ void set_suppress_append_ws (bool suppress)
+ { m_suppress_append_ws = suppress; }
+
/* Return true if we only have one completion, and it matches
exactly the completion word. I.e., completing results in what we
already have. */
@@ -255,6 +265,14 @@ private:
completable words. */
int m_custom_word_point = 0;
+ /* If true, tell readline to skip appending a whitespace after the
+ completion. Automatically set if we have a unique completion
+ that already has a space at the end. A completer may also
+ explicitly set this. E.g., the linespec completer sets this when
+ the completion ends with the ":" separator between filename and
+ function name. */
+ bool m_suppress_append_ws = false;
+
/* Our idea of lowest common denominator to hand over to readline.
See intro. */
char *m_lowest_common_denominator = NULL;
@@ -353,6 +371,16 @@ extern completer_handle_brkchars_ftype *
/* Exported to linespec.c */
+/* Return a list of all source files whose names begin with matching
+ TEXT. */
+extern completion_list complete_source_filenames (const char *text);
+
+/* Complete on expressions. Often this means completing on symbol
+ names, but some language parsers also have support for completing
+ field names. */
+extern void complete_expression (completion_tracker &tracker,
+ const char *text, const char *word);
+
extern const char *skip_quoted_chars (const char *, const char *,
const char *);