Example #1
0
def OpenReferencePage(line, pos):
  tokens = gcloud_parser.ParseLine(line)
  tokens = [x for x in tokens if x.start < pos]
  url = _GetReferenceURL(tokens)
  browser = webbrowser.get()
  webbrowser.subprocess = FakeSubprocessModule()
  browser.open_new_tab(url)
Example #2
0
def _GetReferenceURL(line, pos=None):
    """Determine the reference url of the command/group preceeding the pos.

  Args:
    line: a string with the current string directly from the shell.
    pos: the position of the cursor on the line.

  Returns:
    A string containing the URL of the reference page.
  """
    if pos is None:
        pos = len(line)

    prefix = u'https://cloud.google.com/sdk/gcloud/reference/'

    invocations = gcloud_parser.ParseLine(line)
    if not invocations:
        return prefix

    tokens = invocations[-1].tokens
    tokens = [x for x in tokens if x.start < pos]
    invocation = gcloud_parser.GcloudInvocation(tokens)

    cmd = invocation.GetCommandOrGroup()
    if not cmd:
        return prefix
    return prefix + '/'.join(cmd.tree['path'][1:])
Example #3
0
def GenerateHelpContent(cli, width):
    """Generates and renders the corresponding help content in the gcloud shell.

  Args:
    cli: the CLI in which to render the help contents.
    width: the width of the help prompt.

  Returns:
    A list with one list per line, each containing (token, string) tuples for
    words in the help text. These tuples represent (Markdown format,
    actual text) pairs.
  """
    if width > 80:
        width = 80
    doc = cli.current_buffer.document
    tok = GetCurrentToken(gcloud_parser.ParseLine(doc.text),
                          doc.cursor_position)
    if not tok:
        return []

    if tok.token_type == gcloud_parser.ArgTokenType.COMMAND:
        return GenerateHelpForCommand(tok, width)
    elif tok.token_type == gcloud_parser.ArgTokenType.GROUP:
        return GenerateHelpForCommand(tok, width)
    elif tok.token_type == gcloud_parser.ArgTokenType.FLAG:
        return GenerateHelpForFlag(tok, width)
    elif tok.token_type == gcloud_parser.ArgTokenType.FLAG_ARG:
        return GenerateHelpForFlag(tok, width)
    elif tok.token_type == gcloud_parser.ArgTokenType.POSITIONAL:
        return GenerateHelpForPositional(tok, width)

    return []
Example #4
0
def GetHelpTokens(cli):
    doc = cli.current_buffer.document
    tok = GetCurrentToken(gcloud_parser.ParseLine(doc.text),
                          doc.cursor_position)
    if tok is None:
        return []

    return [(Token.HelpToolbar.SectionName, 'Description: '),
            (Token.HelpToolbar.SectionValue, tok.tree['description'])]
Example #5
0
def GenerateHelpContent(cli, width):
    if width > 80:
        width = 80
    doc = cli.current_buffer.document
    tok = GetCurrentToken(gcloud_parser.ParseLine(doc.text),
                          doc.cursor_position)
    if not tok:
        return []

    if tok.token_type == gcloud_parser.ArgTokenType.COMMAND:
        return GenerateHelpForCommand(tok, width)
    elif tok.token_type == gcloud_parser.ArgTokenType.GROUP:
        return GenerateHelpForCommand(tok, width)
    elif tok.token_type == gcloud_parser.ArgTokenType.FLAG:
        return GenerateHelpForFlag(tok, width)
    elif tok.token_type == gcloud_parser.ArgTokenType.POSITIONAL:
        return GenerateHelpForPositional(tok, width)

    return []
Example #6
0
  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.
    """
    commands = parser.ParseLine(doc.text_before_cursor)
    if not commands:
      return

    tokens = commands[-1]
    if not tokens:
      return
    if tokens[0].value != 'gcloud':
      gcloud_token = parser.ArgToken('gcloud', parser.ArgTokenType.GROUP,
                                     gcloud_tree, 0, 0)
      tokens = ([gcloud_token] + tokens)
    node = self.root
    info = None
    last_token = tokens[-1]
    path = []

    # Autocomplete commands and groups after spaces.
    if (last_token.token_type == parser.ArgTokenType.GROUP and
        doc.cursor_position > last_token.end):
      for completion in CompleteCommandGroups(tokens):
        yield Completion(completion)
      return

    # Traverse the CLI tree.
    for token in tokens:
      if token.value in node:
        info = node[token.value]
        path.append(info)
        node = info.get('commands', {})
      else:
        break

    last_token_name = last_token.value
    offset = -len(last_token_name)

    # Check for flags.
    if ((last_token_name.startswith('-') and info) or
        (last_token.token_type == parser.ArgTokenType.FLAG_ARG)):
      # 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', {})))

      if doc.text_before_cursor[-1].isspace():
        return

      if last_token.token_type == parser.ArgTokenType.FLAG_ARG:
        flag_token = tokens[-2]
        if flag_token.value in node:
          choice_offset = doc.cursor_position - last_token.end
          info = node[flag_token.value]
          if info.get('type', None) != 'bool':
            choices = info.get('choices', None)
            if choices:
              # A flag with static choices.
              offset -= choice_offset
              for choice in choices:
                if choice.lower().startswith(last_token_name.lower()):
                  yield Completion(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_token_name):
        yield Completion(
            choice,
            offset,
            display_meta=_MetaTextForChoice(choice))
Example #7
0
    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.
    """
        # Check there's at least one invocation
        invocations = parser.ParseLine(doc.text_before_cursor)
        if not invocations:
            return
        invocation = invocations[-1]

        # Check there's at least one token in the invocation
        tokens = invocation.tokens
        if not tokens:
            return

        # Only allow gcloud-related commands
        if tokens[0].value != 'gcloud':
            gcloud_token = parser.ArgToken('gcloud', parser.ArgTokenType.GROUP,
                                           gcloud_tree, 0, 0)
            tokens = ([gcloud_token] + tokens)
            invocation = parser.GcloudInvocation(tokens)

        last_token = tokens[-1]
        last_token_name = last_token.value
        offset = -len(last_token_name)
        suggestions = last_token.tree.get('commands', {})

        # Autocomplete commands and groups after spaces
        if IsGroup(last_token):
            if CursorAheadOfToken(doc.cursor_position, last_token):
                offset = last_token.end - doc.cursor_position + 1
                for completion in invocation.GetPossibleCommandGroups():
                    yield Completion(completion, offset)
                return
        elif IsFlag(last_token_name):
            suggestions = FilterHiddenFlags(invocation.GetPossibleFlags())
            if CursorAheadOfToken(doc.cursor_position, last_token):
                offset = 0
                # Check if the flag has a set of choices to choose from
                choices = suggestions.get(last_token.value,
                                          {}).get('choices', [])
                for choice in choices:
                    yield Completion(choice, offset)
                return
        elif IsFlagArg(last_token):
            suggestions = FilterHiddenFlags(invocation.GetPossibleFlags())
            flag_token = tokens[-2]
            if not CursorAheadOfToken(doc.cursor_position, last_token):
                # Check if the flag has a set of choices to choose from
                choices = suggestions.get(flag_token.value,
                                          {}).get('choices', [])
                for choice in choices:
                    if choice.lower().startswith(last_token_name.lower()):
                        yield Completion(choice, offset)
            return

        def _GetRankedCompletions():
            if self.experimental_autocomplete_enabled:
                return RankedCompletions(suggestions, invocation)
            else:
                return sorted(suggestions)

        def _DisplayTextForChoice(choice):
            """Returns the appropriate display text for the given choice.

      If the choice is a non-bool flag and experimental autocomplete is enabled,
      an equal sign followed by the flag's metavariables will be shown.
      Otherwise, only the choice name will be shown.

      Args:
        choice: the choice for which to create the display text.

      Returns:
        The appropriate display text for the given choice.
      """
            display_text = choice
            if self.experimental_autocomplete_enabled:
                if IsFlag(choice):
                    flag_type = suggestions[choice].get('type', None)
                    if flag_type != 'bool':
                        display_text += '='
                        flag_arg_value = suggestions[choice].get('value', '')
                        if flag_type == 'list' or flag_type == 'dict':
                            display_text += '[' + flag_arg_value + ',...]'
                        else:
                            display_text += flag_arg_value
            return display_text

        def _MetaTextForChoice(choice):
            if (self.experimental_autocomplete_enabled
                    and FlagIsRequired(suggestions[choice])):
                return 'required'

        ranked_completions = _GetRankedCompletions()
        for choice in ranked_completions:
            if choice.startswith(last_token_name):
                yield Completion(choice,
                                 offset,
                                 display=_DisplayTextForChoice(choice),
                                 display_meta=_MetaTextForChoice(choice))
Example #8
0
    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.
    """
        # Check there's at least one invocation
        invocations = parser.ParseLine(doc.text_before_cursor)
        if not invocations:
            return
        invocation = invocations[-1]

        # Check there's at least one token in the invocation
        tokens = invocation.tokens
        if not tokens:
            return

        # Only allow gcloud-related commands
        if tokens[0].value != 'gcloud':
            gcloud_token = parser.ArgToken('gcloud', parser.ArgTokenType.GROUP,
                                           gcloud_tree, 0, 0)
            tokens = ([gcloud_token] + tokens)
            invocation = parser.GcloudInvocation(tokens)

        last_token = tokens[-1]
        last_token_name = last_token.value
        offset = -len(last_token_name)

        suggestions = last_token.tree.get('commands', {})
        if IsFlag(last_token_name) or IsFlagArg(last_token):
            suggestions = FilterHiddenFlags(invocation.GetPossibleFlags())

        cursor_ahead = CursorAheadOfToken(doc.cursor_position, last_token)
        if IsGroup(last_token) and cursor_ahead:
            # Autocomplete commands and groups after spaces
            offset = last_token.end - doc.cursor_position + 1
            for completion in invocation.GetPossibleCommandGroups():
                yield Completion(completion, offset)
        elif IsFlag(last_token_name) and cursor_ahead:
            # Check if the flag has a set of choices to choose from
            offset = 0
            choices = suggestions.get(last_token.value, {}).get('choices', [])
            for choice in choices:
                yield Completion(choice, offset)
        elif IsFlagArg(last_token):
            if cursor_ahead:
                return
            else:
                # Check if the flag has a set of choices to choose from
                flag_token = tokens[-2]
                choices = suggestions.get(flag_token.value,
                                          {}).get('choices', [])
                for choice in choices:
                    if choice.lower().startswith(last_token_name.lower()):
                        yield Completion(choice, offset)
        else:
            ranked_completions = self._GetRankedCompletions(
                suggestions, invocation)
            for choice in ranked_completions:
                if choice.startswith(last_token_name):
                    yield Completion(choice,
                                     offset,
                                     display=self._DisplayTextForChoice(
                                         choice, suggestions[choice]),
                                     display_meta=self._MetaTextForChoice(
                                         suggestions[choice], invocation))