IPython 5.0 and key bindings in console

醉酒当歌 提交于 2021-02-18 08:57:53

问题


The new release of IPython does not depend any more on readline but uses the pure Python library prompt-toolkit, solving maintenance problems on Apple's and Windows' systems.

A new feature is the ability to edit a multi-line code block, using the cursor keys to move freely in the code block — with this power it comes, at least for me, a problem: because a ret inserts a new line in your code, to pass the whole block to the interpreter you have to use the shortcut alt+ret or possibly the less convenient key sequence esc followed by ret.

I say, this is a problem, because my terminal emulator of choice is the XTerm and, on many Linux distributions, the shortcut alt+ret is not passed to the application but it is directly used by the XTerm in which IPython is running, to toggle the screen-fullness of the said terminal (@ThomasDickey, xterm's mantainer and co-author pointed out that, by default, xterm doesn't care to send to the application the modifier bit on Enter even when one unbinds the Fullscreen action).

For this reason I'd like to modify at least this specific IPython key binding.

I've found instructions (sort of) for the previouos versions, the readline based ones, of IPython that do not apply to the new, 5.0 version.

What I would need are instructions that lead me to find, in IPython's user documentation, the names of the possible actions that I can bind, the names of the shortcuts to bind with the actions and the procedure to follow to configure a new key binding.

Failing to have this type of canonical answer, I may be happy with a recipe to accomplish this specific keybinding, with the condition that the recipe still works in IPython 6.0


回答1:


You could change xterm's configuration.

xterm is configurable (and documented). In the xterm manual, the Default Key Bindings section shows the default binding for this key:

                        Alt <Key>Return:fullscreen() \n\

You can suppress that binding in more than one way:

  • using the omitTranslation resource to suppress the feature
  • setting the fullscreen resource to never

However, just suppressing it will not make it send something interesting (xterm ignores the modifier for Enter). Setting a translation resource works, e.g., in your $HOME/.Xdefaults file:

*VT100*translations:      #override \n\ 
     Alt <Key>Return: string("\033[27;3;13~")



回答2:


The ctrl+j or ctrl+m keyboard shortcuts are validating the entry.




回答3:


Modifying keyboard shortcuts in configuration when using prompt_toolkit is not (yet) possible; though it is pretty easy if you install IPython from source. If you look at the file IPython/terminal/shortcuts.py you will see that it contains the various logic; in particular you will find:

# Ctrl+J == Enter, seemingly
registry.add_binding(Keys.ControlJ,
                     filter=(HasFocus(DEFAULT_BUFFER)
                             & ~HasSelection()
                             & insert_mode
                    ))(newline_or_execute_outer(shell))

This bind CtrlJ (enter) to the function newline_or_execute_outer which is responsible for adding new lines; it's define later in the file. In particular if you press enter twice at the end of a block of code, it should execute the block without the need to use any other shortcuts.

Strip the logic that adds new lines:

def execute_outer(shell):
    def execute(event):
        """When the user presses return, insert a newline or execute the code."""
        b = event.current_buffer

        # some logic to also dismiss the completer

        b.accept_action.validate_and_handle(event.cli, b)
    return execute

Bind it around line 20-something:

registry.add_binding(Keys.ControlE,
                     filter=(HasFocus(DEFAULT_BUFFER)
                             & ~HasSelection()
                             & insert_mode
                    ))(execute_outer(shell))

And enjoy. If you are unhappy with the documentation we welcome help; For example, taking the gist of the answers there and contributing them back. It is a bit hurtful to read harsh comments when we do say in release notes:

New terminal interface

The overhaul of the terminal interface will probably cause a range of minor
issues for existing users. This is inevitable for such a significant
change, and we’ve done our best to minimise these issues. Some changes that
we’re aware of, with suggestions on how to handle them:

IPython no longer uses readline configuration (~/.inputrc). We hope that
the functionality you want (e.g. vi input mode) will be available by
configuring IPython directly (see Terminal IPython options). If something’s
missing, please file an issue.

...

Helping actually improving IPython to have configurable keybinding with actions name is also appreciated, so then you will be able to answer your own question.



来源:https://stackoverflow.com/questions/38659721/ipython-5-0-and-key-bindings-in-console

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!