diff options
author | Andrew Burgess <aburgess@redhat.com> | 2024-02-22 14:56:43 +0000 |
---|---|---|
committer | Andrew Burgess <aburgess@redhat.com> | 2024-09-07 20:28:58 +0100 |
commit | 2bebc9ee2708086cec6c8dfd256c91184357ed2f (patch) | |
tree | fa1d747d870aa14e1c0ae81cdd8158a2972286e6 /gdb/completer.h | |
parent | bbbfe4af4fb5bc246a6cb15e95f29a3cd05e9145 (diff) | |
download | binutils-2bebc9ee2708086cec6c8dfd256c91184357ed2f.zip binutils-2bebc9ee2708086cec6c8dfd256c91184357ed2f.tar.gz binutils-2bebc9ee2708086cec6c8dfd256c91184357ed2f.tar.bz2 |
gdb: add match formatter mechanism for 'complete' command output
This commit solves a problem that existed prior to the previous
commit, but the previous commit made more common.
When completing a filename with the 'complete' command GDB will always
add a trailing quote character, even if the completion is a directory
name, in which case it would be better if the trailing quote was not
added. Consider:
(gdb) complete file '/tmp/xx
file '/tmp/xxx/'
The completion offered here is really only a partial completion, we've
completed up to the end of the next directory name, but, until we have
a filename then the completion is not finished and the trailing quote
should not be added.
This would match the readline behaviour, e.g.:
(gdb) file '/tmp/xx<TAB>
(gdb) file '/tmp/xxx/
In this case readline completes the directory name, but doesn't add
the trailing quote character.
Remember that the 'complete' command is intended for tools like
e.g. emacs in order that they can emulate GDB's standard readline
completion when implementing a CLI of their own. As such, not adding
the trailing quote in this case matches the readline behaviour, and
seems like the right way to go.
To achieve this, I've added a new function pointer member variable
completion_result::m_match_formatter. This contains a pointer to a
callback function which is used by the 'complete' command to format
each result.
The default behaviour of this callback function is to just append the
quote character (the character from before the completion string) to
the end of the completion result. This matches the current behaviour.
However, for filename completion we override the default value of
m_match_formatter, this new function checks if the completion result
is a directory or not. If the completion result is a directory then
the closing quote is not added, instead we add a trailing '/'
character.
The code to add a trailing '/' character already exists within the
filename_completer function. This is no longer needed in this
location, instead this code is moved into the formatter callback.
Tests are updated to handle the changes in functionality, this removes
an xfail added in the previous commit.
Diffstat (limited to 'gdb/completer.h')
-rw-r--r-- | gdb/completer.h | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/gdb/completer.h b/gdb/completer.h index e6dc941..c18bd16 100644 --- a/gdb/completer.h +++ b/gdb/completer.h @@ -247,12 +247,24 @@ struct completion_match_result struct completion_result { + /* The type of a function that is used to format completion results when + using the 'complete' command. MATCH is the completion word to be + printed, and QUOTE_CHAR is a trailing quote character to (possibly) + add at the end of MATCH. QUOTE_CHAR can be the null-character in + which case no trailing quote should be added. + + Return the possibly modified completion match word which should be + presented to the user. */ + using match_format_func_t = std::string (*) (const char *match, + char quote_char); + /* Create an empty result. */ completion_result (); /* Create a result. */ completion_result (char **match_list, size_t number_matches, - bool completion_suppress_append); + bool completion_suppress_append, + match_format_func_t match_format_func); /* Destroy a result. */ ~completion_result (); @@ -274,10 +286,15 @@ struct completion_result completions, otherwise, each line of output consists of PREFIX followed by one of the possible completion words. - The QUOTE_CHAR is appended after each possible completion word and - should be the quote character that appears before the completion word, - or the null-character if there is no quote before the completion - word. */ + The QUOTE_CHAR is usually appended after each possible completion + word and should be the quote character that appears before the + completion word, or the null-character if there is no quote before + the completion word. + + The QUOTE_CHAR is not always appended to the completion output. For + example, filename completions will not append QUOTE_CHAR if the + completion is a directory name. This is all handled by calling this + function. */ void print_matches (const std::string &prefix, const char *word, int quote_char); @@ -305,6 +322,12 @@ public: /* Whether readline should suppress appending a whitespace, when there's only one possible completion. */ bool completion_suppress_append; + +private: + /* A function which formats a single completion match ready for display + as part of the 'complete' command output. Different completion + functions can set different formatter functions. */ + match_format_func_t m_match_formatter; }; /* Object used by completers to build a completion match list to hand @@ -441,6 +464,14 @@ public: bool from_readline () const { return m_from_readline; } + /* Set the function used to format the completion word before displaying + it to the user to F, this is used by the 'complete' command. */ + void set_match_format_func (completion_result::match_format_func_t f) + { + gdb_assert (f != nullptr); + m_match_format_func = f; + } + private: /* The type that we place into the m_entries_hash hash table. */ @@ -535,6 +566,10 @@ private: interactively. The 'complete' command is a way to generate completions not to be displayed by readline. */ bool m_from_readline; + + /* The function used to format the completion word before it is printed + in the 'complete' command output. */ + completion_result::match_format_func_t m_match_format_func; }; /* Return a string to hand off to readline as a completion match |