def Build(self, argv, arg, base_opts): """Given flags to complete/compgen, return a UserSpec.""" cmd_ev = self.cmd_ev actions = [] # NOTE: bash doesn't actually check the name until completion time, but # obviously it's better to check here. if arg.F: func_name = arg.F func = cmd_ev.procs.get(func_name) if func is None: raise error.Usage('Function %r not found' % func_name) actions.append( completion.ShellFuncAction(cmd_ev, func, self.comp_lookup)) # NOTE: We need completion for -A action itself!!! bash seems to have it. for name in arg.actions: if name == 'alias': a = _FixedWordsAction(self.parse_ctx.aliases) elif name == 'binding': # TODO: Where do we get this from? a = _FixedWordsAction(['vi-delete']) elif name == 'command': # compgen -A command in bash is SIX things: aliases, builtins, # functions, keywords, external commands relative to the current # directory, and external commands in $PATH. actions.append(_FixedWordsAction(consts.BUILTIN_NAMES)) actions.append(_FixedWordsAction(self.parse_ctx.aliases)) actions.append(_FixedWordsAction(cmd_ev.procs)) actions.append(_FixedWordsAction(lexer_def.OSH_KEYWORD_NAMES)) actions.append(completion.FileSystemAction(exec_only=True)) # Look on the file system. a = completion.ExternalCommandAction(cmd_ev.mem) elif name == 'directory': a = completion.FileSystemAction(dirs_only=True) elif name == 'file': a = completion.FileSystemAction() elif name == 'function': a = _FixedWordsAction(cmd_ev.procs) elif name == 'job': a = _FixedWordsAction(['jobs-not-implemented']) elif name == 'user': a = completion.UsersAction() elif name == 'variable': a = completion.VariablesAction(cmd_ev.mem) elif name == 'helptopic': # Note: it would be nice to have 'helpgroup' for help -i too a = _FixedWordsAction(help_.TOPICS) elif name == 'setopt': names = [ opt.name for opt in option_def.All() if opt.builtin == 'set' ] a = _FixedWordsAction(names) elif name == 'shopt': names = [ opt.name for opt in option_def.All() if opt.builtin == 'shopt' ] a = _FixedWordsAction(names) elif name == 'signal': a = _FixedWordsAction(['TODO:signals']) elif name == 'stopped': a = _FixedWordsAction(['jobs-not-implemented']) else: raise NotImplementedError(name) actions.append(a) # e.g. -W comes after -A directory if arg.W is not None: # could be '' # NOTES: # - Parsing is done at REGISTRATION time, but execution and splitting is # done at COMPLETION time (when the user hits tab). So parse errors # happen early. w_parser = self.parse_ctx.MakeWordParserForPlugin(arg.W) arena = self.parse_ctx.arena try: arg_word = w_parser.ReadForPlugin() except error.Parse as e: ui.PrettyPrintError(e, arena) raise # Let 'complete' or 'compgen' return 2 a = completion.DynamicWordsAction(self.word_ev, self.splitter, arg_word, arena) actions.append(a) extra_actions = [] if base_opts.get('plusdirs'): extra_actions.append(completion.FileSystemAction(dirs_only=True)) # These only happen if there were zero shown. else_actions = [] if base_opts.get('default'): else_actions.append(completion.FileSystemAction()) if base_opts.get('dirnames'): else_actions.append(completion.FileSystemAction(dirs_only=True)) if not actions and not else_actions: raise error.Usage('No actions defined in completion: %s' % argv) p = completion.DefaultPredicate if arg.X: filter_pat = arg.X if filter_pat.startswith('!'): p = completion.GlobPredicate(False, filter_pat[1:]) else: p = completion.GlobPredicate(True, filter_pat) return completion.UserSpec(actions, extra_actions, else_actions, p, prefix=arg.P or '', suffix=arg.S or '')
def Build(self, argv, arg, base_opts): """Given flags to complete/compgen, return a UserSpec.""" ex = self.ex actions = [] # NOTE: bash doesn't actually check the name until completion time, but # obviously it's better to check here. if arg.F: func_name = arg.F func = ex.funcs.get(func_name) if func is None: raise args.UsageError('Function %r not found' % func_name) actions.append( completion.ShellFuncAction(ex, func, self.comp_lookup)) # NOTE: We need completion for -A action itself!!! bash seems to have it. for name in arg.actions: if name == 'alias': a = _FixedWordsAction(ex.aliases) elif name == 'binding': # TODO: Where do we get this from? a = _FixedWordsAction(['vi-delete']) elif name == 'command': # compgen -A command in bash is SIX things: aliases, builtins, # functions, keywords, external commands relative to the current # directory, and external commands in $PATH. actions.append(_FixedWordsAction(builtin.BUILTIN_NAMES)) actions.append(_FixedWordsAction(ex.aliases)) actions.append(_FixedWordsAction(ex.funcs)) actions.append(_FixedWordsAction(lex.OSH_KEYWORD_NAMES)) actions.append(completion.FileSystemAction(exec_only=True)) # Look on the file system. a = completion.ExternalCommandAction(ex.mem) elif name == 'directory': a = completion.FileSystemAction(dirs_only=True) elif name == 'file': a = completion.FileSystemAction() elif name == 'function': a = _FixedWordsAction(ex.funcs) elif name == 'job': a = _FixedWordsAction(['jobs-not-implemented']) elif name == 'user': a = completion.UsersAction() elif name == 'variable': a = completion.VariablesAction(ex.mem) elif name == 'helptopic': a = _FixedWordsAction(osh_help.TOPIC_LOOKUP) elif name == 'setopt': a = _FixedWordsAction(state.SET_OPTION_NAMES) elif name == 'shopt': a = _FixedWordsAction(state.SHOPT_OPTION_NAMES) elif name == 'signal': a = _FixedWordsAction(['TODO:signals']) elif name == 'stopped': a = _FixedWordsAction(['jobs-not-implemented']) else: raise NotImplementedError(name) actions.append(a) # e.g. -W comes after -A directory if arg.W is not None: # could be '' # NOTES: # - Parsing is done at REGISTRATION time, but execution and splitting is # done at COMPLETION time (when the user hits tab). So parse errors # happen early. # - It's OK to reuse the same arena because this doesn't happen during # translation. TODO: But we need PushSource(). We should # create SideArena instances that track back to the current location of # the 'complete' builtin. arena = self.parse_ctx.arena w_parser = self.parse_ctx.MakeWordParserForPlugin(arg.W, arena) try: arg_word = w_parser.ReadForPlugin() except util.ParseError as e: ui.PrettyPrintError(e, self.parse_ctx.arena) raise # Let 'complete' or 'compgen' return 2 a = completion.DynamicWordsAction(self.word_ev, self.splitter, arg_word, arena) actions.append(a) extra_actions = [] if base_opts.get('plusdirs'): extra_actions.append(completion.FileSystemAction(dirs_only=True)) # These only happen if there were zero shown. else_actions = [] if base_opts.get('default'): else_actions.append(completion.FileSystemAction()) if base_opts.get('dirnames'): else_actions.append(completion.FileSystemAction(dirs_only=True)) if not actions and not else_actions: raise args.UsageError('No actions defined in completion: %s' % argv) p = completion.DefaultPredicate if arg.X: filter_pat = arg.X if filter_pat.startswith('!'): p = completion.GlobPredicate(False, filter_pat[1:]) else: p = completion.GlobPredicate(True, filter_pat) return completion.UserSpec(actions, extra_actions, else_actions, p, prefix=arg.P or '', suffix=arg.S or '')