Format: text/x-python
⬇ Download File (4.6 KB)
   1  """
   2  Utilities for end-users.
   3  """
   4  
   5  import __main__
   6  from collections import namedtuple
   7  import logging
   8  import traceback
   9  import re
  10  import os
  11  import sys
  12  
  13  from jedi import Interpreter
  14  
  15  
  16  READLINE_DEBUG = False
  17  
  18  
  19  def setup_readline(namespace_module=__main__, fuzzy=False):
  20      """
  21      This function sets up :mod:`readline` to use Jedi in a Python interactive
  22      shell.
  23  
  24      If you want to use a custom ``PYTHONSTARTUP`` file (typically
  25      ``$HOME/.pythonrc.py``), you can add this piece of code::
  26  
  27          try:
  28              from jedi.utils import setup_readline
  29          except ImportError:
  30              # Fallback to the stdlib readline completer if it is installed.
  31              # Taken from http://docs.python.org/2/library/rlcompleter.html
  32              print("Jedi is not installed, falling back to readline")
  33              try:
  34                  import readline
  35                  import rlcompleter
  36                  readline.parse_and_bind("tab: complete")
  37              except ImportError:
  38                  print("Readline is not installed either. No tab completion is enabled.")
  39          else:
  40              setup_readline()
  41  
  42      This will fallback to the readline completer if Jedi is not installed.
  43      The readline completer will only complete names in the global namespace,
  44      so for example::
  45  
  46          ran<TAB>
  47  
  48      will complete to ``range``.
  49  
  50      With Jedi the following code::
  51  
  52          range(10).cou<TAB>
  53  
  54      will complete to ``range(10).count``, this does not work with the default
  55      cPython :mod:`readline` completer.
  56  
  57      You will also need to add ``export PYTHONSTARTUP=$HOME/.pythonrc.py`` to
  58      your shell profile (usually ``.bash_profile`` or ``.profile`` if you use
  59      bash).
  60      """
  61      if READLINE_DEBUG:
  62          logging.basicConfig(
  63              filename='/tmp/jedi.log',
  64              filemode='a',
  65              level=logging.DEBUG
  66          )
  67  
  68      class JediRL:
  69          def complete(self, text, state):
  70              """
  71              This complete stuff is pretty weird, a generator would make
  72              a lot more sense, but probably due to backwards compatibility
  73              this is still the way how it works.
  74  
  75              The only important part is stuff in the ``state == 0`` flow,
  76              everything else has been copied from the ``rlcompleter`` std.
  77              library module.
  78              """
  79              if state == 0:
  80                  sys.path.insert(0, os.getcwd())
  81                  # Calling python doesn't have a path, so add to sys.path.
  82                  try:
  83                      logging.debug("Start REPL completion: " + repr(text))
  84                      interpreter = Interpreter(text, [namespace_module.__dict__])
  85  
  86                      completions = interpreter.complete(fuzzy=fuzzy)
  87                      logging.debug("REPL completions: %s", completions)
  88  
  89                      self.matches = [
  90                          text[:len(text) - c._like_name_length] + c.name_with_symbols
  91                          for c in completions
  92                      ]
  93                  except:
  94                      logging.error("REPL Completion error:\n" + traceback.format_exc())
  95                      raise
  96                  finally:
  97                      sys.path.pop(0)
  98              try:
  99                  return self.matches[state]
 100              except IndexError:
 101                  return None
 102  
 103      try:
 104          # Need to import this one as well to make sure it's executed before
 105          # this code. This didn't use to be an issue until 3.3. Starting with
 106          # 3.4 this is different, it always overwrites the completer if it's not
 107          # already imported here.
 108          import rlcompleter  # noqa: F401
 109          import readline
 110      except ImportError:
 111          print("Jedi: Module readline not available.")
 112      else:
 113          readline.set_completer(JediRL().complete)
 114          readline.parse_and_bind("tab: complete")
 115          # jedi itself does the case matching
 116          readline.parse_and_bind("set completion-ignore-case on")
 117          # because it's easier to hit the tab just once
 118          readline.parse_and_bind("set show-all-if-unmodified")
 119          readline.parse_and_bind("set show-all-if-ambiguous on")
 120          # don't repeat all the things written in the readline all the time
 121          readline.parse_and_bind("set completion-prefix-display-length 2")
 122          # No delimiters, Jedi handles that.
 123          readline.set_completer_delims('')
 124  
 125  
 126  def version_info():
 127      """
 128      Returns a namedtuple of Jedi's version, similar to Python's
 129      ``sys.version_info``.
 130      """
 131      Version = namedtuple('Version', 'major, minor, micro')
 132      from jedi import __version__
 133      tupl = re.findall(r'[a-z]+|\d+', __version__)
 134      return Version(*[x if i == 3 else int(x) for i, x in enumerate(tupl)])
 135