##// END OF EJS Templates
Remove the "autoedit_syntax" feature....
Matthias Bussonnier -
Show More
@@ -1,214 +1,226 b''
1 1 """Hooks for IPython.
2 2
3 3 In Python, it is possible to overwrite any method of any object if you really
4 4 want to. But IPython exposes a few 'hooks', methods which are *designed* to
5 5 be overwritten by users for customization purposes. This module defines the
6 6 default versions of all such hooks, which get used by IPython if not
7 7 overridden by the user.
8 8
9 9 Hooks are simple functions, but they should be declared with ``self`` as their
10 10 first argument, because when activated they are registered into IPython as
11 11 instance methods. The self argument will be the IPython running instance
12 12 itself, so hooks have full access to the entire IPython object.
13 13
14 14 If you wish to define a new hook and activate it, you can make an :doc:`extension
15 15 </config/extensions/index>` or a :ref:`startup script <startup_files>`. For
16 16 example, you could use a startup file like this::
17 17
18 18 import os
19 19
20 20 def calljed(self,filename, linenum):
21 21 "My editor hook calls the jed editor directly."
22 22 print "Calling my own editor, jed ..."
23 23 if os.system('jed +%d %s' % (linenum,filename)) != 0:
24 24 raise TryNext()
25 25
26 26 def load_ipython_extension(ip):
27 27 ip.set_hook('editor', calljed)
28 28
29 29 """
30 30
31 31 #*****************************************************************************
32 32 # Copyright (C) 2005 Fernando Perez. <fperez@colorado.edu>
33 33 #
34 34 # Distributed under the terms of the BSD License. The full license is in
35 35 # the file COPYING, distributed as part of this software.
36 36 #*****************************************************************************
37 37
38 38 import os
39 39 import subprocess
40 import warnings
40 41 import sys
41 42
42 43 from IPython.core.error import TryNext
43 44
44 45 # List here all the default hooks. For now it's just the editor functions
45 46 # but over time we'll move here all the public API for user-accessible things.
46 47
47 48 __all__ = ['editor', 'fix_error_editor', 'synchronize_with_editor',
48 49 'shutdown_hook', 'late_startup_hook',
49 50 'show_in_pager','pre_prompt_hook',
50 51 'pre_run_code_hook', 'clipboard_get']
51 52
52 53 deprecated = {'pre_run_code_hook': "a callback for the 'pre_execute' or 'pre_run_cell' event",
53 54 'late_startup_hook': "a callback for the 'shell_initialized' event",
54 55 'shutdown_hook': "the atexit module",
55 56 }
56 57
57 58 def editor(self, filename, linenum=None, wait=True):
58 59 """Open the default editor at the given filename and linenumber.
59 60
60 61 This is IPython's default editor hook, you can use it as an example to
61 62 write your own modified one. To set your own editor function as the
62 63 new editor hook, call ip.set_hook('editor',yourfunc)."""
63 64
64 65 # IPython configures a default editor at startup by reading $EDITOR from
65 66 # the environment, and falling back on vi (unix) or notepad (win32).
66 67 editor = self.editor
67 68
68 69 # marker for at which line to open the file (for existing objects)
69 70 if linenum is None or editor=='notepad':
70 71 linemark = ''
71 72 else:
72 73 linemark = '+%d' % int(linenum)
73 74
74 75 # Enclose in quotes if necessary and legal
75 76 if ' ' in editor and os.path.isfile(editor) and editor[0] != '"':
76 77 editor = '"%s"' % editor
77 78
78 79 # Call the actual editor
79 80 proc = subprocess.Popen('%s %s %s' % (editor, linemark, filename),
80 81 shell=True)
81 82 if wait and proc.wait() != 0:
82 83 raise TryNext()
83 84
84 85 import tempfile
85 86 def fix_error_editor(self,filename,linenum,column,msg):
86 """Open the editor at the given filename, linenumber, column and
87 """DEPRECATED
88
89 Open the editor at the given filename, linenumber, column and
87 90 show an error message. This is used for correcting syntax errors.
88 91 The current implementation only has special support for the VIM editor,
89 92 and falls back on the 'editor' hook if VIM is not used.
90 93
91 Call ip.set_hook('fix_error_editor',youfunc) to use your own function,
94 Call ip.set_hook('fix_error_editor',yourfunc) to use your own function,
92 95 """
96
97 warnings.warn("""
98 `fix_error_editor` is pending deprecation as of IPython 5.0 and will be removed
99 in future versions. It appears to be used only for automatically fixing syntax
100 error that has been broken for a few years and has thus been removed. If you
101 happend to use this function and still need it please make your voice heard on
102 the mailing list ipython-dev@scipy.org , or on the GitHub Issue tracker:
103 https://github.com/ipython/ipython/issues/9649 """, UserWarning)
104
93 105 def vim_quickfix_file():
94 106 t = tempfile.NamedTemporaryFile()
95 107 t.write('%s:%d:%d:%s\n' % (filename,linenum,column,msg))
96 108 t.flush()
97 109 return t
98 110 if os.path.basename(self.editor) != 'vim':
99 111 self.hooks.editor(filename,linenum)
100 112 return
101 113 t = vim_quickfix_file()
102 114 try:
103 115 if os.system('vim --cmd "set errorformat=%f:%l:%c:%m" -q ' + t.name):
104 116 raise TryNext()
105 117 finally:
106 118 t.close()
107 119
108 120
109 121 def synchronize_with_editor(self, filename, linenum, column):
110 122 pass
111 123
112 124
113 125 class CommandChainDispatcher:
114 126 """ Dispatch calls to a chain of commands until some func can handle it
115 127
116 128 Usage: instantiate, execute "add" to add commands (with optional
117 129 priority), execute normally via f() calling mechanism.
118 130
119 131 """
120 132 def __init__(self,commands=None):
121 133 if commands is None:
122 134 self.chain = []
123 135 else:
124 136 self.chain = commands
125 137
126 138
127 139 def __call__(self,*args, **kw):
128 140 """ Command chain is called just like normal func.
129 141
130 142 This will call all funcs in chain with the same args as were given to
131 143 this function, and return the result of first func that didn't raise
132 144 TryNext"""
133 145 last_exc = TryNext()
134 146 for prio,cmd in self.chain:
135 147 #print "prio",prio,"cmd",cmd #dbg
136 148 try:
137 149 return cmd(*args, **kw)
138 150 except TryNext as exc:
139 151 last_exc = exc
140 152 # if no function will accept it, raise TryNext up to the caller
141 153 raise last_exc
142 154
143 155 def __str__(self):
144 156 return str(self.chain)
145 157
146 158 def add(self, func, priority=0):
147 159 """ Add a func to the cmd chain with given priority """
148 160 self.chain.append((priority, func))
149 161 self.chain.sort(key=lambda x: x[0])
150 162
151 163 def __iter__(self):
152 164 """ Return all objects in chain.
153 165
154 166 Handy if the objects are not callable.
155 167 """
156 168 return iter(self.chain)
157 169
158 170
159 171 def shutdown_hook(self):
160 172 """ default shutdown hook
161 173
162 174 Typically, shotdown hooks should raise TryNext so all shutdown ops are done
163 175 """
164 176
165 177 #print "default shutdown hook ok" # dbg
166 178 return
167 179
168 180
169 181 def late_startup_hook(self):
170 182 """ Executed after ipython has been constructed and configured
171 183
172 184 """
173 185 #print "default startup hook ok" # dbg
174 186
175 187
176 188 def show_in_pager(self, data, start, screen_lines):
177 189 """ Run a string through pager """
178 190 # raising TryNext here will use the default paging functionality
179 191 raise TryNext
180 192
181 193
182 194 def pre_prompt_hook(self):
183 195 """ Run before displaying the next prompt
184 196
185 197 Use this e.g. to display output from asynchronous operations (in order
186 198 to not mess up text entry)
187 199 """
188 200
189 201 return None
190 202
191 203
192 204 def pre_run_code_hook(self):
193 205 """ Executed before running the (prefiltered) code in IPython """
194 206 return None
195 207
196 208
197 209 def clipboard_get(self):
198 210 """ Get text from the clipboard.
199 211 """
200 212 from IPython.lib.clipboard import (
201 213 osx_clipboard_get, tkinter_clipboard_get,
202 214 win32_clipboard_get
203 215 )
204 216 if sys.platform == 'win32':
205 217 chain = [win32_clipboard_get, tkinter_clipboard_get]
206 218 elif sys.platform == 'darwin':
207 219 chain = [osx_clipboard_get, tkinter_clipboard_get]
208 220 else:
209 221 chain = [tkinter_clipboard_get]
210 222 dispatcher = CommandChainDispatcher()
211 223 for func in chain:
212 224 dispatcher.add(func)
213 225 text = dispatcher()
214 226 return text
@@ -1,598 +1,532 b''
1 1 """IPython terminal interface using prompt_toolkit"""
2 2 from __future__ import print_function
3 3
4 4 import os
5 5 import sys
6 6 import signal
7 7 from warnings import warn
8 8
9 9 from IPython.core.error import TryNext
10 10 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
11 11 from IPython.utils.py3compat import PY3, cast_unicode_py2, input
12 12 from IPython.utils.terminal import toggle_set_term_title, set_term_title
13 13 from IPython.utils.process import abbrev_cwd
14 14 from traitlets import Bool, Unicode, Dict, Integer, observe, Instance, Type, default, Enum
15 15
16 16 from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER, EditingMode
17 17 from prompt_toolkit.filters import (HasFocus, HasSelection, Condition,
18 18 ViInsertMode, EmacsInsertMode, IsDone, HasCompletions)
19 19 from prompt_toolkit.filters.cli import ViMode
20 20 from prompt_toolkit.history import InMemoryHistory
21 21 from prompt_toolkit.shortcuts import create_prompt_application, create_eventloop, create_prompt_layout
22 22 from prompt_toolkit.interface import CommandLineInterface
23 23 from prompt_toolkit.key_binding.manager import KeyBindingManager
24 24 from prompt_toolkit.keys import Keys
25 25 from prompt_toolkit.layout.processors import ConditionalProcessor, HighlightMatchingBracketProcessor
26 26 from prompt_toolkit.styles import PygmentsStyle, DynamicStyle
27 27 from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline
28 28
29 29 from pygments.styles import get_style_by_name, get_all_styles
30 30 from pygments.token import Token
31 31
32 32 from .debugger import TerminalPdb, Pdb
33 33 from .magics import TerminalMagics
34 34 from .pt_inputhooks import get_inputhook_func
35 35 from .prompts import Prompts, ClassicPrompts, RichPromptDisplayHook
36 36 from .ptutils import IPythonPTCompleter, IPythonPTLexer
37 37
38 38 DISPLAY_BANNER_DEPRECATED = object()
39 39
40 40
41 41 def get_default_editor():
42 42 try:
43 43 ed = os.environ['EDITOR']
44 44 if not PY3:
45 45 ed = ed.decode()
46 46 return ed
47 47 except KeyError:
48 48 pass
49 49 except UnicodeError:
50 50 warn("$EDITOR environment variable is not pure ASCII. Using platform "
51 51 "default editor.")
52 52
53 53 if os.name == 'posix':
54 54 return 'vi' # the only one guaranteed to be there!
55 55 else:
56 56 return 'notepad' # same in Windows!
57 57
58 58
59 59 if sys.stdin and sys.stdout and sys.stderr:
60 60 _is_tty = (sys.stdin.isatty()) and (sys.stdout.isatty()) and (sys.stderr.isatty())
61 61 else:
62 62 _is_tty = False
63 63
64 64
65 65 _use_simple_prompt = ('IPY_TEST_SIMPLE_PROMPT' in os.environ) or (not _is_tty)
66 66
67 67 class TerminalInteractiveShell(InteractiveShell):
68 68 colors_force = True
69 69
70 70 space_for_menu = Integer(6, help='Number of line at the bottom of the screen '
71 71 'to reserve for the completion menu'
72 72 ).tag(config=True)
73 73
74 74 def _space_for_menu_changed(self, old, new):
75 75 self._update_layout()
76 76
77 77 pt_cli = None
78 78 debugger_history = None
79 79
80 80 simple_prompt = Bool(_use_simple_prompt,
81 81 help="""Use `raw_input` for the REPL, without completion, multiline input, and prompt colors.
82 82
83 83 Useful when controlling IPython as a subprocess, and piping STDIN/OUT/ERR. Known usage are:
84 84 IPython own testing machinery, and emacs inferior-shell integration through elpy.
85 85
86 86 This mode default to `True` if the `IPY_TEST_SIMPLE_PROMPT`
87 87 environment variable is set, or the current terminal is not a tty.
88 88
89 89 """
90 90 ).tag(config=True)
91 91
92 92 @property
93 93 def debugger_cls(self):
94 94 return Pdb if self.simple_prompt else TerminalPdb
95 95
96 autoedit_syntax = Bool(False,
97 help="auto editing of files with syntax errors.",
98 ).tag(config=True)
99
100
101 96 confirm_exit = Bool(True,
102 97 help="""
103 98 Set to confirm when you try to exit IPython with an EOF (Control-D
104 99 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
105 100 you can force a direct exit without any confirmation.""",
106 101 ).tag(config=True)
107 102
108 103 editing_mode = Unicode('emacs',
109 104 help="Shortcut style to use at the prompt. 'vi' or 'emacs'.",
110 105 ).tag(config=True)
111 106
112 107 mouse_support = Bool(False,
113 108 help="Enable mouse support in the prompt"
114 109 ).tag(config=True)
115 110
116 111 highlighting_style = Unicode('default',
117 112 help="The name of a Pygments style to use for syntax highlighting: \n %s" % ', '.join(get_all_styles())
118 113 ).tag(config=True)
119 114
120 115
121 116 @observe('highlighting_style')
122 117 def _highlighting_style_changed(self, change):
123 118 self._style = self._make_style_from_name(self.highlighting_style)
124 119
125 120 highlighting_style_overrides = Dict(
126 121 help="Override highlighting format for specific tokens"
127 122 ).tag(config=True)
128 123
129 124 editor = Unicode(get_default_editor(),
130 125 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
131 126 ).tag(config=True)
132 127
133 128 prompts_class = Type(Prompts, help='Class used to generate Prompt token for prompt_toolkit').tag(config=True)
134 129
135 130 prompts = Instance(Prompts)
136 131
137 132 @default('prompts')
138 133 def _prompts_default(self):
139 134 return self.prompts_class(self)
140 135
141 136 @observe('prompts')
142 137 def _(self, change):
143 138 self._update_layout()
144 139
145 140 @default('displayhook_class')
146 141 def _displayhook_class_default(self):
147 142 return RichPromptDisplayHook
148 143
149 144 term_title = Bool(True,
150 145 help="Automatically set the terminal title"
151 146 ).tag(config=True)
152 147
153 148 # Leaving that for beta/rc tester, shoudl remove for 5.0.0 final.
154 149 display_completions_in_columns = Bool(None,
155 150 help="DEPRECATED", allow_none=True
156 151 ).tag(config=True)
157 152
158 153 @observe('display_completions_in_columns')
159 154 def _display_completions_in_columns_changed(self, new):
160 155 raise DeprecationWarning("The `display_completions_in_columns` Boolean has been replaced by the enum `display_completions`"
161 156 "with the following acceptable value: 'column', 'multicolumn','readlinelike'. ")
162 157
163 158 display_completions = Enum(('column', 'multicolumn','readlinelike'), default_value='multicolumn').tag(config=True)
164 159
165 160 highlight_matching_brackets = Bool(True,
166 161 help="Highlight matching brackets .",
167 162 ).tag(config=True)
168 163
169 164 @observe('term_title')
170 165 def init_term_title(self, change=None):
171 166 # Enable or disable the terminal title.
172 167 if self.term_title:
173 168 toggle_set_term_title(True)
174 169 set_term_title('IPython: ' + abbrev_cwd())
175 170 else:
176 171 toggle_set_term_title(False)
177 172
178 173 def init_display_formatter(self):
179 174 super(TerminalInteractiveShell, self).init_display_formatter()
180 175 # terminal only supports plain text
181 176 self.display_formatter.active_types = ['text/plain']
182 177
183 178 def init_prompt_toolkit_cli(self):
184 179 self._app = None
185 180 if self.simple_prompt:
186 181 # Fall back to plain non-interactive output for tests.
187 182 # This is very limited, and only accepts a single line.
188 183 def prompt():
189 184 return cast_unicode_py2(input('In [%d]: ' % self.execution_count))
190 185 self.prompt_for_code = prompt
191 186 return
192 187
193 188 kbmanager = KeyBindingManager.for_prompt()
194 189 insert_mode = ViInsertMode() | EmacsInsertMode()
195 190 # Ctrl+J == Enter, seemingly
196 191 @kbmanager.registry.add_binding(Keys.ControlJ,
197 192 filter=(HasFocus(DEFAULT_BUFFER)
198 193 & ~HasSelection()
199 194 & insert_mode
200 195 ))
201 196 def _(event):
202 197 b = event.current_buffer
203 198 d = b.document
204 199
205 200 if b.complete_state:
206 201 cc = b.complete_state.current_completion
207 202 if cc:
208 203 b.apply_completion(cc)
209 204 else:
210 205 b.cancel_completion()
211 206 return
212 207
213 208 if not (d.on_last_line or d.cursor_position_row >= d.line_count
214 209 - d.empty_line_count_at_the_end()):
215 210 b.newline()
216 211 return
217 212
218 213 status, indent = self.input_splitter.check_complete(d.text + '\n')
219 214
220 215 if (status != 'incomplete') and b.accept_action.is_returnable:
221 216 b.accept_action.validate_and_handle(event.cli, b)
222 217 else:
223 218 b.insert_text('\n' + (' ' * (indent or 0)))
224 219
225 220 @kbmanager.registry.add_binding(Keys.ControlP, filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER)))
226 221 def _previous_history_or_previous_completion(event):
227 222 """
228 223 Control-P in vi edit mode on readline is history next, unlike default prompt toolkit.
229 224
230 225 If completer is open this still select previous completion.
231 226 """
232 227 event.current_buffer.auto_up()
233 228
234 229 @kbmanager.registry.add_binding(Keys.ControlN, filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER)))
235 230 def _next_history_or_next_completion(event):
236 231 """
237 232 Control-N in vi edit mode on readline is history previous, unlike default prompt toolkit.
238 233
239 234 If completer is open this still select next completion.
240 235 """
241 236 event.current_buffer.auto_down()
242 237
243 238 @kbmanager.registry.add_binding(Keys.ControlG, filter=(
244 239 HasFocus(DEFAULT_BUFFER) & HasCompletions()
245 240 ))
246 241 def _dismiss_completion(event):
247 242 b = event.current_buffer
248 243 if b.complete_state:
249 244 b.cancel_completion()
250 245
251 246 @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER))
252 247 def _reset_buffer(event):
253 248 b = event.current_buffer
254 249 if b.complete_state:
255 250 b.cancel_completion()
256 251 else:
257 252 b.reset()
258 253
259 254 @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER))
260 255 def _reset_search_buffer(event):
261 256 if event.current_buffer.document.text:
262 257 event.current_buffer.reset()
263 258 else:
264 259 event.cli.push_focus(DEFAULT_BUFFER)
265 260
266 261 supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP'))
267 262
268 263 @kbmanager.registry.add_binding(Keys.ControlZ, filter=supports_suspend)
269 264 def _suspend_to_bg(event):
270 265 event.cli.suspend_to_background()
271 266
272 267 @Condition
273 268 def cursor_in_leading_ws(cli):
274 269 before = cli.application.buffer.document.current_line_before_cursor
275 270 return (not before) or before.isspace()
276 271
277 272 # Ctrl+I == Tab
278 273 @kbmanager.registry.add_binding(Keys.ControlI,
279 274 filter=(HasFocus(DEFAULT_BUFFER)
280 275 & ~HasSelection()
281 276 & insert_mode
282 277 & cursor_in_leading_ws
283 278 ))
284 279 def _indent_buffer(event):
285 280 event.current_buffer.insert_text(' ' * 4)
286 281
287 282
288 283 if self.display_completions == 'readlinelike':
289 284 @kbmanager.registry.add_binding(Keys.ControlI,
290 285 filter=(HasFocus(DEFAULT_BUFFER)
291 286 & ~HasSelection()
292 287 & insert_mode
293 288 & ~cursor_in_leading_ws
294 289 ))
295 290 def _disaply_compl(ev):
296 291 display_completions_like_readline(ev)
297 292
298 293
299 294 if sys.platform == 'win32':
300 295 from IPython.lib.clipboard import (ClipboardEmpty,
301 296 win32_clipboard_get, tkinter_clipboard_get)
302 297 @kbmanager.registry.add_binding(Keys.ControlV,
303 298 filter=(HasFocus(DEFAULT_BUFFER) & ~ViMode()))
304 299 def _paste(event):
305 300 try:
306 301 text = win32_clipboard_get()
307 302 except TryNext:
308 303 try:
309 304 text = tkinter_clipboard_get()
310 305 except (TryNext, ClipboardEmpty):
311 306 return
312 307 except ClipboardEmpty:
313 308 return
314 309 event.current_buffer.insert_text(text.replace('\t', ' ' * 4))
315 310
316 311 # Pre-populate history from IPython's history database
317 312 history = InMemoryHistory()
318 313 last_cell = u""
319 314 for __, ___, cell in self.history_manager.get_tail(self.history_load_length,
320 315 include_latest=True):
321 316 # Ignore blank lines and consecutive duplicates
322 317 cell = cell.rstrip()
323 318 if cell and (cell != last_cell):
324 319 history.append(cell)
325 320
326 321 self._style = self._make_style_from_name(self.highlighting_style)
327 322 style = DynamicStyle(lambda: self._style)
328 323
329 324 editing_mode = getattr(EditingMode, self.editing_mode.upper())
330 325
331 326 self._app = create_prompt_application(
332 327 editing_mode=editing_mode,
333 328 key_bindings_registry=kbmanager.registry,
334 329 history=history,
335 330 completer=IPythonPTCompleter(self.Completer),
336 331 enable_history_search=True,
337 332 style=style,
338 333 mouse_support=self.mouse_support,
339 334 **self._layout_options()
340 335 )
341 336 self._eventloop = create_eventloop(self.inputhook)
342 337 self.pt_cli = CommandLineInterface(self._app, eventloop=self._eventloop)
343 338
344 339 def _make_style_from_name(self, name):
345 340 """
346 341 Small wrapper that make an IPython compatible style from a style name
347 342
348 343 We need that to add style for prompt ... etc.
349 344 """
350 345 style_cls = get_style_by_name(name)
351 346 style_overrides = {
352 347 Token.Prompt: '#009900',
353 348 Token.PromptNum: '#00ff00 bold',
354 349 Token.OutPrompt: '#990000',
355 350 Token.OutPromptNum: '#ff0000 bold',
356 351 }
357 352 if name == 'default':
358 353 style_cls = get_style_by_name('default')
359 354 # The default theme needs to be visible on both a dark background
360 355 # and a light background, because we can't tell what the terminal
361 356 # looks like. These tweaks to the default theme help with that.
362 357 style_overrides.update({
363 358 Token.Number: '#007700',
364 359 Token.Operator: 'noinherit',
365 360 Token.String: '#BB6622',
366 361 Token.Name.Function: '#2080D0',
367 362 Token.Name.Class: 'bold #2080D0',
368 363 Token.Name.Namespace: 'bold #2080D0',
369 364 })
370 365 style_overrides.update(self.highlighting_style_overrides)
371 366 style = PygmentsStyle.from_defaults(pygments_style_cls=style_cls,
372 367 style_dict=style_overrides)
373 368
374 369 return style
375 370
376 371 def _layout_options(self):
377 372 """
378 373 Return the current layout option for the current Terminal InteractiveShell
379 374 """
380 375 return {
381 376 'lexer':IPythonPTLexer(),
382 377 'reserve_space_for_menu':self.space_for_menu,
383 378 'get_prompt_tokens':self.prompts.in_prompt_tokens,
384 379 'get_continuation_tokens':self.prompts.continuation_prompt_tokens,
385 380 'multiline':True,
386 381 'display_completions_in_columns': (self.display_completions == 'multicolumn'),
387 382
388 383 # Highlight matching brackets, but only when this setting is
389 384 # enabled, and only when the DEFAULT_BUFFER has the focus.
390 385 'extra_input_processors': [ConditionalProcessor(
391 386 processor=HighlightMatchingBracketProcessor(chars='[](){}'),
392 387 filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() &
393 388 Condition(lambda cli: self.highlight_matching_brackets))],
394 389 }
395 390
396 391 def _update_layout(self):
397 392 """
398 393 Ask for a re computation of the application layout, if for example ,
399 394 some configuration options have changed.
400 395 """
401 396 if getattr(self, '._app', None):
402 397 self._app.layout = create_prompt_layout(**self._layout_options())
403 398
404 399 def prompt_for_code(self):
405 400 document = self.pt_cli.run(
406 401 pre_run=self.pre_prompt, reset_current_buffer=True)
407 402 return document.text
408 403
409 404 def init_io(self):
410 405 if sys.platform not in {'win32', 'cli'}:
411 406 return
412 407
413 408 import win_unicode_console
414 409 import colorama
415 410
416 411 win_unicode_console.enable()
417 412 colorama.init()
418 413
419 414 # For some reason we make these wrappers around stdout/stderr.
420 415 # For now, we need to reset them so all output gets coloured.
421 416 # https://github.com/ipython/ipython/issues/8669
422 417 from IPython.utils import io
423 418 io.stdout = io.IOStream(sys.stdout)
424 419 io.stderr = io.IOStream(sys.stderr)
425 420
426 421 def init_magics(self):
427 422 super(TerminalInteractiveShell, self).init_magics()
428 423 self.register_magics(TerminalMagics)
429 424
430 425 def init_alias(self):
431 426 # The parent class defines aliases that can be safely used with any
432 427 # frontend.
433 428 super(TerminalInteractiveShell, self).init_alias()
434 429
435 430 # Now define aliases that only make sense on the terminal, because they
436 431 # need direct access to the console in a way that we can't emulate in
437 432 # GUI or web frontend
438 433 if os.name == 'posix':
439 434 for cmd in ['clear', 'more', 'less', 'man']:
440 435 self.alias_manager.soft_define_alias(cmd, cmd)
441 436
442 437
443 438 def __init__(self, *args, **kwargs):
444 439 super(TerminalInteractiveShell, self).__init__(*args, **kwargs)
445 440 self.init_prompt_toolkit_cli()
446 441 self.init_term_title()
447 442 self.keep_running = True
448 443
449 444 self.debugger_history = InMemoryHistory()
450 445
451 446 def ask_exit(self):
452 447 self.keep_running = False
453 448
454 449 rl_next_input = None
455 450
456 451 def pre_prompt(self):
457 452 if self.rl_next_input:
458 453 self.pt_cli.application.buffer.text = cast_unicode_py2(self.rl_next_input)
459 454 self.rl_next_input = None
460 455
461 456 def interact(self, display_banner=DISPLAY_BANNER_DEPRECATED):
462 457
463 458 if display_banner is not DISPLAY_BANNER_DEPRECATED:
464 459 warn('interact `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2)
465 460
466 461 while self.keep_running:
467 462 print(self.separate_in, end='')
468 463
469 464 try:
470 465 code = self.prompt_for_code()
471 466 except EOFError:
472 467 if (not self.confirm_exit) \
473 468 or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
474 469 self.ask_exit()
475 470
476 471 else:
477 472 if code:
478 473 self.run_cell(code, store_history=True)
479 if self.autoedit_syntax and self.SyntaxTB.last_syntax_error:
480 self.edit_syntax_error()
481 474
482 475 def mainloop(self, display_banner=DISPLAY_BANNER_DEPRECATED):
483 476 # An extra layer of protection in case someone mashing Ctrl-C breaks
484 477 # out of our internal code.
485 478 if display_banner is not DISPLAY_BANNER_DEPRECATED:
486 479 warn('mainloop `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2)
487 480 while True:
488 481 try:
489 482 self.interact()
490 483 break
491 484 except KeyboardInterrupt:
492 485 print("\nKeyboardInterrupt escaped interact()\n")
493 486
494 487 if hasattr(self, '_eventloop'):
495 488 self._eventloop.close()
496 489
497 490 _inputhook = None
498 491 def inputhook(self, context):
499 492 if self._inputhook is not None:
500 493 self._inputhook(context)
501 494
502 495 def enable_gui(self, gui=None):
503 496 if gui:
504 497 self._inputhook = get_inputhook_func(gui)
505 498 else:
506 499 self._inputhook = None
507 500
508 # Methods to support auto-editing of SyntaxErrors:
509
510 def edit_syntax_error(self):
511 """The bottom half of the syntax error handler called in the main loop.
512
513 Loop until syntax error is fixed or user cancels.
514 """
515
516 while self.SyntaxTB.last_syntax_error:
517 # copy and clear last_syntax_error
518 err = self.SyntaxTB.clear_err_state()
519 if not self._should_recompile(err):
520 return
521 try:
522 # may set last_syntax_error again if a SyntaxError is raised
523 self.safe_execfile(err.filename, self.user_ns)
524 except:
525 self.showtraceback()
526 else:
527 try:
528 with open(err.filename) as f:
529 # This should be inside a display_trap block and I
530 # think it is.
531 sys.displayhook(f.read())
532 except:
533 self.showtraceback()
534
535 def _should_recompile(self, e):
536 """Utility routine for edit_syntax_error"""
537
538 if e.filename in ('<ipython console>', '<input>', '<string>',
539 '<console>', '<BackgroundJob compilation>',
540 None):
541 return False
542 try:
543 if (self.autoedit_syntax and
544 not self.ask_yes_no(
545 'Return to editor to correct syntax error? '
546 '[Y/n] ', 'y')):
547 return False
548 except EOFError:
549 return False
550
551 def int0(x):
552 try:
553 return int(x)
554 except TypeError:
555 return 0
556
557 # always pass integer line and offset values to editor hook
558 try:
559 self.hooks.fix_error_editor(e.filename,
560 int0(e.lineno), int0(e.offset),
561 e.msg)
562 except TryNext:
563 warn('Could not open editor')
564 return False
565 return True
566
567 501 # Run !system commands directly, not through pipes, so terminal programs
568 502 # work correctly.
569 503 system = InteractiveShell.system_raw
570 504
571 505 def auto_rewrite_input(self, cmd):
572 506 """Overridden from the parent class to use fancy rewriting prompt"""
573 507 if not self.show_rewritten_input:
574 508 return
575 509
576 510 tokens = self.prompts.rewrite_prompt_tokens()
577 511 if self.pt_cli:
578 512 self.pt_cli.print_tokens(tokens)
579 513 print(cmd)
580 514 else:
581 515 prompt = ''.join(s for t, s in tokens)
582 516 print(prompt, cmd, sep='')
583 517
584 518 _prompts_before = None
585 519 def switch_doctest_mode(self, mode):
586 520 """Switch prompts to classic for %doctest_mode"""
587 521 if mode:
588 522 self._prompts_before = self.prompts
589 523 self.prompts = ClassicPrompts(self)
590 524 elif self._prompts_before:
591 525 self.prompts = self._prompts_before
592 526 self._prompts_before = None
593 527
594 528
595 529 InteractiveShellABC.register(TerminalInteractiveShell)
596 530
597 531 if __name__ == '__main__':
598 532 TerminalInteractiveShell.instance().interact()
@@ -1,130 +1,156 b''
1 1 ============
2 2 5.x Series
3 3 ============
4 4
5 5 IPython 5.0
6 6 ===========
7 7
8 8 Released June, 2016
9 9
10 10 IPython 5.0 now uses `prompt-toolkit` for the command line interface, thus
11 11 allowing real multi-line editing and syntactic coloration as you type.
12 12
13 13
14 14 When using IPython as a subprocess, like for emacs inferior-shell, IPython can
15 15 be started with --simple-prompt flag, which will bypass the prompt_toolkit
16 16 input layer. In this mode completion, prompt color and many other features are
17 17 disabled.
18 18
19 19 Backwards incompatible changes
20 20 ------------------------------
21 21
22 22
23 23 The `install_ext magic` function which was deprecated since 4.0 have now been deleted.
24 24 You can still distribute and install extension as packages on PyPI.
25 25
26 26 Update IPython event triggering to ensure callback registration and
27 27 unregistration only affects the set of callbacks the *next* time that event is
28 28 triggered. See :ghissue:`9447` and :ghpull:`9453`.
29 29
30 30 This is a change to the existing semantics, wherein one callback registering a
31 31 second callback when triggered for an event would previously be invoked for
32 32 that same event.
33 33
34 34 Integration with pydb has been removed since pydb development has been stopped
35 35 since 2012, and pydb is not installable from PyPI
36 36
37 37
38 38
39 39 Replacement of readline in TerminalInteractiveShell and PDB
40 40 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
41 41
42 42 IPython 5.0 now uses ``prompt_toolkit``. The
43 43 ``IPython.terminal.interactiveshell.TerminalInteractiveShell`` now uses
44 44 ``prompt_toolkit``. It is an almost complete rewrite, so many settings have
45 45 thus changed or disappeared. The class keep the same name to avoid breaking
46 46 user configuration for the options which names is unchanged.
47 47
48 48 The usage of ``prompt_toolkit`` is accompanied by a complete removal of all
49 49 code, using ``readline``. A particular effect of not using `readline` anymore
50 50 is that `.inputrc` settings are note effective anymore. Options having similar
51 51 effects have likely been replaced by a configuration option on IPython itself
52 52 (e.g: vi input mode).
53 53
54 54 The `PromptManager` class have been removed, and the prompt machinery simplified.
55 55 See `TerminalInteractiveShell.prompts` configurable for how to setup your prompts.
56 56
57 57 .. note::
58 58
59 59 During developement and beta cycle, ``TerminalInteractiveShell`` was
60 60 temporarly moved to ``IPtyhon.terminal.ptshell``.
61 61
62 62
63 63 Most of the above remarks also affect `IPython.core.debugger.Pdb`, the `%debug`
64 64 and `%pdb` magic which do not use readline anymore either.
65 65
66 66
67
68
69 67 Provisional Changes
70 68 -------------------
71 69
72 70 Provisional changes are in experimental functionality that may, or may not make
73 71 it to future version of IPython, and which API may change without warnings.
74 72 Activating these feature and using these API is at your own risk, and may have
75 73 security implication for your system, especially if used with the Jupyter notebook,
76 74
77 75 When running via the Jupyter notebook interfaces, or other compatible client,
78 76 you can enable rich documentation experimental functionality:
79 77
80 78 When the ``docrepr`` package is installed setting the boolean flag
81 79 ``InteractiveShell.sphinxify_docstring`` to ``True``, will process the various
82 80 object through sphinx before displaying them (see the ``docrepr`` package
83 81 documentation for more information.
84 82
85 83 You need to also enable the IPython pager display rich HTML representation
86 84 using the ``InteractiveShell.enable_html_pager`` boolean configuration option.
87 85 As usual you can set these configuration options globally in your configuration
88 86 files, alternatively you can turn them on dynamically using the following
89 87 snippet:
90 88
91 89 .. code-block:: python
92 90
93 91 ip = get_ipython()
94 92 ip.sphinxify_docstring = True
95 93 ip.enable_html_pager = True
96 94
97 95 You can test the effect of various combinations of the above configuration in
98 96 the Jupyter notebook, with things example like :
99 97
100 98 .. code-block:: python
101 99
102 100 import numpy as np
103 101 np.histogram?
104 102
105 103 This is part of an effort to make Documentation in Python richer and provide in
106 104 the long term if possible dynamic examples that can contain math, images,
107 105 widgets... As stated above this is nightly experimental feature with a lot of
108 106 (fun) problem to solve. We would be happy to get your feedback and expertise on
109 107 it.
110 108
111 109
110 Removed Feature
111 ---------------
112
113 - ``TerminalInteractiveShell.autoedit_syntax`` Has been broken for many years now
114 apparently. It has been removed.
115
116
117 Deprecated Features
118 -------------------
119
120 Some deprecated feature, don't forget to enable `DeprecationWarning` as error
121 of you are using IPython in Continuous Integration setup or in your testing in general:
122
123 .. code::
124 :python:
125
126 import warnings
127 warnings.filterwarnings('error', '.*', DeprecationWarning, module='yourmodule.*')
128
129
130 - `hooks.fix_error_editor` seem to be unused and is pending deprecation.
131 - `IPython/core/excolors.py:ExceptionColors` is deprecated.
132 - `IPython.core.InteractiveShell:write()` is deprecated, use `sys.stdout` instead.
133 - `IPython.core.InteractiveShell:write_err()` is deprecated, use `sys.stderr` instead.
134 - The `formatter` keyword argument to `Inspector.info` in `IPython.core.oinspec` has now no effects.
135 - The `global_ns` keyword argument of IPython Embed was deprecated, and will now have no effect. Use `module` keyword argument instead.
136
137
112 138 Known Issues:
113 139 -------------
114 140
115 141 - ``<Esc>`` Key does not dismiss the completer and does not clear the current
116 142 buffer. This is an on purpose modification due to current technical
117 143 limitation. Cf :ghpull:`9572`. Escape the control character which is used
118 144 for other shortcut, and there is no practical way to distinguish. Use Ctr-G
119 145 or Ctrl-C as an alternative.
120 146
121 147 - Cannot use ``Shift-Enter`` and ``Ctrl-Enter`` to submit code in terminal. cf
122 148 :ghissue:`9587` and :ghissue:`9401`. In terminal there is no practical way to
123 149 distinguish these key sequences from a normal new line return.
124 150
125 151 - ``PageUp`` and ``pageDown`` do not move through completion menu.
126 152
127 153 - Color styles might not adapt to terminal emulator themes. This will need new
128 154 version of Pygments to be released, and can be mitigated with custom themes.
129 155
130 156
General Comments 0
You need to be logged in to leave comments. Login now