diff --git a/tlmisc/optcomplete/optcomplete.py b/tlmisc/optcomplete/optcomplete.py index 9b2ff730c..11d495896 100644 --- a/tlmisc/optcomplete/optcomplete.py +++ b/tlmisc/optcomplete/optcomplete.py @@ -229,6 +229,19 @@ def get_comp_words(): cwords.append(os.environ[cw]) return cwords +def determine_option_completer(option, completer, optarg): + if option.nargs > 0: + optarg = True + if hasattr(option, 'completer'): + completer = option.completer + else: + completer = opt_completer + # Warn user at least, it could help him figure out the problem. + elif hasattr(option, 'completer'): + raise SystemExit("Error: optparse option with a completer " + "does not take arguments: %s" % str(option)) + return (completer, optarg) + #------------------------------------------------------------------------------- # def autocomplete( parser, @@ -340,17 +353,32 @@ def autocomplete( parser, # The following line change solves the issue when trying to # complete more options after one that doesn't take any args. if option and option.nargs != None: - if option.nargs > 0: - optarg = True - if hasattr(option, 'completer'): - completer = option.completer - else: - completer = opt_completer - # Warn user at least, it could help him figure out the problem. - elif hasattr(option, 'completer'): - raise SystemExit( - "Error: optparse option with a completer " - "does not take arguments: %s" % str(option)) + (completer, optarg) = determine_option_completer( + option, completer, optarg) + + # Prev starts with '-' but no corresponding option could be + # identified. This is likely due to squashed short opts as in -a -b + # -c -> -abc. Loop through individual short opts to see if more than + # one of them takes arguments, in which case we don't try to + # complete since it's not unambiguous which option completer to use. + elif not option and not prev.startswith('--'): + + n = 0 + for so in tuple(prev.replace('-','')): + short_option = parser.get_option("-%s" % so) + + if short_option: + if short_option.nargs == None or \ + short_option.nargs == 0: + continue + else: + (completer, optarg) = determine_option_completer( + short_option, completer, optarg) + n += 1 + + if n > 1: + sys.exit(exit_code) + except KeyError: pass