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