Important
This documentation covers IPython versions 6.0 and higher. Beginning with version 6.0, IPython stopped supporting compatibility with Python versions lower than 3.3 including all versions of Python 2.7.
If you are looking for an IPython version compatible with Python 2.7, please use the IPython 5.x LTS release and refer to its documentation (LTS is the long term support release).
Specific configuration details
LLM Suggestions
Starting with 9.0, IPython will be able to use LLM providers to suggest code in the terminal. This requires a recent version of prompt_toolkit in order to allow multiline suggestions. There are currently a number of limitations, and feedback on the API is welcome.
Unlike many of IPython features, this is not enabled by default and requires multiple configuration options to be set to properly work:
Set a keybinding to trigger LLM suggestions. Due to terminal limitations across platforms and emulators, it is difficult to provide a default keybinding. Note that not all keybindings are availables, in particular all the
Ctrl-Enter
,Alt-backslash
andCtrl-Shift-Enter
are not available without integration with your terminal emulator.Chose a LLM
provider
, usually from Jupyter-AI. This will be the interface between IPython itself, and the LLM – that may be local or in on a server.Configure said provider with models, API keys, etc – this will depend on the provider, and you will have to refer to Jupyter-AI documentation, and/or your LLM documenatation.
While setting up IPython to use a real LLM, you can refer to
examples/auto_suggest_llm.py
that both provide an example of how to set up
IPython to use a Fake LLM provider, this can help ensure that the full setup is
working before switching to a real LLM provider.
Setup a keybinding
You may want to refer on how to setup a keybinding in IPython, but in short you
want to bind the IPython:auto_suggest.llm_autosuggestion
command to a
keybinding, and have it active only when the default buffer isi focused, and
when using the NavigableSuggestions suggestter (this is the default suggestter,
the one that is history and LLM aware). Thus the navigable_suggestions &
default_buffer_focused
filter should be used.
Usually Ctrl-Q
on macos is an available shortcut, note that is does use
Ctrl
, and not Command
.
The following example will bind Ctrl-Q
to the llm_autosuggestion
command, with the suggested filter:
c.TerminalInteractiveShell.shortcuts = [
{
"new_keys": ["c-q"],
"command": "IPython:auto_suggest.llm_autosuggestion",
"new_filter": "navigable_suggestions & default_buffer_focused",
"create": True,
},
]
Choose a LLM provider
Set the TerminalInteractiveShell.llm_provider_class
trait to the fully
qualified name of the Provider you like, when testing from inside the IPython
source tree, you can use
"examples.auto_suggest_llm.ExampleCompletionProvider"
This will always
stream an extract of the Little Prince by Antoine de Saint-Exupéry, and will not
require any API key or real LLM.
In your configuration file adapt the following line to your needs:
c.TerminalInteractiveShell.llm_provider_class = "examples.auto_suggest_llm.ExampleCompletionProvider"
Configure the provider
It the provider needs to be passed parameters at initialization, you can do so
by setting the llm_provider_kwargs
traitlet.
c.TerminalInteractiveShell.llm_provider_kwargs = {"model": "skynet"}
This will depdend on the provider you chose, and you will have to refer to the provider documentation.
Extra configuration may be needed by setting environment variables, this will again depend on the provider you chose, and you will have to refer to the provider documentation.
Custom Prompts
Changed in version 5.0.
From IPython 5, prompts are produced as a list of Pygments tokens, which are tuples of (token_type, text). You can customise prompts by writing a method which generates a list of tokens.
There are four kinds of prompt:
The in prompt is shown before the first line of input (default like
In [1]:
).The continuation prompt is shown before further lines of input (default like
...:
).The rewrite prompt is shown to highlight how special syntax has been interpreted (default like
----->
).The out prompt is shown before the result from evaluating the input (default like
Out[1]:
).
Custom prompts are supplied together as a class. If you want to customise only
some of the prompts, inherit from IPython.terminal.prompts.Prompts
,
which defines the defaults. The required interface is like this:
- class MyPrompts(shell)
Prompt style definition. shell is a reference to the
TerminalInteractiveShell
instance.
Here is an example Prompt class that will show the current working directory in the input prompt:
from IPython.terminal.prompts import Prompts, Token
import os
class MyPrompt(Prompts):
def in_prompt_tokens(self):
return [(Token, os.getcwd()),
(Token.Prompt, ' >>>')]
To set the new prompt, assign it to the prompts
attribute of the IPython
shell:
In [2]: ip = get_ipython()
...: ip.prompts = MyPrompt(ip)
/home/bob >>> # it works
See IPython/example/utils/cwd_prompt.py
for an example of how to write
extensions to customise prompts.
Inside IPython or in a startup script, you can use a custom prompts class
by setting get_ipython().prompts
to an instance of the class.
In configuration, TerminalInteractiveShell.prompts_class
may be set to
either the class object, or a string of its full importable name.
To include invisible terminal control sequences in a prompt, use
Token.ZeroWidthEscape
as the token type. Tokens with this type are ignored
when calculating the width.
Colours in the prompt are determined by the token types and the highlighting
style; see below for more details. The tokens used in the default prompts are
Prompt
, PromptNum
, OutPrompt
and OutPromptNum
.
Terminal Colors
Changed in version 5.0.
There are two main configuration options controlling colours.
InteractiveShell.colors
sets the colour of tracebacks and object info (the
output from e.g. zip?
). It may also affect other things if the option below
is set to 'legacy'
. It has four case-insensitive values:
'nocolor', 'neutral', 'linux', 'lightbg'
. The default is neutral, which
should be legible on either dark or light terminal backgrounds. linux is
optimised for dark backgrounds and lightbg for light ones.
TerminalInteractiveShell.highlighting_style
determines prompt colours and
syntax highlighting. It takes the name (as a string) or class (as a subclass of
pygments.style.Style
) of a Pygments style, or the special value 'legacy'
to pick a style in accordance with InteractiveShell.colors
.
You can see the Pygments styles available on your system by running:
from pygments.styles import get_all_styles
list(get_all_styles())
Additionally, TerminalInteractiveShell.highlighting_style_overrides
can override
specific styles in the highlighting. It should be a dictionary mapping Pygments
token types to strings defining the style. See Pygments’ documentation for the language used
to define styles.
Colors in the pager
On some systems, the default pager has problems with ANSI colour codes. To configure your default pager to allow these:
Set the environment PAGER variable to
less
.Set the environment LESS variable to
-r
(plus any other options you always want to pass to less by default). This tells less to properly interpret control sequences, which is how color information is given to your terminal.
Editor configuration
IPython can integrate with text editors in a number of different ways:
Editors (such as (X)Emacs, vim and TextMate) can send code to IPython for execution.
IPython’s
%edit
magic command can open an editor of choice to edit a code block.
The %edit command (and its alias %ed) will invoke the editor set in your
environment as EDITOR
. If this variable is not set, it will default
to vi under Linux/Unix and to notepad under Windows. You may want to set this
variable properly and to a lightweight editor which doesn’t take too long to
start (that is, something other than a new instance of Emacs). This way you
can edit multi-line code quickly and with the power of a real editor right
inside IPython.
You can also control the editor by setting TerminalInteractiveShell.editor
in ipython_config.py
.
Vim
Paul Ivanov’s vim-ipython provides powerful IPython integration for vim.
(X)Emacs
If you are a dedicated Emacs user, and want to use Emacs when IPython’s
%edit
magic command is called you should set up the Emacs server so that
new requests are handled by the original process. This means that almost no
time is spent in handling the request (assuming an Emacs process is already
running). For this to work, you need to set your EDITOR environment variable
to ‘emacsclient’. The code below, supplied by Francois Pinard, can then be
used in your .emacs
file to enable the server:
(defvar server-buffer-clients)
(when (and (fboundp 'server-start) (string-equal (getenv "TERM") 'xterm))
(server-start)
(defun fp-kill-server-with-buffer-routine ()
(and server-buffer-clients (server-done)))
(add-hook 'kill-buffer-hook 'fp-kill-server-with-buffer-routine))
Thanks to the work of Alexander Schmolck and Prabhu Ramachandran, currently (X)Emacs and IPython get along very well in other ways.
With (X)EMacs >= 24, You can enable IPython in python-mode with:
(require 'python)
(setq python-shell-interpreter "ipython")
Keyboard Shortcuts
Added in version 8.11.
You can modify, disable or modify keyboard shortcuts for IPython Terminal using
TerminalInteractiveShell.shortcuts
traitlet.
The list of shortcuts is available in the Configuring IPython IPython shortcuts section.
Advanced configuration
Changed in version 5.0.
Creating custom commands requires adding custom code to a startup file:
from IPython import get_ipython
from prompt_toolkit.enums import DEFAULT_BUFFER
from prompt_toolkit.keys import Keys
from prompt_toolkit.filters import HasFocus, HasSelection, ViInsertMode, EmacsInsertMode
ip = get_ipython()
insert_mode = ViInsertMode() | EmacsInsertMode()
def insert_unexpected(event):
buf = event.current_buffer
buf.insert_text('The Spanish Inquisition')
# Register the shortcut if IPython is using prompt_toolkit
if getattr(ip, 'pt_app', None):
registry = ip.pt_app.key_bindings
registry.add_binding(Keys.ControlN,
filter=(HasFocus(DEFAULT_BUFFER)
& ~HasSelection()
& insert_mode))(insert_unexpected)
Here is a second example that bind the key sequence j
, k
to switch to
VI input mode to Normal
when in insert mode:
from IPython import get_ipython
from prompt_toolkit.enums import DEFAULT_BUFFER
from prompt_toolkit.filters import HasFocus, ViInsertMode
from prompt_toolkit.key_binding.vi_state import InputMode
ip = get_ipython()
def switch_to_navigation_mode(event):
vi_state = event.cli.vi_state
vi_state.input_mode = InputMode.NAVIGATION
if getattr(ip, 'pt_app', None):
registry = ip.pt_app.key_bindings
registry.add_binding(u'j',u'k',
filter=(HasFocus(DEFAULT_BUFFER)
& ViInsertMode()))(switch_to_navigation_mode)
For more information on filters and what you can do with the event
object,
see the prompt_toolkit docs.
Enter to execute
In the Terminal IPython shell – which by default uses the prompt_toolkit
interface, the semantic meaning of pressing the Enter key can be
ambiguous. In some case Enter should execute code, and in others it
should add a new line. IPython uses heuristics to decide whether to execute or
insert a new line at cursor position. For example, if we detect that the current
code is not valid Python, then the user is likely editing code and the right
behavior is to likely to insert a new line. If the current code is a simple
statement like ord('*')
, then the right behavior is likely to execute. Though
the exact desired semantics often varies from users to users.
As the exact behavior of Enter is ambiguous, it has been special cased
to allow users to completely configure the behavior they like. Hence you can
have enter always execute code. If you prefer fancier behavior, you need to get
your hands dirty and read the prompt_toolkit
and IPython documentation
though. See PR #10500, set the
c.TerminalInteractiveShell.handle_return
option and get inspiration from the
following example that only auto-executes the input if it begins with a bang or
a modulo character (!
or %
). To use the following code, add it to your
IPython configuration:
def custom_return(shell):
"""This function is required by the API. It takes a reference to
the shell, which is the same thing `get_ipython()` evaluates to.
This function must return a function that handles each keypress
event. That function, named `handle` here, references `shell`
by closure."""
def handle(event):
"""This function is called each time `Enter` is pressed,
and takes a reference to a Prompt Toolkit event object.
If the current input starts with a bang or modulo, then
the input is executed, otherwise a newline is entered,
followed by any spaces needed to auto-indent."""
# set up a few handy references to nested items...
buffer = event.current_buffer
document = buffer.document
text = document.text
if text.startswith('!') or text.startswith('%'): # execute the input...
buffer.accept_action.validate_and_handle(event.cli, buffer)
else: # insert a newline with auto-indentation...
if document.line_count > 1: text = text[:document.cursor_position]
indent = shell.check_complete(text)[1]
buffer.insert_text('\n' + indent)
# if you just wanted a plain newline without any indentation, you
# could use `buffer.insert_text('\n')` instead of the lines above
return handle
c.TerminalInteractiveShell.handle_return = custom_return