예제 #1
0
 def add_completer(self, fxn, **kargs):
     """ adds (and logs the addition of) a completion hook,
         probably with run-priority mentioned in the kargs
     """
     completion_log.info("adding new completer: {0}".format(fxn))
     self.completers[get_caller(2)['class']].append(fxn)
     get_ipython().set_hook('complete_command', fxn, **kargs)
예제 #2
0
def smash_env_complete(symbol):
    completion_log.info("symbol: [{0}]".format(symbol))
    symbol = symbol.strip()
    if not symbol:
        return
    if symbol.startswith('$'):
        symbol = symbol[1:]
    return [x for x in os.environ if x.startswith(symbol)]
예제 #3
0
 def history_completion_update(self, line):
     line = line.strip()
     tokens = smart_split(line)
     full = len(self.db) > self.MAX_SIZE
     completion_log.info('eating {0} tokens'.format(len(tokens)))
     for token in tokens:
         if len(token) < 4:
             # too small, dont care
             continue
         if token not in self.db:
             self.db.append(token)
         if full:
             self.db.pop(0)
예제 #4
0
def fabric_cmd_completer(self, event):
    completion_log.info("event [{0}]".format(event.__dict__))
    if event.symbol.startswith("-"):
        return []
    if ope("fabfile.py"):
        _fabfile = "fabfile.py"
    elif ope("Fabfile.py"):
        _fabfile = "Fabfile.py"
    else:
        smash_log.info("no fabfile was found")
        return []
    with open(_fabfile, "r") as fhandle:
        src = fhandle.read()
    node = ast.parse(src)
    return list([x.name for x in ast.walk(node) if isinstance(x, ast.FunctionDef)])
예제 #5
0
    def smash_matcher(self, shell, event):
        completion_log.info('completing event: {0}'.format(event.__dict__))
        line = event.line

        if not line.strip():
            raise TryNext()
        first_word = line.split()[0]
        # NB: cannot use event.symbol here, it splits on '$'
        last_word = event.text_until_cursor.split()
        last_word = last_word[-1] if last_word else ''
        completion_log.info("first-word, last-word: {0}".format(
            [first_word, last_word]))
        if last_word.startswith('$'):
            return smash_env_complete(last_word)
        magic_command_alias = first_word.startswith('%') and \
            have_command_alias(first_word[1:])
        naked_command_alias = have_command_alias(first_word)
        results = []
        if naked_command_alias:
            completion_log.info('naked command alias detected')
            results += smash_bash_complete(line)[:self.MAX_MATCH]
        elif magic_command_alias:
            completion_log.info('magic command alias detected')
            results += smash_bash_complete(line[1:])[:self.MAX_MATCH]

        # can't do anything smarter? look for file matches.
        # this works by default if the last word contains os.path.sep,
        # but this doesn't necessarily work with the special "ed" alias
        # unless this sectiion is executed
        if not results:
            completion_log.info(('no results for completion, looking for '
                                 'file matches with "{0}"'.format(last_word)))
            results = self.smash.shell.Completer.file_matches(last_word)

        if results:
            completion_log.info("returning: {0}".format(results))
            return results
        else:
            completion_log.info("no results so far, raising trynext ")
            raise TryNext()
예제 #6
0
def smash_bash_complete(*args, **kargs):
    completion_log.info("calling pybcompgen: {0}".format([args, kargs]))
    result = complete(*args, **kargs)
    completion_log.info("result: {0}".format(result))
    result = [x for x in result if x not in keyword.kwlist]
    return result
예제 #7
0
 def init(self):
     completion_log.info("adding fabric completer")
     self.smash.add_completer(fabric_cmd_completer, re_key="fab")
     self.smash.add_completer(fabric_opt_completer, re_key="fab -")
     self.smash.add_completer(fabric_opt_completer, re_key="fab --")
     return self
예제 #8
0
    def complete(self, text=None, line_buffer=None, cursor_pos=None):
        completion_log.info("received data: [{0}]".format(
            [text, line_buffer, cursor_pos]))
        """Find completions for the given text and line context.

        Note that both the text and the line_buffer are optional, but at least
        one of them must be given.

        Parameters
        ----------
          text : string, optional
            Text to perform the completion on.  If not given, the line buffer
            is split using the instance's CompletionSplitter object.

          line_buffer : string, optional
            If not given, the completer attempts to obtain the current line
            buffer via readline.  This keyword allows clients which are
            requesting for text completions in non-readline contexts to inform
            the completer of the entire text.

          cursor_pos : int, optional
            Index of the cursor in the full line buffer.  Should be provided by
            remote frontends where kernel has no access to frontend state.

        Returns
        -------
        text : str
          Text that was actually used in the completion.

        matches : list
          A list of completion matches.
        """
        # io.rprint('\nCOMP1 %r %r %r' % (text, line_buffer, cursor_pos))  #
        # dbg

        # if the cursor position isn't given, the only sane assumption we can
        # make is that it's at the end of the line (the common case)
        if cursor_pos is None:
            cursor_pos = len(line_buffer) if text is None else len(text)

        if PY3:
            latex_text = text if not line_buffer else line_buffer[:cursor_pos]
            latex_text, latex_matches = self.latex_matches(latex_text)
            if latex_matches:
                return latex_text, latex_matches

        # if text is either None or an empty string, rely on the line buffer
        if not text:
            text = self.splitter.split_line(line_buffer, cursor_pos)

        # If no line buffer is given, assume the input text is all there was
        if line_buffer is None:
            line_buffer = text

        self.line_buffer = line_buffer
        self.text_until_cursor = self.line_buffer[:cursor_pos]
        # io.rprint('COMP2 %r %r %r' % (text, line_buffer, cursor_pos))  # dbg

        # Start with a clean slate of completions
        self.matches[:] = []
        custom_res = self.dispatch_custom_completer(text)
        if custom_res:
            # did custom completers produce something?
            completion_log.info("custom completers: {0}".format(custom_res))
            self.matches = custom_res
        else:
            # Extend the list of completions with the results of each
            # matcher, so we return results to the user from all
            # namespaces.
            if self.merge_completions:
                completion_log.info('merging completions')
                self.matches = []
                for matcher in self.matchers:
                    extra = matcher(text)
                    self.matches.extend(extra)
                    completion_log.info(
                        "extending matches with: {0}".format(extra))
                    # try:
                    #    self.matches.extend(matcher(text))
                    # except:
                    # Show the ugly traceback if the matcher causes an
                    # exception, but do NOT crash the kernel!
                    #    raise
                    #   sys.excepthook(*sys.exc_info())
            else:
                for matcher in self.matchers:
                    self.matches = matcher(text)
                    if self.matches:
                        completion_log.info(
                            "returning matches from: {0}".format(matcher))
                        break
        # FIXME: we should extend our api to return a dict with completions for
        # different types of objects.  The rlcomplete() method could then
        # simply collapse the dict into a list for readline, but we'd have
        # richer completion semantics in other evironments.

        # use penalize_magics_key to put magics after variables with same name
        self.matches = sorted(set(self.matches), key=penalize_magics_key)
        completion_log.info('COMP TEXT, MATCHES: %r, %r' %
                            (text, self.matches))  # dbg
        return text, self.matches