Skip to content

Terminal interface based on prompt_toolkit#9118

Merged
Carreau merged 36 commits intoipython:masterfrom
takluyver:ptshell
Feb 22, 2016
Merged

Terminal interface based on prompt_toolkit#9118
Carreau merged 36 commits intoipython:masterfrom
takluyver:ptshell

Conversation

@takluyver
Copy link
Member

This adds a new terminal interface using prompt_toolkit in place of readline. It's on top of my refactoring in #9070.

You can test the new interface by running:

python3 -m IPython.terminal.ptshell

Multiline editing with syntax highlighting, persistent history and tab completion are all working. So far, I'm really impressed with prompt_toolkit: I've written about 100 lines to make that happen, and while it's taken some research, nothing I've had to do feels like a hack. Kudos to @jonathanslenders :-)

@jonathanslenders
Copy link
Contributor

This is really great to see you doing this work @takluyver! I have not had the time to write the shell for IPython. Don't hesitate to let me know if you have any questions about this library.

@takluyver
Copy link
Member Author

Thanks! So far I'm working it out OK, and I'm impressed with your docs (though I'm referring to the code quite a bit as well to work out the best way to integrate our stuff). But I'll be in touch if there are any questions I get stuck on!

One thing that gave me a bit of trouble was multiline. Each time the user presses enter, we try to work out whether to prompt for an extra line or execute the code that's already there. I initially tried expressing this by passing a Condition to multiline which ran the 'prompt for more input' test, but it caused some odd behaviour as that changed back and forth. So now I'm passing multiline=True and overriding the Enter key event to do the 'prompt for more input' test. I'm perfectly happy with this solution, but I think it's useful for API design to understand where users have gone wrong.

@takluyver
Copy link
Member Author

Actually, now that I'm thinking about it, there is something I'd like to ask about:

When the buffer is multiline, is there an easy way to have continuation prompts on each row? Currently there's just blank space to the left, and it's not obvious how much is prompt and how much is indentation. I.e.:

# What I currently have:
In [1]: for a in range(5):
            print(a)

# What I'd like:
In [1]: for a in range(5):
      :      print(a)
      :      

I'm sure this is possible using the deeper API described in 'Building a full screen application', but so far I've been able to stick with the higher level APIs for prompts, and this feels like something that should be simple enough.

@jonathanslenders
Copy link
Contributor

Hi @takluyver,

About overriding the Enter key binding, that's fine. That's also what I'm doing. (I think, that behaviour is quite custom for each application.)

About the continuation prompts, that's not yet possible with the shortcut function, but I will try to implement that asap. (@scopatz from xonsh had the same request: prompt-toolkit/python-prompt-toolkit#209 ) Just keep using the higher level API, and assume that it will be possible very soon.

Jonathan

@takluyver
Copy link
Member Author

Awesome, thanks! And let me know if I can help with that or anything else in PT - it looks like we're going to be able to ditch a lot of rusty old code, simplify installation and improve the user experience all in one go, so we're very grateful, and accordingly happy to do our bit. :-)

@jonathanslenders
Copy link
Contributor

Thanks for the offer! Everything in PT becomes very stable, there's probably not much need to improve it. If there is something that has to be done, it's better documentation. Mostly for all the "internal" stuff that people creating full screen apps would use. Don't worry about that, just focus on the IPython user interface. ;) But all feedback about things that can be done better is very welcome!

@takluyver
Copy link
Member Author

Ah, brilliant, and it's good to hear that it's pretty stable as well. I'll let you know of any snags that I run into, and if I meet you at a conference some time, I'll buy you a drink. ;-)

@jonathanslenders
Copy link
Contributor

I will remember that ;-)

@takluyver
Copy link
Member Author

Another question that's not really specific to prompt_toolkit, but I guess you know quite a bit about terminals. We've had trouble in the past picking default colours, because as far as we can find there's no way to know whether the terminal has a dark or a light background. Do you know of either some secret terminal foo to detect that, or any best practices for picking text colours that will work either way?

@jonathanslenders
Copy link
Contributor

Pick colors that work either way. There is no universal way that works everywhere. The default color (black or white) should always be visible. Of course it's possible to specify a background color as well, but that's not respectful regarding the user preferences of the terminal application.

@takluyver
Copy link
Member Author

Fair enough. BTW, in the colours section of the docs, it would be useful to see how to override a token's colour back to the plain terminal default, if you want to override a colour set in the default style.

@takluyver
Copy link
Member Author

On Windows, pyreadline currently handles translating the ANSI escapes for colours etc. into Windows API calls. Clearly PT can talk to Windows for its own colouring etc., but we'd also like to use colours in other parts of IPython, like for tracebacks.

  • Does PT offer an ANSI to Windows-API convertor that we can hook into sys.stdout to colour other output? Or should we use a separate package like colorama to do this?
  • If we use a separate ANSI to Windows terminal package, is there a risk that will interfere with what PT is doing?

@takluyver
Copy link
Member Author

Is there a halfway house for the complete_while_typing option? In the notebook, we don't offer any completions until the user hits tab to request them, but once the completion popup is visible, it remains visible and updates as the user types more letters. Maybe it's just familiarity, but this feels about right to me.

With complete_while_typing on, I find it pops up a bit too eagerly and distracts me, though perhaps I just need to get used to it. With the option off, I find it disappears when I'd expect it to stay.

@Carreau
Copy link
Member

Carreau commented Jan 12, 2016

subscribing to issue.

@jasongrout
Copy link
Member

(FYI, @Carreau, you can subscribe to an issue by clicking on the "subscribe" button in the upper right, in the "Notifications" heading in the right column. You don't have to comment to subscribe)

@Carreau
Copy link
Member

Carreau commented Jan 12, 2016

(FYI, @Carreau, you can subscribe to an issue by clicking on the "subscribe" button in the upper right, in the "Notifications" heading in the right column. You don't have to comment to subscribe)

I know, I did. I wrote the message just for human friendly information.

@jonathanslenders
Copy link
Contributor

@takluyver I hope to do a new prompt_toolkit release, somewhere this month.

Currently, I'm rewriting some code to properly handle arbitrary big inputs. (Right now, it becomes slow around 2000 lines, while my development version handles 100,000 lines smoothly.) This is however irrelevant for most users, so probably I will release first without those changes.

@takluyver
Copy link
Member Author

Great! I look forward to the new release. And the large input changes sound amazing, even if I doubt we'd ever use them. I guess that's prompted by things like pyvim?

@jonathanslenders
Copy link
Contributor

@takluyver: When do you expect to release a first beta version of IPython 5? Just to make sure that I don't wait too long for pushing a new prompt-toolkit release. If I can wait maybe one or two weeks, that would be good on my side.

@Carreau
Copy link
Member

Carreau commented Feb 9, 2016

@takluyver: When do you expect to release a first beta version of IPython 5?

Not soon. Is that sufficient for you ?

@takluyver
Copy link
Member Author

Yeah, one or two weeks definitely won't be a problem. We don't start doing pre-releases until fairly close to the release, and for IPython 5.0, that's likely to be months away.

That said, I want to get people using this on master fairly soon so that we have plenty of time to discover bugs. If the new prompt_toolkit's coming any time this month, that's fine - if you think it might be longer, I'll temporarily disable the continuation prompts, which should make it work with the released version, and then we can add them back when you have time to do a release.

@takluyver
Copy link
Member Author

I decided to disable the continuation prompts so that this can move forwards. It's trivial to re-enable them once there's a new release of prompt_toolkit.

After a bit of fiddling with the tests, this is passing now, so I think it's ready to go.

@Carreau
Copy link
Member

Carreau commented Feb 22, 2016

After a bit of fiddling with the tests, this is passing now, so I think it's ready to go.

I'll go through that quickly one last time and merge.

@Carreau
Copy link
Member

Carreau commented Feb 22, 2016

Thanks !

Carreau added a commit that referenced this pull request Feb 22, 2016
Terminal interface based on prompt_toolkit
@Carreau Carreau merged commit 7d6dfc3 into ipython:master Feb 22, 2016
@takluyver
Copy link
Member Author

🎈

@asmeurer
Copy link
Contributor

I just tested this. Is it possible for the PTInteractiveShell to inherit from TerminalInteractiveShell so that my existing configuration carries forward? Or is the new configuration too different for this to work?

@Carreau
Copy link
Member

Carreau commented Feb 22, 2016

so that my existing configuration carries forward?

Which part of your configuration in particular ? it' already inherit form InteractiveShell and many methods of TerminalInteractiveShell don't make sent for PTInteractiveShell.

@takluyver
Copy link
Member Author

We could rename PTInteractiveShell to TerminalInteractiveShell so that it tries to apply all the same config, since config just goes by class names. It doesn't necessarily mean it will all work, though.

@asmeurer
Copy link
Contributor

Well I don't have much configured. Personally, I was jarred my color settings, custom prompt (I need to test if that still works out of the box), and confirm_exit settings were reverted. I guess the problem is that the configuration that was created by IPython ages ago used TerminalInteractiveShell in the skeleton.

@takluyver
Copy link
Member Author

Or introduce an empty intermediate class called TerminalInteractiveShell. I don't want it to inherit from the old TIS class, though - the aim is to get rid of that.

Prompt configuration will be lost - I'm still thinking about how to make them configurable (and, mildly devil's advocating, whether to even bother - since the two process work, prompt customisation for other frontends has come up occasionally, but never been high enough priority for us to work on it there)

@Carreau
Copy link
Member

Carreau commented Feb 22, 2016

THe color think wil likely not work, but I am working on that, and I have some patches in Pygments so that Styles can use #ansi<color> to actually match terminals settings. But it will take a few iterations.

@takluyver
Copy link
Member Author

The colour config should still work for other bits of colour (tracebacks, foo? output, etc.), but it won't affect the input prompts or syntax highlighting as you type. There's a new option PTInteractiveShell.highlighting_style, which takes the name of a Pygments style.

@rcarneva
Copy link

rcarneva commented Mar 8, 2016

The new interface is slick, and I really appreciate the incorporation of vi keys. Really nice addition!

@takluyver
Copy link
Member Author

Thanks @rcarneva

@ndunsworth
Copy link

Is there any way to turn off pt in 5.0?

I really miss the dir like tab completion of readline. Its the main reason I hit tab. Its a fast dir call.

Please tell me I'm missing some config option in pt or ipy to disable the pulldown autocompletion.

@takluyver
Copy link
Member Author

There is no option to switch back to readline. There are discussions going on in other issues about how best to present completions.

@ndunsworth
Copy link

After a quick search I was not able to find any such discussions, could you provide a few please?

Also where would be a good starting point in the source for completely disabling ipy autocompletion so that readline will work on its own?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants