Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1"""allow bash-completion for argparse with argcomplete if installed 

2needs argcomplete>=0.5.6 for python 3.2/3.3 (older versions fail 

3to find the magic string, so _ARGCOMPLETE env. var is never set, and 

4this does not need special code. 

5 

6Function try_argcomplete(parser) should be called directly before 

7the call to ArgumentParser.parse_args(). 

8 

9The filescompleter is what you normally would use on the positional 

10arguments specification, in order to get "dirname/" after "dirn<TAB>" 

11instead of the default "dirname ": 

12 

13 optparser.add_argument(Config._file_or_dir, nargs='*' 

14 ).completer=filescompleter 

15 

16Other, application specific, completers should go in the file 

17doing the add_argument calls as they need to be specified as .completer 

18attributes as well. (If argcomplete is not installed, the function the 

19attribute points to will not be used). 

20 

21SPEEDUP 

22======= 

23The generic argcomplete script for bash-completion 

24(/etc/bash_completion.d/python-argcomplete.sh ) 

25uses a python program to determine startup script generated by pip. 

26You can speed up completion somewhat by changing this script to include 

27 # PYTHON_ARGCOMPLETE_OK 

28so the the python-argcomplete-check-easy-install-script does not 

29need to be called to find the entry point of the code and see if that is 

30marked with PYTHON_ARGCOMPLETE_OK 

31 

32INSTALL/DEBUGGING 

33================= 

34To include this support in another application that has setup.py generated 

35scripts: 

36- add the line: 

37 # PYTHON_ARGCOMPLETE_OK 

38 near the top of the main python entry point 

39- include in the file calling parse_args(): 

40 from _argcomplete import try_argcomplete, filescompleter 

41 , call try_argcomplete just before parse_args(), and optionally add 

42 filescompleter to the positional arguments' add_argument() 

43If things do not work right away: 

44- switch on argcomplete debugging with (also helpful when doing custom 

45 completers): 

46 export _ARC_DEBUG=1 

47- run: 

48 python-argcomplete-check-easy-install-script $(which appname) 

49 echo $? 

50 will echo 0 if the magic line has been found, 1 if not 

51- sometimes it helps to find early on errors using: 

52 _ARGCOMPLETE=1 _ARC_DEBUG=1 appname 

53 which should throw a KeyError: 'COMPLINE' (which is properly set by the 

54 global argcomplete script). 

55""" 

56import os 

57import sys 

58from glob import glob 

59from typing import Optional 

60 

61 

62class FastFilesCompleter: 

63 "Fast file completer class" 

64 

65 def __init__(self, directories=True): 

66 self.directories = directories 

67 

68 def __call__(self, prefix, **kwargs): 

69 """only called on non option completions""" 

70 if os.path.sep in prefix[1:]: 

71 prefix_dir = len(os.path.dirname(prefix) + os.path.sep) 

72 else: 

73 prefix_dir = 0 

74 completion = [] 

75 globbed = [] 

76 if "*" not in prefix and "?" not in prefix: 

77 # we are on unix, otherwise no bash 

78 if not prefix or prefix[-1] == os.path.sep: 

79 globbed.extend(glob(prefix + ".*")) 

80 prefix += "*" 

81 globbed.extend(glob(prefix)) 

82 for x in sorted(globbed): 

83 if os.path.isdir(x): 

84 x += "/" 

85 # append stripping the prefix (like bash, not like compgen) 

86 completion.append(x[prefix_dir:]) 

87 return completion 

88 

89 

90if os.environ.get("_ARGCOMPLETE"): 

91 try: 

92 import argcomplete.completers 

93 except ImportError: 

94 sys.exit(-1) 

95 filescompleter = FastFilesCompleter() # type: Optional[FastFilesCompleter] 

96 

97 def try_argcomplete(parser): 

98 argcomplete.autocomplete(parser, always_complete_options=False) 

99 

100 

101else: 

102 

103 def try_argcomplete(parser): 

104 pass 

105 

106 filescompleter = None