
Python REPL with syntax highlighting, autocomplete and multiline editing - tbrock
https://github.com/jonathanslenders/python-prompt-toolkit
======
aidos
This is actually brilliant. It fixes my (relatively minor) gripes with the
standard iPython front-end. Namely the multiline mode is miles better, so so
much better.

Already mentioned on the thread somewhere else is an issue with autocompletion
on imported modules, but that sounds like a bug that will be fixed.

I'm using the ipython mode and there are a couple of differences. For example
I'm used to typing 'hist -l 100' to see the recent history, now I need to use
the magic ipython variant '%hist -l 100'. Not a big deal, just slightly
different behaviour.

The vi-mode is actually not too bad. For me it's good enough to be used in
this context. Would be great if it was more complete (eg, daw doesn't work).
Maybe it could make use of neovim at some point?

I LOVE that a syntax error means the line isn't flushed so you can fix the
issue and hit enter to execute it again. That's a really smart enhancement
that I hadn't even noticed was a total waste of time in my workflow until now.

Does it read my local iPython config profile? I use auto-reloading heavily for
hot code swapping during my development, will that still work?

Edit: just tested and the iPython auto-reloading isn't working. Maybe it needs
to be converted to run as a front-end to get the full power of iPython?

Also, needed to do _PYTHONPATH=. ptipython --vi_ to be able to load modules
from the directory in which I started the app.

~~~
jonathan_s
Thanks for the feedback.

About "daw": it looks like I forgot about that. To be fixed, but right now use
"diw" instead. (Please create a github issue if there are some other important
key bindings missing.)

At the moment, I don't know yet about auto-reloading in IPython, but that's
worth looking at.

About the PYTHONPATH, that's easy to fix. (Should we always add the current
directory to the path in a REPL?)

~~~
PythonicAlpha

      (Should we always add the current directory to the path in a REPL?)
    

Yes, of course! That was my first problem. The standard "python" always has
the current directory in the module path.

Please also have a look on my suggestion for the search facility:
[https://news.ycombinator.com/item?id=8391647](https://news.ycombinator.com/item?id=8391647)

It would be really helpful, to just search for some keyword and have the last
occurence (for example import) as template without the need for going back the
history by hand.

~~~
jonathan_s
>> It would be really helpful, to just search for some keyword and have the
last occurence...

In Vi-mode, use ControlX-ControlL after typing the start of the line, then you
have line based completion, which also completes from the history.

------
devnonymous
Disclaimer: this comment includes a shameless plug to something I wrote. Read
further only if you are not offended by this behavior. I am just trying to
help others reading this post who like me think IPython might be a bit of an
overkill at times but aren't really happy with the default python prompt. Now
my comment ...

This Looks really nice and it does seem like it adds a lot to IPython. That
said, I personally prefer working in a proper editor (rather than an
approximation) when doing multi-line editing of commands on the prompt. So I
wrote a small function to just invoke the editor with the lines in the current
prompt 'buffer'[1]. This gives all the things like autocomplete and syntax-
highlighting for free (albeit, when you are in the editor). Further more you
may open up other buffers to refer to other code while editing the thing that
you are on your prompt.

To see what I mean --
[https://gist.github.com/lonetwin/5902720](https://gist.github.com/lonetwin/5902720)

Furthermore, what I wrote is a small enough file to copy as a .pythonrc
(rather than pip install ...).

[1] ...and then I added more ...a _lot_ more.

------
nobodysbusiness
If you're looking for a better python prompt, you might want to check out
BPython as well: [http://bpython-interpreter.org/](http://bpython-
interpreter.org/)

~~~
gknoy
I used to use BPython. I really liked its way of presenting autocomplete.
However, its scrolling drove me NUTS (it doesn't use your terminal's scroll).
I was much happier when I switched to IPython.

Both are leagues better than the plain REPL, though. :)

~~~
vishvananda
If you haven't seen it, you should check out bpython-curtsies, it solves the
scrolling problem problem:

    
    
        pip install bpython[curtsies]
        bpython-curtsies

------
orkoden
For ruby there's something similar called pry
[http://pryrepl.org](http://pryrepl.org) which I've been using instead of irb
for a while now. It's great news to do something similar with python now too.

------
rattray
This is awesome. Can't imagine wanting to use anything else now.

Folks who like the library aspect of this and are interested in building
similar things for bash instead of python might want to check out twosheds
[0], a library by a friend of mine that lets you do zsh-type-stuff in Python.

[0] [https://github.com/Ceasar/twosheds](https://github.com/Ceasar/twosheds)

------
PythonicAlpha
Very useful, indeed.

One thing that I am missing already is searching inside the history for a
specific input. There is some search facility (in vi mode, you can press / and
it says that it will search), but I don't know how it works, since it gives no
results.

Ok, now I see, it just marks the search results, but does not give an
immediate result. That is not, what I would expect and what would be useful
for me. In ksh, I believe, there was the possibility to search backwards in
history and when it was performed, the most recent input line was put into the
active input for replay or editing.

~~~
jonathan_s
This could be confusing. '?' is for searching backwards, '/' for searching
forward. Because we are in a multiline environment, I preferred the Vi
keybindings instead of the readline bindings (where '/' goes backwards.)

Also the ControlX-ControlL sequence can complete a line based on the history.
(Type "imp"C-X C-L and you get your last import.)

------
giancarlostoro
It's refreshing to see that it works with Python 3 as well. Thanks.

------
arocks
Looks like an IPython replacement with syntax highlighting as you type.
Couldn't this be something that could be added to IPython itself?

~~~
jonathan_s
(author here.)

The idea is indeed that ``ptpython`` could become the terminal front-end for
IPython.

The only thing on which ``prompt_toolkit`` is focussing, is reading input from
stdin and returning it to the application. IPython is a very powerful
execution environment, but the current command line interface which uses GNU
readline lacks decent multiline editing and syntax highlighting.

There is a proof of concept of what the integration could look like:
[https://github.com/jonathanslenders/python-prompt-
toolkit/bl...](https://github.com/jonathanslenders/python-prompt-
toolkit/blob/master/bin/ptipython) But in the end it would be nice to have
this as a part of IPython itself.

~~~
andreasvc
How does it compare to bpython, then? That does syntax highlighting and has
support for multiline editing IIRC.

~~~
thomasballinger
Basically it's great, and matches up well with bpython: I wrote up some
comparisons at [http://ballingt.com/2014/09/30/prompt-
toolkit.html](http://ballingt.com/2014/09/30/prompt-toolkit.html) (bpython-
curtsies author here)

------
1331
Great job!

I really like the multi-line editing and IPython-style prompts. The syntax
highlighting feature is nice as well, and it can be turned off with a flag. I
am not a fan of auto-completion, however, so I wish there were a flag to turn
it off as well (perhaps --autocompletion=off).

~~~
jonathan_s
Thank you for the feedback. I'll add an option to turn off the automatic
autocompletion.

------
arenaninja
This is amazing. My niece has recently been interested in "doing what I do",
and Python is the language of choice for that. I was thinking of using
bpython, but I guess I'll have my choice of REPLs

------
jeffrand
This is great, I really enjoy this. The one thing I'd be interesting in
contributing is using ipython's sqlite history database if a user chooses to.

------
firemanphil
This is fantastic and completely intuitive. After wasting many hours fiddling
around with Vim plugins so that I can use autocompletion, this is a relief.

------
antihero
This looks neat, would be great to get it working with django-extensions so we
can have the nice ./manage.py shell_plus using it if available.

~~~
jonathan_s
We have that: [https://github.com/django-extensions/django-
extensions/commi...](https://github.com/django-extensions/django-
extensions/commit/a21d6424e9c753a11ea12fd40c4bd1a806447ea6)

(Not yet on Pypi, we we'll get there.)

~~~
antihero
You beautiful person.

------
Beltiras
Maybe I am just doing something wrong, but ptipython does not autocomplete
anything I import.

~~~
jonathan_s
(author here)

I noticed. You're not doing it wrong. It's a bug and it will be fixed asap.

------
stuaxo
Very very nice. Does it work in windows too ?

~~~
jonathan_s
I'm sorry about this, at the moment there is no Windows support.

However the architecture of the library decouples the input and output from
the rest, so it should be possible to plug in something to make it compatible
with the Windows terminal.

For me personally, it doesn't have priority, but maybe in the future I will
have a look.

------
mrmch
This is freaking awesome. Vi-mode is huge.

------
sgt
Getting some errors trying to define simple functions and call them:

    
    
      In [3]: foo(Exception in thread Thread-159:
      Traceback (most recent call last):
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner
        self.run()
      File "/Library/Python/2.7/site-packages/prompt_toolkit/__init__.py", line 200, in run
        callback()
      File "/Library/Python/2.7/site-packages/prompt_toolkit/__init__.py", line 440, in run.7.6
        completions = list(line.completer.get_completions(document))
      File "/Library/Python/2.7/site-packages/prompt_toolkit/contrib/python_input.py", line 449, in get_completions
        for c in script.completions():
      File "/Library/Python/2.7/site-packages/jedi/api/__init__.py", line 161, in completions
        for call_sig in self.call_signatures():
      File "/Library/Python/2.7/site-packages/jedi/api/__init__.py", line 574, in call_signatures
        self._pos, user_stmt)
      File "/Library/Python/2.7/site-packages/jedi/cache.py", line 90, in wrapper
        value = optional_callable()
      File "/Library/Python/2.7/site-packages/jedi/api/__init__.py", line 572, in <lambda>
        _callable = lambda: self._evaluator.eval_call(stmt_el)
      File "/Library/Python/2.7/site-packages/jedi/evaluate/__init__.py", line 226, in eval_call
        return self.eval_call_path(path, par, s.start_pos)
      File "/Library/Python/2.7/site-packages/jedi/evaluate/__init__.py", line 240, in eval_call_path
        search_global=True)
      File "/Library/Python/2.7/site-packages/jedi/evaluate/__init__.py", line 113, in find_types
        return f.find(scopes, resolve_decorator, search_global)
      File "/Library/Python/2.7/site-packages/jedi/debug.py", line 51, in wrapper
        result = func(*args, **kwargs)
      File "/Library/Python/2.7/site-packages/jedi/evaluate/finder.py", line 46, in find
        names = self.filter_name(scopes)
      File "/Library/Python/2.7/site-packages/jedi/evaluate/finder.py", line 89, in filter_name
        scope = name.parent.parent
      File "/Library/Python/2.7/site-packages/jedi/cache.py", line 139, in wrapper
        result = func(self)
      File "/Library/Python/2.7/site-packages/jedi/api/interpreter.py", line 69, in parent
        module = __import__(module_name)

TypeError: __import__() argument 1 must be string, not None

~~~
lake99
HN is not the right place for reporting bugs of this sort. Report it on
github.

