3333import cmd
3434import collections
3535from colorama import Fore
36+ import copy
3637import glob
3738import os
3839import platform
@@ -494,13 +495,19 @@ def __init__(self, completekey='tab', stdin=None, stdout=None, persistent_histor
494495 # will be added if there is an unmatched opening quote
495496 self .allow_closing_quote = True
496497
497- # Use this list if you are completing strings that contain a common delimiter and you only want to
498- # display the final portion of the matches as the tab-completion suggestions. The full matches
499- # still must be returned from your completer function. For an example, look at path_complete()
500- # which uses this to show only the basename of paths as the suggestions. delimiter_complete() also
501- # populates this list.
498+ # An optional header that prints above the tab-completion suggestions
499+ self .completion_header = ''
500+
501+ # If the tab-completion suggestions should be displayed in a way that is different than the actual match values,
502+ # then place those results in this list. The full matches still must be returned from your completer function.
503+ # For an example, look at path_complete() which uses this to show only the basename of paths as the
504+ # suggestions. delimiter_complete() also populates this list.
502505 self .display_matches = []
503506
507+ # Used by functions like path_complete() and delimiter_complete() to properly
508+ # quote matches that are completed in a delimited fashion
509+ self .matches_delimited = False
510+
504511 # ----- Methods related to presenting output to the user -----
505512
506513 @property
@@ -657,7 +664,9 @@ def reset_completion_defaults(self):
657664 """
658665 self .allow_appended_space = True
659666 self .allow_closing_quote = True
667+ self .completion_header = ''
660668 self .display_matches = []
669+ self .matches_delimited = False
661670
662671 if rl_type == RlType .GNU :
663672 readline .set_completion_display_matches_hook (self ._display_matches_gnu_readline )
@@ -683,7 +692,6 @@ def tokens_for_completion(self, line, begidx, endidx):
683692 On Failure
684693 Both items are None
685694 """
686- import copy
687695 unclosed_quote = ''
688696 quotes_to_try = copy .copy (constants .QUOTES )
689697
@@ -836,6 +844,8 @@ def delimiter_complete(self, text, line, begidx, endidx, match_against, delimite
836844
837845 # Display only the portion of the match that's being completed based on delimiter
838846 if matches :
847+ # Set this to True for proper quoting of matches with spaces
848+ self .matches_delimited = True
839849
840850 # Get the common beginning for the matches
841851 common_prefix = os .path .commonprefix (matches )
@@ -1037,6 +1047,9 @@ def complete_users():
10371047 search_str = os .path .join (os .getcwd (), search_str )
10381048 cwd_added = True
10391049
1050+ # Set this to True for proper quoting of paths with spaces
1051+ self .matches_delimited = True
1052+
10401053 # Find all matching path completions
10411054 matches = glob .glob (search_str )
10421055
@@ -1245,6 +1258,10 @@ def _display_matches_gnu_readline(self, substitution, matches, longest_match_len
12451258 strings_array [1 :- 1 ] = encoded_matches
12461259 strings_array [- 1 ] = None
12471260
1261+ # Print the header if one exists
1262+ if self .completion_header :
1263+ sys .stdout .write ('\n ' + self .completion_header )
1264+
12481265 # Call readline's display function
12491266 # rl_display_match_list(strings_array, number of completion matches, longest match length)
12501267 readline_lib .rl_display_match_list (strings_array , len (encoded_matches ), longest_match_length )
@@ -1270,6 +1287,10 @@ def _display_matches_pyreadline(self, matches): # pragma: no cover
12701287 # Add padding for visual appeal
12711288 matches_to_display , _ = self ._pad_matches_to_display (matches_to_display )
12721289
1290+ # Print the header if one exists
1291+ if self .completion_header :
1292+ readline .rl .mode .console .write ('\n ' + self .completion_header )
1293+
12731294 # Display matches using actual display function. This also redraws the prompt and line.
12741295 orig_pyreadline_display (matches_to_display )
12751296
@@ -1414,17 +1435,10 @@ def complete(self, text, state):
14141435 display_matches_set = set (self .display_matches )
14151436 self .display_matches = list (display_matches_set )
14161437
1417- # Check if display_matches has been used. If so, then matches
1418- # on delimited strings like paths was done.
1419- if self .display_matches :
1420- matches_delimited = True
1421- else :
1422- matches_delimited = False
1423-
1438+ if not self .display_matches :
14241439 # Since self.display_matches is empty, set it to self.completion_matches
14251440 # before we alter them. That way the suggestions will reflect how we parsed
14261441 # the token being completed and not how readline did.
1427- import copy
14281442 self .display_matches = copy .copy (self .completion_matches )
14291443
14301444 # Check if we need to add an opening quote
@@ -1435,7 +1449,7 @@ def complete(self, text, state):
14351449 # This is the tab completion text that will appear on the command line.
14361450 common_prefix = os .path .commonprefix (self .completion_matches )
14371451
1438- if matches_delimited :
1452+ if self . matches_delimited :
14391453 # Check if any portion of the display matches appears in the tab completion
14401454 display_prefix = os .path .commonprefix (self .display_matches )
14411455
0 commit comments