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"""TAB-completion sub-command and update helper funtion.
3Run this when ever options are changed::
5 python3 -m ase.cli.completion
6"""
8import sys
9from pathlib import Path
10from typing import List, Dict, Tuple
12# Path of the complete.py script:
13path = Path(__file__).with_name('complete.py')
16class CLICommand:
17 """Add tab-completion for Bash.
19 Will show the command that needs to be added to your '~/.bashrc file.
20 """
21 cmd = f'complete -o default -C "{sys.executable} {path}" ase'
23 @staticmethod
24 def add_arguments(parser):
25 pass
27 @staticmethod
28 def run(args):
29 cmd = CLICommand.cmd
30 print(cmd)
33def update(path: Path,
34 subcommands: List[Tuple[str, str]],
35 test: bool = False) -> None:
36 """Update commands dict in complete.py.
38 Use test=True to test that no changes are needed.
40 Refactor with care! This function is also used by GPAW.
41 """
43 import textwrap
44 from importlib import import_module
46 dct: Dict[str, List[str]] = {}
48 class Subparser:
49 def __init__(self, command):
50 self.command = command
51 dct[command] = []
53 def add_argument(self, *args, **kwargs):
54 dct[command].extend(arg for arg in args
55 if arg.startswith('-'))
57 def add_mutually_exclusive_group(self, required=False):
58 return self
60 for command, module_name in subcommands:
61 module = import_module(module_name)
62 module.CLICommand.add_arguments(Subparser(command)) # type: ignore
64 txt = 'commands = {'
65 for command, opts in sorted(dct.items()):
66 txt += "\n '" + command + "':\n ["
67 if opts:
68 txt += '\n'.join(textwrap.wrap("'" + "', '".join(opts) + "'],",
69 width=65,
70 break_on_hyphens=False,
71 subsequent_indent=' '))
72 else:
73 txt += '],'
74 txt = txt[:-1] + '}\n'
76 with path.open() as fd:
77 lines = fd.readlines()
79 a = lines.index('# Beginning of computer generated data:\n')
80 b = lines.index('# End of computer generated data\n')
82 if test:
83 if ''.join(lines[a + 1:b]) != txt:
84 raise ValueError(
85 'Please update ase/cli/complete.py using '
86 '"python3 -m ase.cli.completion".')
87 else:
88 lines[a + 1:b] = [txt]
89 new = path.with_name('complete.py.new')
90 with new.open('w') as fd:
91 print(''.join(lines), end='', file=fd)
92 new.rename(path)
93 path.chmod(0o775)
96if __name__ == '__main__':
97 from ase.cli.main import commands
98 update(path, commands)