def complete(self, line):
        """
        Attempt to auto-completes the given line. Returns the completed
        line and a list of possibilities.

        :param str line: The line to complete
        :rtype: (str, [str])
        """
        _, current_state = self.stash.runtime.get_current_worker_and_state()

        len_line = len(line)
        tokens, _ = self.stash.runtime.parser.parse(line)

        toks = []  # this is only for sub-cmd completion
        is_cmd_word = True
        for t in tokens:
            if t.ttype == ShToken._CMD:
                toks = []
                is_cmd_word = True

            if t.epos == len_line:
                word_to_complete = t.tok
                replace_from = t.spos
                break

            toks.append(t.tok)
            is_cmd_word = False

        else:
            word_to_complete = ''
            replace_from = len_line

        toks.append(word_to_complete)

        if self.debug:
            self.logger.debug(
                'is_cmd_word: %s, word_to_complete: %s, replace_from: %d\n' % (is_cmd_word,
                                                                               word_to_complete,
                                                                               replace_from)
            )

        cands, with_normal_completion = self.stash.libcompleter.subcmd_complete(toks)

        if cands is None or with_normal_completion:

            path_names = self.path_match(word_to_complete)

            if is_cmd_word:
                path_names = [p for p in path_names if p.endswith('/') or p.endswith('.py') or p.endswith('.sh')]
                script_names = self.stash.runtime.get_all_script_names()
                script_names.extend(current_state.aliases.keys())
                if word_to_complete != '':
                    script_names = [name for name in script_names if name.startswith(word_to_complete)]
            else:
                script_names = []

            if word_to_complete.startswith('$'):
                environ_names = [
                    '$' + varname for varname in current_state.environ.keys() if varname.startswith(word_to_complete[1:])
                ]
            else:
                environ_names = []

            all_names = path_names + environ_names + script_names

        else:
            all_names = cands

        all_names = sorted(set(all_names))

        # Do not show hidden files when matching for an empty string
        if word_to_complete == '':
            all_names = [name for name in all_names if not name.startswith('.')]

        # Complete up to the longest common prefix of all possibilities
        prefix = os.path.commonprefix(all_names)

        # TODO: check max number possibilities
        if prefix != '':
            if len(all_names) == 1 and not prefix.endswith('/'):
                prefix += ' '
            newline = line[:replace_from] + prefix
        else:
            newline = line

        return newline, all_names

        Attempt to auto-completes the given line. Returns the completed
        line and a list of possibilities.

        :param str line: The line to complete
        :rtype: (str, [str])
        
system/shparsers.py