##// END OF EJS Templates
Include reviews from `@tornaria`
Matthias Bussonnier -
Show More
@@ -1,323 +1,321 b''
1 1 =======================
2 2 Specific config details
3 3 =======================
4 4
5 5 .. _custom_prompts:
6 6
7 7 Custom Prompts
8 8 ==============
9 9
10 10 .. versionchanged:: 5.0
11 11
12 12 From IPython 5, prompts are produced as a list of Pygments tokens, which are
13 13 tuples of (token_type, text). You can customise prompts by writing a method
14 14 which generates a list of tokens.
15 15
16 16 There are four kinds of prompt:
17 17
18 18 * The **in** prompt is shown before the first line of input
19 19 (default like ``In [1]:``).
20 20 * The **continuation** prompt is shown before further lines of input
21 21 (default like ``...:``).
22 22 * The **rewrite** prompt is shown to highlight how special syntax has been
23 23 interpreted (default like ``----->``).
24 24 * The **out** prompt is shown before the result from evaluating the input
25 25 (default like ``Out[1]:``).
26 26
27 27 Custom prompts are supplied together as a class. If you want to customise only
28 28 some of the prompts, inherit from :class:`IPython.terminal.prompts.Prompts`,
29 29 which defines the defaults. The required interface is like this:
30 30
31 31 .. class:: MyPrompts(shell)
32 32
33 33 Prompt style definition. *shell* is a reference to the
34 34 :class:`~.TerminalInteractiveShell` instance.
35 35
36 .. method:: in_prompt_tokens(cli=None)
36 .. method:: in_prompt_tokens()
37 37 continuation_prompt_tokens(self, width=None)
38 38 rewrite_prompt_tokens()
39 39 out_prompt_tokens()
40 40
41 41 Return the respective prompts as lists of ``(token_type, text)`` tuples.
42 42
43 43 For continuation prompts, *width* is an integer representing the width of
44 44 the prompt area in terminal columns.
45 45
46 *cli*, where used, is the prompt_toolkit ``CommandLineInterface`` instance.
47 This is mainly for compatibility with the API prompt_toolkit expects.
48 46
49 47 Here is an example Prompt class that will show the current working directory
50 48 in the input prompt:
51 49
52 50 .. code-block:: python
53 51
54 52 from IPython.terminal.prompts import Prompts, Token
55 53 import os
56 54
57 55 class MyPrompt(Prompts):
58 def in_prompt_tokens(self, cli=None):
56 def in_prompt_tokens(self):
59 57 return [(Token, os.getcwd()),
60 58 (Token.Prompt, ' >>>')]
61 59
62 60 To set the new prompt, assign it to the ``prompts`` attribute of the IPython
63 61 shell:
64 62
65 63 .. code-block:: python
66 64
67 65 In [2]: ip = get_ipython()
68 66 ...: ip.prompts = MyPrompt(ip)
69 67
70 68 /home/bob >>> # it works
71 69
72 70 See ``IPython/example/utils/cwd_prompt.py`` for an example of how to write
73 71 extensions to customise prompts.
74 72
75 73 Inside IPython or in a startup script, you can use a custom prompts class
76 74 by setting ``get_ipython().prompts`` to an *instance* of the class.
77 75 In configuration, ``TerminalInteractiveShell.prompts_class`` may be set to
78 76 either the class object, or a string of its full importable name.
79 77
80 78 To include invisible terminal control sequences in a prompt, use
81 79 ``Token.ZeroWidthEscape`` as the token type. Tokens with this type are ignored
82 80 when calculating the width.
83 81
84 82 Colours in the prompt are determined by the token types and the highlighting
85 83 style; see below for more details. The tokens used in the default prompts are
86 84 ``Prompt``, ``PromptNum``, ``OutPrompt`` and ``OutPromptNum``.
87 85
88 86 .. _termcolour:
89 87
90 88 Terminal Colors
91 89 ===============
92 90
93 91 .. versionchanged:: 5.0
94 92
95 93 There are two main configuration options controlling colours.
96 94
97 95 ``InteractiveShell.colors`` sets the colour of tracebacks and object info (the
98 96 output from e.g. ``zip?``). It may also affect other things if the option below
99 97 is set to ``'legacy'``. It has four case-insensitive values:
100 98 ``'nocolor', 'neutral', 'linux', 'lightbg'``. The default is *neutral*, which
101 99 should be legible on either dark or light terminal backgrounds. *linux* is
102 100 optimised for dark backgrounds and *lightbg* for light ones.
103 101
104 102 ``TerminalInteractiveShell.highlighting_style`` determines prompt colours and
105 103 syntax highlighting. It takes the name (as a string) or class (as a subclass of
106 104 ``pygments.style.Style``) of a Pygments style, or the special value ``'legacy'``
107 105 to pick a style in accordance with ``InteractiveShell.colors``.
108 106
109 107 You can see the Pygments styles available on your system by running::
110 108
111 109 from pygments.styles import get_all_styles
112 110 list(get_all_styles())
113 111
114 112 Additionally, ``TerminalInteractiveShell.highlighting_style_overrides`` can override
115 113 specific styles in the highlighting. It should be a dictionary mapping Pygments
116 114 token types to strings defining the style. See `Pygments' documentation
117 115 <http://pygments.org/docs/styles/#creating-own-styles>`__ for the language used
118 116 to define styles.
119 117
120 118 Colors in the pager
121 119 -------------------
122 120
123 121 On some systems, the default pager has problems with ANSI colour codes.
124 122 To configure your default pager to allow these:
125 123
126 124 1. Set the environment PAGER variable to ``less``.
127 125 2. Set the environment LESS variable to ``-r`` (plus any other options
128 126 you always want to pass to less by default). This tells less to
129 127 properly interpret control sequences, which is how color
130 128 information is given to your terminal.
131 129
132 130 .. _editors:
133 131
134 132 Editor configuration
135 133 ====================
136 134
137 135 IPython can integrate with text editors in a number of different ways:
138 136
139 137 * Editors (such as `(X)Emacs`_, vim_ and TextMate_) can
140 138 send code to IPython for execution.
141 139
142 140 * IPython's ``%edit`` magic command can open an editor of choice to edit
143 141 a code block.
144 142
145 143 The %edit command (and its alias %ed) will invoke the editor set in your
146 144 environment as :envvar:`EDITOR`. If this variable is not set, it will default
147 145 to vi under Linux/Unix and to notepad under Windows. You may want to set this
148 146 variable properly and to a lightweight editor which doesn't take too long to
149 147 start (that is, something other than a new instance of Emacs). This way you
150 148 can edit multi-line code quickly and with the power of a real editor right
151 149 inside IPython.
152 150
153 151 You can also control the editor by setting :attr:`TerminalInteractiveShell.editor`
154 152 in :file:`ipython_config.py`.
155 153
156 154 Vim
157 155 ---
158 156
159 157 Paul Ivanov's `vim-ipython <https://github.com/ivanov/vim-ipython>`_ provides
160 158 powerful IPython integration for vim.
161 159
162 160 .. _emacs:
163 161
164 162 (X)Emacs
165 163 --------
166 164
167 165 If you are a dedicated Emacs user, and want to use Emacs when IPython's
168 166 ``%edit`` magic command is called you should set up the Emacs server so that
169 167 new requests are handled by the original process. This means that almost no
170 168 time is spent in handling the request (assuming an Emacs process is already
171 169 running). For this to work, you need to set your EDITOR environment variable
172 170 to 'emacsclient'. The code below, supplied by Francois Pinard, can then be
173 171 used in your :file:`.emacs` file to enable the server:
174 172
175 173 .. code-block:: common-lisp
176 174
177 175 (defvar server-buffer-clients)
178 176 (when (and (fboundp 'server-start) (string-equal (getenv "TERM") 'xterm))
179 177 (server-start)
180 178 (defun fp-kill-server-with-buffer-routine ()
181 179 (and server-buffer-clients (server-done)))
182 180 (add-hook 'kill-buffer-hook 'fp-kill-server-with-buffer-routine))
183 181
184 182 Thanks to the work of Alexander Schmolck and Prabhu Ramachandran,
185 183 currently (X)Emacs and IPython get along very well in other ways.
186 184
187 185 With (X)EMacs >= 24, You can enable IPython in python-mode with:
188 186
189 187 .. code-block:: common-lisp
190 188
191 189 (require 'python)
192 190 (setq python-shell-interpreter "ipython")
193 191
194 192 .. _`(X)Emacs`: http://www.gnu.org/software/emacs/
195 193 .. _TextMate: http://macromates.com/
196 194 .. _vim: http://www.vim.org/
197 195
198 196 .. _custom_keyboard_shortcuts:
199 197
200 198 Keyboard Shortcuts
201 199 ==================
202 200
203 201 .. versionadded:: 8.11
204 202
205 203 You can modify, disable or modify keyboard shortcuts for IPython Terminal using
206 204 :std:configtrait:`TerminalInteractiveShell.shortcuts` traitlet.
207 205
208 206 The list of shortcuts is available in the Configuring IPython :ref:`terminal-shortcuts-list` section.
209 207
210 208 Advanced configuration
211 209 ----------------------
212 210
213 211 .. versionchanged:: 5.0
214 212
215 213 Creating custom commands requires adding custom code to a
216 214 :ref:`startup file <startup_files>`::
217 215
218 216 from IPython import get_ipython
219 217 from prompt_toolkit.enums import DEFAULT_BUFFER
220 218 from prompt_toolkit.keys import Keys
221 219 from prompt_toolkit.filters import HasFocus, HasSelection, ViInsertMode, EmacsInsertMode
222 220
223 221 ip = get_ipython()
224 222 insert_mode = ViInsertMode() | EmacsInsertMode()
225 223
226 224 def insert_unexpected(event):
227 225 buf = event.current_buffer
228 226 buf.insert_text('The Spanish Inquisition')
229 227 # Register the shortcut if IPython is using prompt_toolkit
230 228 if getattr(ip, 'pt_app', None):
231 229 registry = ip.pt_app.key_bindings
232 230 registry.add_binding(Keys.ControlN,
233 231 filter=(HasFocus(DEFAULT_BUFFER)
234 232 & ~HasSelection()
235 233 & insert_mode))(insert_unexpected)
236 234
237 235
238 236 Here is a second example that bind the key sequence ``j``, ``k`` to switch to
239 237 VI input mode to ``Normal`` when in insert mode::
240 238
241 239 from IPython import get_ipython
242 240 from prompt_toolkit.enums import DEFAULT_BUFFER
243 241 from prompt_toolkit.filters import HasFocus, ViInsertMode
244 242 from prompt_toolkit.key_binding.vi_state import InputMode
245 243
246 244 ip = get_ipython()
247 245
248 246 def switch_to_navigation_mode(event):
249 247 vi_state = event.cli.vi_state
250 248 vi_state.input_mode = InputMode.NAVIGATION
251 249
252 250 if getattr(ip, 'pt_app', None):
253 251 registry = ip.pt_app.key_bindings
254 252 registry.add_binding(u'j',u'k',
255 253 filter=(HasFocus(DEFAULT_BUFFER)
256 254 & ViInsertMode()))(switch_to_navigation_mode)
257 255
258 256 For more information on filters and what you can do with the ``event`` object,
259 257 `see the prompt_toolkit docs
260 258 <https://python-prompt-toolkit.readthedocs.io/en/latest/pages/asking_for_input.html#adding-custom-key-bindings>`__.
261 259
262 260
263 261 Enter to execute
264 262 ----------------
265 263
266 264 In the Terminal IPython shell – which by default uses the ``prompt_toolkit``
267 265 interface, the semantic meaning of pressing the :kbd:`Enter` key can be
268 266 ambiguous. In some case :kbd:`Enter` should execute code, and in others it
269 267 should add a new line. IPython uses heuristics to decide whether to execute or
270 268 insert a new line at cursor position. For example, if we detect that the current
271 269 code is not valid Python, then the user is likely editing code and the right
272 270 behavior is to likely to insert a new line. If the current code is a simple
273 271 statement like `ord('*')`, then the right behavior is likely to execute. Though
274 272 the exact desired semantics often varies from users to users.
275 273
276 274 As the exact behavior of :kbd:`Enter` is ambiguous, it has been special cased
277 275 to allow users to completely configure the behavior they like. Hence you can
278 276 have enter always execute code. If you prefer fancier behavior, you need to get
279 277 your hands dirty and read the ``prompt_toolkit`` and IPython documentation
280 278 though. See :ghpull:`10500`, set the
281 279 ``c.TerminalInteractiveShell.handle_return`` option and get inspiration from the
282 280 following example that only auto-executes the input if it begins with a bang or
283 281 a modulo character (``!`` or ``%``). To use the following code, add it to your
284 282 IPython configuration::
285 283
286 284 def custom_return(shell):
287 285
288 286 """This function is required by the API. It takes a reference to
289 287 the shell, which is the same thing `get_ipython()` evaluates to.
290 288 This function must return a function that handles each keypress
291 289 event. That function, named `handle` here, references `shell`
292 290 by closure."""
293 291
294 292 def handle(event):
295 293
296 294 """This function is called each time `Enter` is pressed,
297 295 and takes a reference to a Prompt Toolkit event object.
298 296 If the current input starts with a bang or modulo, then
299 297 the input is executed, otherwise a newline is entered,
300 298 followed by any spaces needed to auto-indent."""
301 299
302 300 # set up a few handy references to nested items...
303 301
304 302 buffer = event.current_buffer
305 303 document = buffer.document
306 304 text = document.text
307 305
308 306 if text.startswith('!') or text.startswith('%'): # execute the input...
309 307
310 308 buffer.accept_action.validate_and_handle(event.cli, buffer)
311 309
312 310 else: # insert a newline with auto-indentation...
313 311
314 312 if document.line_count > 1: text = text[:document.cursor_position]
315 313 indent = shell.check_complete(text)[1]
316 314 buffer.insert_text('\n' + indent)
317 315
318 316 # if you just wanted a plain newline without any indentation, you
319 317 # could use `buffer.insert_text('\n')` instead of the lines above
320 318
321 319 return handle
322 320
323 321 c.TerminalInteractiveShell.handle_return = custom_return
@@ -1,145 +1,145 b''
1 1 #!/usr/bin/env python
2 2 """An example of how to embed an IPython shell into a running program.
3 3
4 4 Please see the documentation in the IPython.Shell module for more details.
5 5
6 6 The accompanying file embed_class_short.py has quick code fragments for
7 7 embedding which you can cut and paste in your code once you understand how
8 8 things work.
9 9
10 10 The code in this file is deliberately extra-verbose, meant for learning."""
11 11
12 12 # The basics to get you going:
13 13
14 14 # IPython injects get_ipython into builtins, so you can know if you have nested
15 15 # copies running.
16 16
17 17 # Try running this code both at the command line and from inside IPython (with
18 18 # %run example-embed.py)
19 19
20 20 from IPython.terminal.prompts import Prompts, Token
21 from traitlets.config.loader import Config
21 22
22 23 class CustomPrompt(Prompts):
23 24
24 def in_prompt_tokens(self, cli=None):
25 def in_prompt_tokens(self):
25 26
26 return [
27 return [
27 28 (Token.Prompt, 'In <'),
28 29 (Token.PromptNum, str(self.shell.execution_count)),
29 30 (Token.Prompt, '>: '),
30 31 ]
31 32
32 33 def out_prompt_tokens(self):
33 return [
34 return [
34 35 (Token.OutPrompt, 'Out<'),
35 36 (Token.OutPromptNum, str(self.shell.execution_count)),
36 37 (Token.OutPrompt, '>: '),
37 38 ]
38 39
39 40
40 from traitlets.config.loader import Config
41 41 try:
42 42 get_ipython
43 43 except NameError:
44 44 nested = 0
45 45 cfg = Config()
46 46 cfg.TerminalInteractiveShell.prompts_class=CustomPrompt
47 47 else:
48 48 print("Running nested copies of IPython.")
49 49 print("The prompts for the nested copy have been modified")
50 50 cfg = Config()
51 51 nested = 1
52 52
53 53 # First import the embeddable shell class
54 54 from IPython.terminal.embed import InteractiveShellEmbed
55 55
56 56 # Now create an instance of the embeddable shell. The first argument is a
57 57 # string with options exactly as you would type them if you were starting
58 58 # IPython at the system command line. Any parameters you want to define for
59 59 # configuration can thus be specified here.
60 60 ipshell = InteractiveShellEmbed(config=cfg,
61 61 banner1 = 'Dropping into IPython',
62 62 exit_msg = 'Leaving Interpreter, back to program.')
63 63
64 64 # Make a second instance, you can have as many as you want.
65 65 ipshell2 = InteractiveShellEmbed(config=cfg,
66 66 banner1 = 'Second IPython instance.')
67 67
68 68 print('\nHello. This is printed from the main controller program.\n')
69 69
70 70 # You can then call ipshell() anywhere you need it (with an optional
71 71 # message):
72 72 ipshell('***Called from top level. '
73 73 'Hit Ctrl-D to exit interpreter and continue program.\n'
74 74 'Note that if you use %kill_embedded, you can fully deactivate\n'
75 75 'This embedded instance so it will never turn on again')
76 76
77 77 print('\nBack in caller program, moving along...\n')
78 78
79 79 #---------------------------------------------------------------------------
80 80 # More details:
81 81
82 82 # InteractiveShellEmbed instances don't print the standard system banner and
83 83 # messages. The IPython banner (which actually may contain initialization
84 84 # messages) is available as get_ipython().banner in case you want it.
85 85
86 86 # InteractiveShellEmbed instances print the following information every time they
87 87 # start:
88 88
89 89 # - A global startup banner.
90 90
91 91 # - A call-specific header string, which you can use to indicate where in the
92 92 # execution flow the shell is starting.
93 93
94 94 # They also print an exit message every time they exit.
95 95
96 96 # Both the startup banner and the exit message default to None, and can be set
97 97 # either at the instance constructor or at any other time with the
98 98 # by setting the banner and exit_msg attributes.
99 99
100 100 # The shell instance can be also put in 'dummy' mode globally or on a per-call
101 101 # basis. This gives you fine control for debugging without having to change
102 102 # code all over the place.
103 103
104 104 # The code below illustrates all this.
105 105
106 106
107 107 # This is how the global banner and exit_msg can be reset at any point
108 108 ipshell.banner2 = 'Entering interpreter - New Banner'
109 109 ipshell.exit_msg = 'Leaving interpreter - New exit_msg'
110 110
111 111 def foo(m):
112 112 s = 'spam'
113 113 ipshell('***In foo(). Try %whos, or print s or m:')
114 114 print('foo says m = ',m)
115 115
116 116 def bar(n):
117 117 s = 'eggs'
118 118 ipshell('***In bar(). Try %whos, or print s or n:')
119 119 print('bar says n = ',n)
120 120
121 121 # Some calls to the above functions which will trigger IPython:
122 122 print('Main program calling foo("eggs")\n')
123 123 foo('eggs')
124 124
125 125 # The shell can be put in 'dummy' mode where calls to it silently return. This
126 126 # allows you, for example, to globally turn off debugging for a program with a
127 127 # single call.
128 128 ipshell.dummy_mode = True
129 129 print('\nTrying to call IPython which is now "dummy":')
130 130 ipshell()
131 131 print('Nothing happened...')
132 132 # The global 'dummy' mode can still be overridden for a single call
133 133 print('\nOverriding dummy mode manually:')
134 134 ipshell(dummy=False)
135 135
136 136 # Reactivate the IPython shell
137 137 ipshell.dummy_mode = False
138 138
139 139 print('You can even have multiple embedded instances:')
140 140 ipshell2()
141 141
142 142 print('\nMain program calling bar("spam")\n')
143 143 bar('spam')
144 144
145 145 print('Main program finished. Bye!')
@@ -1,26 +1,25 b''
1 1 """This is an example that shows how to create new prompts for IPython
2 2 """
3 3
4 4 from IPython.terminal.prompts import Prompts, Token
5 5 import os
6 6
7 7 class MyPrompt(Prompts):
8 8
9 def in_prompt_tokens(self, cli=None):
10 return [(Token, os.getcwd()),
11 (Token.Prompt, '>>>')]
9 def in_prompt_tokens(self):
10 return [
11 (Token, os.getcwd()),
12 (Token.Prompt, ">>>")
13 ]
14
12 15
13 16 def load_ipython_extension(shell):
14 17 new_prompts = MyPrompt(shell)
15 18 new_prompts.old_prompts = shell.prompts
16 19 shell.prompts = new_prompts
17 20
18 21 def unload_ipython_extension(shell):
19 22 if not hasattr(shell.prompts, 'old_prompts'):
20 23 print("cannot unload")
21 24 else:
22 25 shell.prompts = shell.prompts.old_prompts
23
24
25
26
General Comments 0
You need to be logged in to leave comments. Login now