diff options
author | Pedro Alves <palves@redhat.com> | 2017-07-17 20:08:02 +0100 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2017-07-17 20:29:37 +0100 |
commit | c45ec17c07d8aa4554b0b2ca67a5f4dc2c87acc4 (patch) | |
tree | a57b4007fe95470fca71df4958c9285141033c52 /gdb/completer.h | |
parent | be966d4207ff8df6572a23b911e5a69a2ab9370f (diff) | |
download | binutils-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.h | 28 |
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 *); |