def ParseLine(line): """Parse a gcloud command line. Args: line: a string containing one or more gcloud invocations Returns: A list of GcloudInvocations, one for each command in the line (delimited by terminators). """ sh_tokens = lexer.GetShellTokens(line) if not sh_tokens: return [] parsed_line = [] current_invocation = [] # Separate parsed line into invocations based on terminators while sh_tokens: current_token = sh_tokens.pop(0) if TokenIsArgument(current_token): current_invocation.append(current_token) elif TokenIsTerminator(current_token): parsed_line.append(GcloudInvocation(ParseArgs(current_invocation))) current_invocation = [] else: # Ignore the rest of the current invocation if the token is not of type # ShellTokenType.ARG (that is, if it's of type IO, REDIRECTION, FILE or # TRAILING_BACKSLASH) while sh_tokens: if TokenIsTerminator(sh_tokens.pop(0)): break # Add the last current_invocation parsed_line.append(GcloudInvocation(ParseArgs(current_invocation))) return parsed_line
def ParseLine(line): """Parse a gcloud command line. Args: line: a string containing a gcloud command Returns: A list of ArgTokens. """ sh_tokens = lexer.GetShellTokens(line) if not sh_tokens: return [] # Cut off at first non-arg token i = 0 while i < len(sh_tokens): if not TokenIsArgument(sh_tokens[i]): break i += 1 sh_tokens = sh_tokens[:i] return ParseArgs(sh_tokens)
def get_completions(self, doc, complete_event): """Yields the completions for doc. Args: doc: A Document instance containing the shell command line to complete. complete_event: The CompleteEvent that triggered this completion. Yields: Completion instances for doc. """ tokens = lexer.GetShellTokens(doc.text_before_cursor) if not tokens: return if tokens[0].value != 'gcloud': gcloud_token = lexer.ShellToken('gcloud', lex=lexer.ShellTokenType.ARG, start=0, end=0) tokens = ([gcloud_token] + tokens) node = self.root info = None last = '' path = [] i = 0 # Autocomplete commands and groups after spaces. if doc.text_before_cursor and doc.text_before_cursor[-1].isspace(): for completion in CompleteCommandGroups(tokens): yield Completion(completion) return # If there is a terminator, do not complete. for token in tokens: if token.lex == lexer.ShellTokenType.TERMINATOR: return # Traverse the cli tree. while i < len(tokens): token = tokens[i] if token.lex == lexer.ShellTokenType.ARG and token.value.startswith( '-'): if i == len(tokens) - 1: last = token.value elif token.value in node: info = node[token.value] path.append(info) node = info.get('commands', {}) else: break i += 1 last = tokens[-1].value offset = -len(last) # Check for flags. if last.startswith('-') and info: # Collect all non-hidden flags of current command and parents into node. node = FilterHiddenFlags(info.get('flags', {})) for info in path: node.update(FilterHiddenFlags(info.get('flags', {}))) value = last.find('=') if value > 0: if doc.text_before_cursor[-1].isspace(): return name = last[:value] else: name = last if name in node: info = node[name] if info.get('type', None) != 'bool': choices = info.get('choices', None) if choices: # A flag with static choices. prefix = last if value < 0: prefix += '=' offset -= 1 for choice in choices: yield Completion(name + '=' + choice, offset) return def _MetaTextForChoice(choice): if (self.experimental_autocomplete_enabled and FlagIsRequired(node[choice])): return 'required' ranked_completions = [] if self.experimental_autocomplete_enabled: ranked_completions = RankedCompletions(node, doc) else: ranked_completions = sorted(node) for choice in ranked_completions: if choice.startswith(last): yield Completion(choice, offset, display_meta=_MetaTextForChoice(choice))
def get_completions(self, doc, complete_event): """Yields the completions for doc. Args: doc: A Document instance containing the shell command line to complete. complete_event: The CompleteEvent that triggered this completion. Yields: Completion instances for doc. """ tokens = lexer.GetShellTokens(doc.text_before_cursor) if not tokens: return # TODO(user): rewrite without virtual "gcloud" token gcloud_token = lexer.ShellToken('gcloud', lex=lexer.ShellTokenType.ARG, start=0, end=0) tokens = ([gcloud_token] + tokens) node = self.root info = None last = '' path = [] i = 0 # Autocomplete commands and groups after spaces. if doc.text_before_cursor and doc.text_before_cursor[-1].isspace(): for completion in CompleteCommandGroups(tokens): yield Completion(completion) return # Traverse the cli tree. while i < len(tokens): token = tokens[i] if token.lex == lexer.ShellTokenType.FLAG: if i == len(tokens) - 1: last = token.value elif token.value in node: info = node[token.value] path.append(info) node = info.get('commands', {}) else: while (i < len(tokens) and tokens[i].lex != lexer.ShellTokenType.TERMINATOR): i += 1 if i >= len(tokens): last = token.value break node = self.root info = None path = [] i += 1 # Bail if no completions. if i < len(tokens) or not last: return offset = -len(last) # Check for flags. if last.startswith('-') and info: node = info.get('flags', {}) for info in path: node.update(info.get('flags', {})) value = last.find('=') if value > 0: if doc.text_before_cursor[-1].isspace(): return name = last[:value] else: name = last if name in node: info = node[name] if info.get('type', None) != 'bool': choices = info.get('choices', None) if choices: # A flag with static choices. prefix = last if value < 0: prefix += '=' offset -= 1 for choice in choices: yield Completion(name + '=' + choice, offset) return # Check for subcommands. for choice in sorted(node): if choice.startswith(last): yield Completion(choice, offset)