##// END OF EJS Templates
more updates to WN
Matthias Bussonnier -
Show More
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
@@ -1,371 +1,371 b''
1 """
1 """
2 Module to define and register Terminal IPython shortcuts with
2 Module to define and register Terminal IPython shortcuts with
3 :mod:`prompt_toolkit`
3 :mod:`prompt_toolkit`
4 """
4 """
5
5
6 # Copyright (c) IPython Development Team.
6 # Copyright (c) IPython Development Team.
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8
8
9 import warnings
9 import warnings
10 import signal
10 import signal
11 import sys
11 import sys
12 import re
12 import re
13 from typing import Callable
13 from typing import Callable
14
14
15
15
16 from prompt_toolkit.application.current import get_app
16 from prompt_toolkit.application.current import get_app
17 from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER
17 from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER
18 from prompt_toolkit.filters import (has_focus, has_selection, Condition,
18 from prompt_toolkit.filters import (has_focus, has_selection, Condition,
19 vi_insert_mode, emacs_insert_mode, has_completions, vi_mode)
19 vi_insert_mode, emacs_insert_mode, has_completions, vi_mode)
20 from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline
20 from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline
21 from prompt_toolkit.key_binding import KeyBindings
21 from prompt_toolkit.key_binding import KeyBindings
22 from prompt_toolkit.key_binding.bindings import named_commands as nc
22 from prompt_toolkit.key_binding.bindings import named_commands as nc
23 from prompt_toolkit.key_binding.vi_state import InputMode, ViState
23 from prompt_toolkit.key_binding.vi_state import InputMode, ViState
24
24
25 from IPython.utils.decorators import undoc
25 from IPython.utils.decorators import undoc
26
26
27 @undoc
27 @undoc
28 @Condition
28 @Condition
29 def cursor_in_leading_ws():
29 def cursor_in_leading_ws():
30 before = get_app().current_buffer.document.current_line_before_cursor
30 before = get_app().current_buffer.document.current_line_before_cursor
31 return (not before) or before.isspace()
31 return (not before) or before.isspace()
32
32
33
33
34 def create_ipython_shortcuts(shell):
34 def create_ipython_shortcuts(shell):
35 """Set up the prompt_toolkit keyboard shortcuts for IPython"""
35 """Set up the prompt_toolkit keyboard shortcuts for IPython"""
36
36
37 kb = KeyBindings()
37 kb = KeyBindings()
38 insert_mode = vi_insert_mode | emacs_insert_mode
38 insert_mode = vi_insert_mode | emacs_insert_mode
39
39
40 if getattr(shell, 'handle_return', None):
40 if getattr(shell, 'handle_return', None):
41 return_handler = shell.handle_return(shell)
41 return_handler = shell.handle_return(shell)
42 else:
42 else:
43 return_handler = newline_or_execute_outer(shell)
43 return_handler = newline_or_execute_outer(shell)
44
44
45 kb.add('enter', filter=(has_focus(DEFAULT_BUFFER)
45 kb.add('enter', filter=(has_focus(DEFAULT_BUFFER)
46 & ~has_selection
46 & ~has_selection
47 & insert_mode
47 & insert_mode
48 ))(return_handler)
48 ))(return_handler)
49
49
50 def reformat_and_execute(event):
50 def reformat_and_execute(event):
51 reformat_text_before_cursor(event.current_buffer, event.current_buffer.document, shell)
51 reformat_text_before_cursor(event.current_buffer, event.current_buffer.document, shell)
52 event.current_buffer.validate_and_handle()
52 event.current_buffer.validate_and_handle()
53
53
54 kb.add('escape', 'enter', filter=(has_focus(DEFAULT_BUFFER)
54 kb.add('escape', 'enter', filter=(has_focus(DEFAULT_BUFFER)
55 & ~has_selection
55 & ~has_selection
56 & insert_mode
56 & insert_mode
57 ))(reformat_and_execute)
57 ))(reformat_and_execute)
58
58
59 kb.add('c-\\')(force_exit)
59 kb.add('c-\\')(force_exit)
60
60
61 kb.add('c-p', filter=(vi_insert_mode & has_focus(DEFAULT_BUFFER))
61 kb.add('c-p', filter=(vi_insert_mode & has_focus(DEFAULT_BUFFER))
62 )(previous_history_or_previous_completion)
62 )(previous_history_or_previous_completion)
63
63
64 kb.add('c-n', filter=(vi_insert_mode & has_focus(DEFAULT_BUFFER))
64 kb.add('c-n', filter=(vi_insert_mode & has_focus(DEFAULT_BUFFER))
65 )(next_history_or_next_completion)
65 )(next_history_or_next_completion)
66
66
67 kb.add('c-g', filter=(has_focus(DEFAULT_BUFFER) & has_completions)
67 kb.add('c-g', filter=(has_focus(DEFAULT_BUFFER) & has_completions)
68 )(dismiss_completion)
68 )(dismiss_completion)
69
69
70 kb.add('c-c', filter=has_focus(DEFAULT_BUFFER))(reset_buffer)
70 kb.add('c-c', filter=has_focus(DEFAULT_BUFFER))(reset_buffer)
71
71
72 kb.add('c-c', filter=has_focus(SEARCH_BUFFER))(reset_search_buffer)
72 kb.add('c-c', filter=has_focus(SEARCH_BUFFER))(reset_search_buffer)
73
73
74 supports_suspend = Condition(lambda: hasattr(signal, 'SIGTSTP'))
74 supports_suspend = Condition(lambda: hasattr(signal, 'SIGTSTP'))
75 kb.add('c-z', filter=supports_suspend)(suspend_to_bg)
75 kb.add('c-z', filter=supports_suspend)(suspend_to_bg)
76
76
77 # Ctrl+I == Tab
77 # Ctrl+I == Tab
78 kb.add('tab', filter=(has_focus(DEFAULT_BUFFER)
78 kb.add('tab', filter=(has_focus(DEFAULT_BUFFER)
79 & ~has_selection
79 & ~has_selection
80 & insert_mode
80 & insert_mode
81 & cursor_in_leading_ws
81 & cursor_in_leading_ws
82 ))(indent_buffer)
82 ))(indent_buffer)
83 kb.add('c-o', filter=(has_focus(DEFAULT_BUFFER) & emacs_insert_mode)
83 kb.add('c-o', filter=(has_focus(DEFAULT_BUFFER) & emacs_insert_mode)
84 )(newline_autoindent_outer(shell.input_transformer_manager))
84 )(newline_autoindent_outer(shell.input_transformer_manager))
85
85
86 kb.add('f2', filter=has_focus(DEFAULT_BUFFER))(open_input_in_editor)
86 kb.add('f2', filter=has_focus(DEFAULT_BUFFER))(open_input_in_editor)
87
87
88 if shell.display_completions == 'readlinelike':
88 if shell.display_completions == 'readlinelike':
89 kb.add('c-i', filter=(has_focus(DEFAULT_BUFFER)
89 kb.add('c-i', filter=(has_focus(DEFAULT_BUFFER)
90 & ~has_selection
90 & ~has_selection
91 & insert_mode
91 & insert_mode
92 & ~cursor_in_leading_ws
92 & ~cursor_in_leading_ws
93 ))(display_completions_like_readline)
93 ))(display_completions_like_readline)
94
94
95 if sys.platform == "win32":
95 if sys.platform == "win32":
96 kb.add("c-v", filter=(has_focus(DEFAULT_BUFFER) & ~vi_mode))(win_paste)
96 kb.add("c-v", filter=(has_focus(DEFAULT_BUFFER) & ~vi_mode))(win_paste)
97
97
98 @Condition
98 @Condition
99 def ebivim():
99 def ebivim():
100 return shell.emacs_bindings_in_vi_insert_mode
100 return shell.emacs_bindings_in_vi_insert_mode
101
101
102 focused_insert = has_focus(DEFAULT_BUFFER) & vi_insert_mode
102 focused_insert_vi = has_focus(DEFAULT_BUFFER) & vi_insert_mode
103
103
104 # Needed for to accept autosuggestions in vi insert mode
104 # Needed for to accept autosuggestions in vi insert mode
105 @kb.add("c-e", filter=focused_insert & ebivim)
105 @kb.add("c-e", filter=focused_insert_vi & ebivim)
106 def _(event):
106 def _(event):
107 b = event.current_buffer
107 b = event.current_buffer
108 suggestion = b.suggestion
108 suggestion = b.suggestion
109 if suggestion:
109 if suggestion:
110 b.insert_text(suggestion.text)
110 b.insert_text(suggestion.text)
111 else:
111 else:
112 nc.end_of_line(event)
112 nc.end_of_line(event)
113
113
114 @kb.add("c-f", filter=focused_insert & ebivim)
114 @kb.add("c-f", filter=focused_insert_vi)
115 def _(event):
115 def _(event):
116 b = event.current_buffer
116 b = event.current_buffer
117 suggestion = b.suggestion
117 suggestion = b.suggestion
118 if suggestion:
118 if suggestion:
119 b.insert_text(suggestion.text)
119 b.insert_text(suggestion.text)
120 else:
120 else:
121 nc.forward_char(event)
121 nc.forward_char(event)
122
122
123 @kb.add("escape", "f", filter=focused_insert & ebivim)
123 @kb.add("escape", "f", filter=focused_insert_vi & ebivim)
124 def _(event):
124 def _(event):
125 b = event.current_buffer
125 b = event.current_buffer
126 suggestion = b.suggestion
126 suggestion = b.suggestion
127 if suggestion:
127 if suggestion:
128 t = re.split(r"(\S+\s+)", suggestion.text)
128 t = re.split(r"(\S+\s+)", suggestion.text)
129 b.insert_text(next((x for x in t if x), ""))
129 b.insert_text(next((x for x in t if x), ""))
130 else:
130 else:
131 nc.forward_word(event)
131 nc.forward_word(event)
132
132
133 # Simple Control keybindings
133 # Simple Control keybindings
134 key_cmd_dict = {
134 key_cmd_dict = {
135 "c-a": nc.beginning_of_line,
135 "c-a": nc.beginning_of_line,
136 "c-b": nc.backward_char,
136 "c-b": nc.backward_char,
137 "c-k": nc.kill_line,
137 "c-k": nc.kill_line,
138 "c-w": nc.backward_kill_word,
138 "c-w": nc.backward_kill_word,
139 "c-y": nc.yank,
139 "c-y": nc.yank,
140 "c-_": nc.undo,
140 "c-_": nc.undo,
141 }
141 }
142
142
143 for key, cmd in key_cmd_dict.items():
143 for key, cmd in key_cmd_dict.items():
144 kb.add(key, filter=focused_insert & ebivim)(cmd)
144 kb.add(key, filter=focused_insert_vi & ebivim)(cmd)
145
145
146 # Alt and Combo Control keybindings
146 # Alt and Combo Control keybindings
147 keys_cmd_dict = {
147 keys_cmd_dict = {
148 # Control Combos
148 # Control Combos
149 ("c-x", "c-e"): nc.edit_and_execute,
149 ("c-x", "c-e"): nc.edit_and_execute,
150 ("c-x", "e"): nc.edit_and_execute,
150 ("c-x", "e"): nc.edit_and_execute,
151 # Alt
151 # Alt
152 ("escape", "b"): nc.backward_word,
152 ("escape", "b"): nc.backward_word,
153 ("escape", "c"): nc.capitalize_word,
153 ("escape", "c"): nc.capitalize_word,
154 ("escape", "d"): nc.kill_word,
154 ("escape", "d"): nc.kill_word,
155 ("escape", "h"): nc.backward_kill_word,
155 ("escape", "h"): nc.backward_kill_word,
156 ("escape", "l"): nc.downcase_word,
156 ("escape", "l"): nc.downcase_word,
157 ("escape", "u"): nc.uppercase_word,
157 ("escape", "u"): nc.uppercase_word,
158 ("escape", "y"): nc.yank_pop,
158 ("escape", "y"): nc.yank_pop,
159 ("escape", "."): nc.yank_last_arg,
159 ("escape", "."): nc.yank_last_arg,
160 }
160 }
161
161
162 for keys, cmd in keys_cmd_dict.items():
162 for keys, cmd in keys_cmd_dict.items():
163 kb.add(*keys, filter=focused_insert & ebivim)(cmd)
163 kb.add(*keys, filter=focused_insert_vi & ebivim)(cmd)
164
164
165 def get_input_mode(self):
165 def get_input_mode(self):
166 app = get_app()
166 app = get_app()
167 app.ttimeoutlen = shell.ttimeoutlen
167 app.ttimeoutlen = shell.ttimeoutlen
168 app.timeoutlen = shell.timeoutlen
168 app.timeoutlen = shell.timeoutlen
169
169
170 return self._input_mode
170 return self._input_mode
171
171
172 def set_input_mode(self, mode):
172 def set_input_mode(self, mode):
173 shape = {InputMode.NAVIGATION: 2, InputMode.REPLACE: 4}.get(mode, 6)
173 shape = {InputMode.NAVIGATION: 2, InputMode.REPLACE: 4}.get(mode, 6)
174 cursor = "\x1b[{} q".format(shape)
174 cursor = "\x1b[{} q".format(shape)
175
175
176 if hasattr(sys.stdout, "_cli"):
176 if hasattr(sys.stdout, "_cli"):
177 write = sys.stdout._cli.output.write_raw
177 write = sys.stdout._cli.output.write_raw
178 else:
178 else:
179 write = sys.stdout.write
179 write = sys.stdout.write
180
180
181 write(cursor)
181 write(cursor)
182 sys.stdout.flush()
182 sys.stdout.flush()
183
183
184 self._input_mode = mode
184 self._input_mode = mode
185
185
186 if shell.editing_mode == "vi" and shell.modal_cursor:
186 if shell.editing_mode == "vi" and shell.modal_cursor:
187 ViState._input_mode = InputMode.INSERT
187 ViState._input_mode = InputMode.INSERT
188 ViState.input_mode = property(get_input_mode, set_input_mode)
188 ViState.input_mode = property(get_input_mode, set_input_mode)
189
189
190 return kb
190 return kb
191
191
192
192
193 def reformat_text_before_cursor(buffer, document, shell):
193 def reformat_text_before_cursor(buffer, document, shell):
194 text = buffer.delete_before_cursor(len(document.text[:document.cursor_position]))
194 text = buffer.delete_before_cursor(len(document.text[:document.cursor_position]))
195 try:
195 try:
196 formatted_text = shell.reformat_handler(text)
196 formatted_text = shell.reformat_handler(text)
197 buffer.insert_text(formatted_text)
197 buffer.insert_text(formatted_text)
198 except Exception as e:
198 except Exception as e:
199 buffer.insert_text(text)
199 buffer.insert_text(text)
200
200
201
201
202 def newline_or_execute_outer(shell):
202 def newline_or_execute_outer(shell):
203
203
204 def newline_or_execute(event):
204 def newline_or_execute(event):
205 """When the user presses return, insert a newline or execute the code."""
205 """When the user presses return, insert a newline or execute the code."""
206 b = event.current_buffer
206 b = event.current_buffer
207 d = b.document
207 d = b.document
208
208
209 if b.complete_state:
209 if b.complete_state:
210 cc = b.complete_state.current_completion
210 cc = b.complete_state.current_completion
211 if cc:
211 if cc:
212 b.apply_completion(cc)
212 b.apply_completion(cc)
213 else:
213 else:
214 b.cancel_completion()
214 b.cancel_completion()
215 return
215 return
216
216
217 # If there's only one line, treat it as if the cursor is at the end.
217 # If there's only one line, treat it as if the cursor is at the end.
218 # See https://github.com/ipython/ipython/issues/10425
218 # See https://github.com/ipython/ipython/issues/10425
219 if d.line_count == 1:
219 if d.line_count == 1:
220 check_text = d.text
220 check_text = d.text
221 else:
221 else:
222 check_text = d.text[:d.cursor_position]
222 check_text = d.text[:d.cursor_position]
223 status, indent = shell.check_complete(check_text)
223 status, indent = shell.check_complete(check_text)
224
224
225 # if all we have after the cursor is whitespace: reformat current text
225 # if all we have after the cursor is whitespace: reformat current text
226 # before cursor
226 # before cursor
227 after_cursor = d.text[d.cursor_position:]
227 after_cursor = d.text[d.cursor_position:]
228 reformatted = False
228 reformatted = False
229 if not after_cursor.strip():
229 if not after_cursor.strip():
230 reformat_text_before_cursor(b, d, shell)
230 reformat_text_before_cursor(b, d, shell)
231 reformatted = True
231 reformatted = True
232 if not (d.on_last_line or
232 if not (d.on_last_line or
233 d.cursor_position_row >= d.line_count - d.empty_line_count_at_the_end()
233 d.cursor_position_row >= d.line_count - d.empty_line_count_at_the_end()
234 ):
234 ):
235 if shell.autoindent:
235 if shell.autoindent:
236 b.insert_text('\n' + indent)
236 b.insert_text('\n' + indent)
237 else:
237 else:
238 b.insert_text('\n')
238 b.insert_text('\n')
239 return
239 return
240
240
241 if (status != 'incomplete') and b.accept_handler:
241 if (status != 'incomplete') and b.accept_handler:
242 if not reformatted:
242 if not reformatted:
243 reformat_text_before_cursor(b, d, shell)
243 reformat_text_before_cursor(b, d, shell)
244 b.validate_and_handle()
244 b.validate_and_handle()
245 else:
245 else:
246 if shell.autoindent:
246 if shell.autoindent:
247 b.insert_text('\n' + indent)
247 b.insert_text('\n' + indent)
248 else:
248 else:
249 b.insert_text('\n')
249 b.insert_text('\n')
250 return newline_or_execute
250 return newline_or_execute
251
251
252
252
253 def previous_history_or_previous_completion(event):
253 def previous_history_or_previous_completion(event):
254 """
254 """
255 Control-P in vi edit mode on readline is history next, unlike default prompt toolkit.
255 Control-P in vi edit mode on readline is history next, unlike default prompt toolkit.
256
256
257 If completer is open this still select previous completion.
257 If completer is open this still select previous completion.
258 """
258 """
259 event.current_buffer.auto_up()
259 event.current_buffer.auto_up()
260
260
261
261
262 def next_history_or_next_completion(event):
262 def next_history_or_next_completion(event):
263 """
263 """
264 Control-N in vi edit mode on readline is history previous, unlike default prompt toolkit.
264 Control-N in vi edit mode on readline is history previous, unlike default prompt toolkit.
265
265
266 If completer is open this still select next completion.
266 If completer is open this still select next completion.
267 """
267 """
268 event.current_buffer.auto_down()
268 event.current_buffer.auto_down()
269
269
270
270
271 def dismiss_completion(event):
271 def dismiss_completion(event):
272 b = event.current_buffer
272 b = event.current_buffer
273 if b.complete_state:
273 if b.complete_state:
274 b.cancel_completion()
274 b.cancel_completion()
275
275
276
276
277 def reset_buffer(event):
277 def reset_buffer(event):
278 b = event.current_buffer
278 b = event.current_buffer
279 if b.complete_state:
279 if b.complete_state:
280 b.cancel_completion()
280 b.cancel_completion()
281 else:
281 else:
282 b.reset()
282 b.reset()
283
283
284
284
285 def reset_search_buffer(event):
285 def reset_search_buffer(event):
286 if event.current_buffer.document.text:
286 if event.current_buffer.document.text:
287 event.current_buffer.reset()
287 event.current_buffer.reset()
288 else:
288 else:
289 event.app.layout.focus(DEFAULT_BUFFER)
289 event.app.layout.focus(DEFAULT_BUFFER)
290
290
291 def suspend_to_bg(event):
291 def suspend_to_bg(event):
292 event.app.suspend_to_background()
292 event.app.suspend_to_background()
293
293
294 def force_exit(event):
294 def force_exit(event):
295 """
295 """
296 Force exit (with a non-zero return value)
296 Force exit (with a non-zero return value)
297 """
297 """
298 sys.exit("Quit")
298 sys.exit("Quit")
299
299
300 def indent_buffer(event):
300 def indent_buffer(event):
301 event.current_buffer.insert_text(' ' * 4)
301 event.current_buffer.insert_text(' ' * 4)
302
302
303 @undoc
303 @undoc
304 def newline_with_copy_margin(event):
304 def newline_with_copy_margin(event):
305 """
305 """
306 DEPRECATED since IPython 6.0
306 DEPRECATED since IPython 6.0
307
307
308 See :any:`newline_autoindent_outer` for a replacement.
308 See :any:`newline_autoindent_outer` for a replacement.
309
309
310 Preserve margin and cursor position when using
310 Preserve margin and cursor position when using
311 Control-O to insert a newline in EMACS mode
311 Control-O to insert a newline in EMACS mode
312 """
312 """
313 warnings.warn("`newline_with_copy_margin(event)` is deprecated since IPython 6.0. "
313 warnings.warn("`newline_with_copy_margin(event)` is deprecated since IPython 6.0. "
314 "see `newline_autoindent_outer(shell)(event)` for a replacement.",
314 "see `newline_autoindent_outer(shell)(event)` for a replacement.",
315 DeprecationWarning, stacklevel=2)
315 DeprecationWarning, stacklevel=2)
316
316
317 b = event.current_buffer
317 b = event.current_buffer
318 cursor_start_pos = b.document.cursor_position_col
318 cursor_start_pos = b.document.cursor_position_col
319 b.newline(copy_margin=True)
319 b.newline(copy_margin=True)
320 b.cursor_up(count=1)
320 b.cursor_up(count=1)
321 cursor_end_pos = b.document.cursor_position_col
321 cursor_end_pos = b.document.cursor_position_col
322 if cursor_start_pos != cursor_end_pos:
322 if cursor_start_pos != cursor_end_pos:
323 pos_diff = cursor_start_pos - cursor_end_pos
323 pos_diff = cursor_start_pos - cursor_end_pos
324 b.cursor_right(count=pos_diff)
324 b.cursor_right(count=pos_diff)
325
325
326 def newline_autoindent_outer(inputsplitter) -> Callable[..., None]:
326 def newline_autoindent_outer(inputsplitter) -> Callable[..., None]:
327 """
327 """
328 Return a function suitable for inserting a indented newline after the cursor.
328 Return a function suitable for inserting a indented newline after the cursor.
329
329
330 Fancier version of deprecated ``newline_with_copy_margin`` which should
330 Fancier version of deprecated ``newline_with_copy_margin`` which should
331 compute the correct indentation of the inserted line. That is to say, indent
331 compute the correct indentation of the inserted line. That is to say, indent
332 by 4 extra space after a function definition, class definition, context
332 by 4 extra space after a function definition, class definition, context
333 manager... And dedent by 4 space after ``pass``, ``return``, ``raise ...``.
333 manager... And dedent by 4 space after ``pass``, ``return``, ``raise ...``.
334 """
334 """
335
335
336 def newline_autoindent(event):
336 def newline_autoindent(event):
337 """insert a newline after the cursor indented appropriately."""
337 """insert a newline after the cursor indented appropriately."""
338 b = event.current_buffer
338 b = event.current_buffer
339 d = b.document
339 d = b.document
340
340
341 if b.complete_state:
341 if b.complete_state:
342 b.cancel_completion()
342 b.cancel_completion()
343 text = d.text[:d.cursor_position] + '\n'
343 text = d.text[:d.cursor_position] + '\n'
344 _, indent = inputsplitter.check_complete(text)
344 _, indent = inputsplitter.check_complete(text)
345 b.insert_text('\n' + (' ' * (indent or 0)), move_cursor=False)
345 b.insert_text('\n' + (' ' * (indent or 0)), move_cursor=False)
346
346
347 return newline_autoindent
347 return newline_autoindent
348
348
349
349
350 def open_input_in_editor(event):
350 def open_input_in_editor(event):
351 event.app.current_buffer.open_in_editor()
351 event.app.current_buffer.open_in_editor()
352
352
353
353
354 if sys.platform == 'win32':
354 if sys.platform == 'win32':
355 from IPython.core.error import TryNext
355 from IPython.core.error import TryNext
356 from IPython.lib.clipboard import (ClipboardEmpty,
356 from IPython.lib.clipboard import (ClipboardEmpty,
357 win32_clipboard_get,
357 win32_clipboard_get,
358 tkinter_clipboard_get)
358 tkinter_clipboard_get)
359
359
360 @undoc
360 @undoc
361 def win_paste(event):
361 def win_paste(event):
362 try:
362 try:
363 text = win32_clipboard_get()
363 text = win32_clipboard_get()
364 except TryNext:
364 except TryNext:
365 try:
365 try:
366 text = tkinter_clipboard_get()
366 text = tkinter_clipboard_get()
367 except (TryNext, ClipboardEmpty):
367 except (TryNext, ClipboardEmpty):
368 return
368 return
369 except ClipboardEmpty:
369 except ClipboardEmpty:
370 return
370 return
371 event.current_buffer.insert_text(text.replace("\t", " " * 4))
371 event.current_buffer.insert_text(text.replace("\t", " " * 4))
@@ -1,467 +1,452 b''
1 =====================
1 =====================
2 Development version
2 Development version
3 =====================
3 =====================
4
4
5 This document describes in-flight development work.
5 This document describes in-flight development work.
6
6
7 .. warning::
7 .. warning::
8
8
9 Please do not edit this file by hand (doing so will likely cause merge
9 Please do not edit this file by hand (doing so will likely cause merge
10 conflicts for other Pull Requests). Instead, create a new file in the
10 conflicts for other Pull Requests). Instead, create a new file in the
11 `docs/source/whatsnew/pr` folder
11 `docs/source/whatsnew/pr` folder
12
12
13
13
14 Released .... ...., 2019
14 Released .... ...., 2019
15
15
16
16
17 Need to be updated:
17 Need to be updated:
18
18
19 .. toctree::
19 .. toctree::
20 :maxdepth: 2
20 :maxdepth: 2
21 :glob:
21 :glob:
22
22
23 pr/*
23 pr/*
24
24
25 IPython 8.0 is bringing a large number of new features and improvements to both the
25 IPython 8.0 is bringing a large number of new features and improvements to both the
26 user of the terminal and of the kernel via Jupyter. The removal of compatibility
26 user of the terminal and of the kernel via Jupyter. The removal of compatibility
27 with older version of Python is also the opportunity to do a couple of
27 with older version of Python is also the opportunity to do a couple of
28 performance improvement in particular with respect to startup time.
28 performance improvement in particular with respect to startup time.
29 The 8.x branch started diverging from its predecessor around IPython 7.12
29 The 8.x branch started diverging from its predecessor around IPython 7.12
30 (January 2020).
30 (January 2020).
31
31
32 This release contains 250+ Pull Requests, in addition to many of the features
32 This release contains 250+ Pull Requests, in addition to many of the features
33 and backports that have made it to the 7.x branch. All PRs that went into this
33 and backports that have made it to the 7.x branch. All PRs that went into this
34 released are properly tagged with the 8.0 milestone if you wish to have a more
34 released are properly tagged with the 8.0 milestone if you wish to have a more
35 in depth look at the changes.
35 in depth look at the changes.
36
36
37 Please fell free to send pull-requests to updates those notes after release,
37 Please fell free to send pull-requests to updates those notes after release,
38 I have likely forgotten a few things reviewing 250+ PRs.
38 I have likely forgotten a few things reviewing 250+ PRs.
39
39
40 Dependencies changes/downstream packaging
40 Dependencies changes/downstream packaging
41 -----------------------------------------
41 -----------------------------------------
42
42
43 Note that most of our building step have been changes to be (mostly) declarative
43 Note that most of our building step have been changes to be (mostly) declarative
44 and follow PEP 517, we are trying to completely remove ``setup.py`` (:ghpull:`13238`) and are
44 and follow PEP 517, we are trying to completely remove ``setup.py`` (:ghpull:`13238`) and are
45 looking for help to do so.
45 looking for help to do so.
46
46
47 - Minimum supported ``traitlets`` version if now 5+
47 - Minimum supported ``traitlets`` version if now 5+
48 - we now require ``stack_data``
48 - we now require ``stack_data``
49 - Minimal Python is now 3.8
49 - Minimal Python is now 3.8
50 - ``nose`` is not a testing requirement anymore
50 - ``nose`` is not a testing requirement anymore
51 - ``pytest`` replaces nose.
51 - ``pytest`` replaces nose.
52 - ``iptest``/``iptest3`` cli entrypoints do not exists anymore.
52 - ``iptest``/``iptest3`` cli entrypoints do not exists anymore.
53 - minimum officially support ``numpy`` version has been bumped, but this should
53 - minimum officially support ``numpy`` version has been bumped, but this should
54 not have much effect on packaging.
54 not have much effect on packaging.
55
55
56
56
57 Deprecation and removal
57 Deprecation and removal
58 -----------------------
58 -----------------------
59
59
60 We removed almost all features, arguments, functions, and modules that were
60 We removed almost all features, arguments, functions, and modules that were
61 marked as deprecated between IPython 1.0 and 5.0. As reminder 5.0 was released
61 marked as deprecated between IPython 1.0 and 5.0. As reminder 5.0 was released
62 in 2016, and 1.0 in 2013. Last release of the 5 branch was 5.10.0, in may 2020.
62 in 2016, and 1.0 in 2013. Last release of the 5 branch was 5.10.0, in may 2020.
63 The few remaining deprecated features we left have better deprecation warnings
63 The few remaining deprecated features we left have better deprecation warnings
64 or have been turned into explicit errors for better error messages.
64 or have been turned into explicit errors for better error messages.
65
65
66 I will use this occasion to add the following requests to anyone emitting a
66 I will use this occasion to add the following requests to anyone emitting a
67 deprecation warning:
67 deprecation warning:
68
68
69 - Please at at least ``stacklevel=2`` so that the warning is emitted into the
69 - Please at at least ``stacklevel=2`` so that the warning is emitted into the
70 caller context, and not the callee one.
70 caller context, and not the callee one.
71 - Please add **since which version** something is deprecated.
71 - Please add **since which version** something is deprecated.
72
72
73 As a side note it is much easier to deal with conditional comparing to versions
73 As a side note it is much easier to deal with conditional comparing to versions
74 numbers than ``try/except`` when a functionality change with version.
74 numbers than ``try/except`` when a functionality change with version.
75
75
76 I won't list all the removed features here, but modules like ``IPython.kernel``,
76 I won't list all the removed features here, but modules like ``IPython.kernel``,
77 which was just a shim module around ``ipykernel`` for the past 8 years have been
77 which was just a shim module around ``ipykernel`` for the past 8 years have been
78 remove, and so many other similar things that pre-date the name **Jupyter**
78 remove, and so many other similar things that pre-date the name **Jupyter**
79 itself.
79 itself.
80
80
81 We no longer need to add ``IPyhton.extensions`` to the PYTHONPATH because that is being
81 We no longer need to add ``IPyhton.extensions`` to the PYTHONPATH because that is being
82 handled by ``load_extension``.
82 handled by ``load_extension``.
83
83
84 We are also removing ``Cythonmagic``, ``sympyprinting`` and ``rmagic`` as they are now in
84 We are also removing ``Cythonmagic``, ``sympyprinting`` and ``rmagic`` as they are now in
85 other packages and no longer need to be inside IPython.
85 other packages and no longer need to be inside IPython.
86
86
87
87
88 Documentation
88 Documentation
89 -------------
89 -------------
90
90
91 Majority of our docstrings have now been reformatted and automatically fixed by
91 Majority of our docstrings have now been reformatted and automatically fixed by
92 the experimental `Vélin <https://pypi.org/project/velin/>`_ project, to conform
92 the experimental `Vélin <https://pypi.org/project/velin/>`_ project, to conform
93 to numpydoc.
93 to numpydoc.
94
94
95 Type annotations
95 Type annotations
96 ----------------
96 ----------------
97
97
98 While IPython itself is highly dynamic and can't be completely typed, many of
98 While IPython itself is highly dynamic and can't be completely typed, many of
99 the function now have type annotation, and part of the codebase and now checked
99 the function now have type annotation, and part of the codebase and now checked
100 by mypy.
100 by mypy.
101
101
102
102
103 Featured changes
103 Featured changes
104 ----------------
104 ----------------
105
105
106 Here is a features list of changes in IPython 8.0. This is of course non-exhaustive.
106 Here is a features list of changes in IPython 8.0. This is of course non-exhaustive.
107 Please note as well that many features have been added in the 7.x branch as well
107 Please note as well that many features have been added in the 7.x branch as well
108 (and hence why you want to read the 7.x what's new notes), in particular
108 (and hence why you want to read the 7.x what's new notes), in particular
109 features contributed by QuantStack (with respect to debugger protocol, and Xeus
109 features contributed by QuantStack (with respect to debugger protocol, and Xeus
110 Python), as well as many debugger features that I was please to implement as
110 Python), as well as many debugger features that I was please to implement as
111 part of my work at QuanSight and Sponsored by DE Shaw.
111 part of my work at QuanSight and Sponsored by DE Shaw.
112
112
113 Better Tracebacks
113 Better Tracebacks
114 ~~~~~~~~~~~~~~~~~
114 ~~~~~~~~~~~~~~~~~
115
115
116 The first on is the integration of the ``stack_data`` package;
116 The first on is the integration of the ``stack_data`` package;
117 which provide smarter informations in traceback; in particular it will highlight
117 which provide smarter informations in traceback; in particular it will highlight
118 the AST node where an error occurs which can help to quickly narrow down errors.
118 the AST node where an error occurs which can help to quickly narrow down errors.
119
119
120 For example in the following snippet::
120 For example in the following snippet::
121
121
122 def foo(i):
122 def foo(i):
123 x = [[[0]]]
123 x = [[[0]]]
124 return x[0][i][0]
124 return x[0][i][0]
125
125
126
126
127 def bar():
127 def bar():
128 return foo(0) + foo(
128 return foo(0) + foo(
129 1
129 1
130 ) + foo(2)
130 ) + foo(2)
131
131
132
132
133 Calling ``bar()`` would raise an ``IndexError`` on the return line of ``foo``,
133 Calling ``bar()`` would raise an ``IndexError`` on the return line of ``foo``,
134 IPython 8.0 is capable of telling you, where the index error occurs::
134 IPython 8.0 is capable of telling you, where the index error occurs::
135
135
136
136
137 IndexError
137 IndexError
138 Input In [2], in <module>
138 Input In [2], in <module>
139 ----> 1 bar()
139 ----> 1 bar()
140 ^^^^^
140 ^^^^^
141
141
142 Input In [1], in bar()
142 Input In [1], in bar()
143 6 def bar():
143 6 def bar():
144 ----> 7 return foo(0) + foo(
144 ----> 7 return foo(0) + foo(
145 ^^^^
145 ^^^^
146 8 1
146 8 1
147 ^^^^^^^^
147 ^^^^^^^^
148 9 ) + foo(2)
148 9 ) + foo(2)
149 ^^^^
149 ^^^^
150
150
151 Input In [1], in foo(i)
151 Input In [1], in foo(i)
152 1 def foo(i):
152 1 def foo(i):
153 2 x = [[[0]]]
153 2 x = [[[0]]]
154 ----> 3 return x[0][i][0]
154 ----> 3 return x[0][i][0]
155 ^^^^^^^
155 ^^^^^^^
156
156
157 Corresponding location marked here with ``^`` will show up highlighted in
157 Corresponding location marked here with ``^`` will show up highlighted in
158 terminal and notebooks.
158 terminal and notebooks.
159
159
160
160
161 Autosuggestons
161 Autosuggestons
162 ~~~~~~~~~~~~~~
162 ~~~~~~~~~~~~~~
163
163
164 Autosuggestion is a very useful feature available in `fish <https://fishshell.com/>`__, `zsh <https://en.wikipedia.org/wiki/Z_shell>`__, and `prompt-toolkit <https://python-prompt-toolkit.readthedocs.io/en/master/pages/asking_for_input.html#auto-suggestion>`__.
164 Autosuggestion is a very useful feature available in `fish <https://fishshell.com/>`__, `zsh <https://en.wikipedia.org/wiki/Z_shell>`__, and `prompt-toolkit <https://python-prompt-toolkit.readthedocs.io/en/master/pages/asking_for_input.html#auto-suggestion>`__.
165
165
166 `Ptpython <https://github.com/prompt-toolkit/ptpython#ptpython>`__ allows users to enable this feature in
166 `Ptpython <https://github.com/prompt-toolkit/ptpython#ptpython>`__ allows users to enable this feature in
167 `ptpython/config.py <https://github.com/prompt-toolkit/ptpython/blob/master/examples/ptpython_config/config.py#L90>`__.
167 `ptpython/config.py <https://github.com/prompt-toolkit/ptpython/blob/master/examples/ptpython_config/config.py#L90>`__.
168
168
169 This feature allows users to accept autosuggestions with ctrl e, ctrl f,
169 This feature allows users to accept autosuggestions with ctrl e, ctrl f,
170 or right arrow as described below.
170 or right arrow as described below.
171
171
172 1. Start ipython
172 1. Start ipython
173
173
174 .. image:: ../_images/8.0/auto_suggest_prompt_no_text.png
174 .. image:: ../_images/8.0/auto_suggest_1_prompt_no_text.png
175
175
176 2. Run ``print("hello")``
176 2. Run ``print("hello")``
177
177
178 .. image:: ../_images/8.0/auto_suggest_print_hello_suggest.png
178 .. image:: ../_images/8.0/auto_suggest_2_print_hello_suggest.png
179
179
180 3. Press p to see the autosuggestion
180 3. start typing ``print`` again to see the autosuggestion
181
181
182 .. image:: ../_images/8.0/auto_suggest_print_hello_suggest.png
182 .. image:: ../_images/8.0/auto_suggest_3_print_hello_suggest.png
183
183
184 4. Press ctrl f, or ctrl e, or right arrow to accept the suggestion
184 4. Press ``ctrl-f``, or ``ctrl-e``, or ``right-arrow`` to accept the suggestion
185
185
186 .. image:: ../_images/8.0/auto_suggest_print_hello.png
186 .. image:: ../_images/8.0/auto_suggest_4_print_hello.png
187
187
188 You can also complete word by word:
188 You can also complete word by word:
189
189
190 1. Run ``def say_hello(): print("hello")``
190 1. Run ``def say_hello(): print("hello")``
191
191
192 .. image:: ../_images/8.0/auto_suggest_second_prompt.png
192 .. image:: ../_images/8.0/auto_suggest_second_prompt.png
193
193
194 2. Press d to see the autosuggestion
194 2. Start typing the first letter if ``def`` to see the autosuggestion
195
195
196 .. image:: ../_images/8.0/auto_suggest_d_phantom.png
196 .. image:: ../_images/8.0/auto_suggest_d_phantom.png
197
197
198 3. Press alt f to accept the first word of the suggestion
198 3. Press ``alt-f`` (or ``escape`` followed by ``f``), to accept the first word of the suggestion
199
199
200 .. image:: ../_images/8.0/auto_suggest_def_phantom.png
200 .. image:: ../_images/8.0/auto_suggest_def_phantom.png
201
201
202 Importantly, this feature does not interfere with tab completion:
202 Importantly, this feature does not interfere with tab completion:
203
203
204 1. After running ``def say_hello(): print("hello")``, press d
204 1. After running ``def say_hello(): print("hello")``, press d
205
205
206 .. image:: ../_images/8.0/auto_suggest_d_phantom.png
206 .. image:: ../_images/8.0/auto_suggest_d_phantom.png
207
207
208 2. Press Tab to start tab completion
208 2. Press Tab to start tab completion
209
209
210 .. image:: ../_images/8.0/auto_suggest_d_completions.png
210 .. image:: ../_images/8.0/auto_suggest_d_completions.png
211
211
212 3A. Press Tab again to select the first option
212 3A. Press Tab again to select the first option
213
213
214 .. image:: ../_images/8.0/auto_suggest_def_completions.png
214 .. image:: ../_images/8.0/auto_suggest_def_completions.png
215
215
216 3B. Press alt f to accept to accept the first word of the suggestion
216 3B. Press ``alt f`` (``escape``, ``f``) to accept to accept the first word of the suggestion
217
217
218 .. image:: ../_images/8.0/auto_suggest_def_phantom.png
218 .. image:: ../_images/8.0/auto_suggest_def_phantom.png
219
219
220 3C. Press ctrl f or ctrl e to accept the entire suggestion
220 3C. Press ``ctrl-f`` or ``ctrl-e`` to accept the entire suggestion
221
221
222 .. image:: ../_images/8.0/auto_suggest_match_parens.png
222 .. image:: ../_images/8.0/auto_suggest_match_parens.png
223
223
224 To install a version of ipython with autosuggestions enabled, run:
225
226 ``pip install git+https://github.com/mskar/ipython@auto_suggest``
227
224
228 Currently, autosuggestions are only shown in the emacs or vi insert editing modes:
225 Currently, autosuggestions are only shown in the emacs or vi insert editing modes:
229
226
230 - The ctrl e, ctrl f, and alt f shortcuts work by default in emacs mode.
227 - The ctrl e, ctrl f, and alt f shortcuts work by default in emacs mode.
231 - To use these shortcuts in vi insert mode, you will have to create `custom keybindings in your config.py <https://github.com/mskar/setup/commit/2892fcee46f9f80ef7788f0749edc99daccc52f4/>`__.
228 - To use these shortcuts in vi insert mode, you will have to create `custom keybindings in your config.py <https://github.com/mskar/setup/commit/2892fcee46f9f80ef7788f0749edc99daccc52f4/>`__.
232
229
233
230
234 Show pinfo information in ipdb using "?" and "??"
231 Show pinfo information in ipdb using "?" and "??"
235 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
232 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
236
233
237 In IPDB, it is now possible to show the information about an object using "?"
234 In IPDB, it is now possible to show the information about an object using "?"
238 and "??", in much the same way it can be done when using the IPython prompt::
235 and "??", in much the same way it can be done when using the IPython prompt::
239
236
240 ipdb> partial?
237 ipdb> partial?
241 Init signature: partial(self, /, *args, **kwargs)
238 Init signature: partial(self, /, *args, **kwargs)
242 Docstring:
239 Docstring:
243 partial(func, *args, **keywords) - new function with partial application
240 partial(func, *args, **keywords) - new function with partial application
244 of the given arguments and keywords.
241 of the given arguments and keywords.
245 File: ~/.pyenv/versions/3.8.6/lib/python3.8/functools.py
242 File: ~/.pyenv/versions/3.8.6/lib/python3.8/functools.py
246 Type: type
243 Type: type
247 Subclasses:
244 Subclasses:
248
245
249 Previously, "pinfo" or "pinfo2" command had to be used for this purpose.
246 Previously, ``pinfo`` or ``pinfo2`` command had to be used for this purpose.
250
247
251
248
252 Autoreload 3 feature
249 Autoreload 3 feature
253 ~~~~~~~~~~~~~~~~~~~~
250 ~~~~~~~~~~~~~~~~~~~~
254
251
255 Example: When an IPython session is ran with the 'autoreload' extension loaded,
252 Example: When an IPython session is ran with the 'autoreload' extension loaded,
256 you will now have the option '3' to select which means the following:
253 you will now have the option '3' to select which means the following:
257
254
258 1. replicate all functionality from option 2
255 1. replicate all functionality from option 2
259 2. autoload all new funcs/classes/enums/globals from the module when they're added
256 2. autoload all new funcs/classes/enums/globals from the module when they are added
260 3. autoload all newly imported funcs/classes/enums/globals from external modules
257 3. autoload all newly imported funcs/classes/enums/globals from external modules
261
258
262 Try ``%autoreload 3`` in an IPython session after running ``%load_ext autoreload``
259 Try ``%autoreload 3`` in an IPython session after running ``%load_ext autoreload``
263
260
264 For more information please see unit test -
261 For more information please see the following unit test : ``extensions/tests/test_autoreload.py:test_autoload_newly_added_objects``
265 extensions/tests/test_autoreload.py : 'test_autoload_newly_added_objects'
266
262
267
263
268
264
269
265
270 History Range Glob feature
266 History Range Glob feature
271 ~~~~~~~~~~~~~~~~~~~~~~~~~~
267 ~~~~~~~~~~~~~~~~~~~~~~~~~~
272
268
273 Previously, when using ``%history``, users could specify either
269 Previously, when using ``%history``, users could specify either
274 a range of sessions and lines, for example:
270 a range of sessions and lines, for example:
275
271
276 .. code-block:: python
272 .. code-block:: python
277
273
278 ~8/1-~6/5 # see history from the first line of 8 sessions ago,
274 ~8/1-~6/5 # see history from the first line of 8 sessions ago,
279 # to the fifth line of 6 sessions ago.``
275 # to the fifth line of 6 sessions ago.``
280
276
281 Or users could specify a glob pattern:
277 Or users could specify a glob pattern:
282
278
283 .. code-block:: python
279 .. code-block:: python
284
280
285 -g <pattern> # glob ALL history for the specified pattern.
281 -g <pattern> # glob ALL history for the specified pattern.
286
282
287 However users could *not* specify both.
283 However users could *not* specify both.
288
284
289 If a user *did* specify both a range and a glob pattern,
285 If a user *did* specify both a range and a glob pattern,
290 then the glob pattern would be used (globbing *all* history) *and the range would be ignored*.
286 then the glob pattern would be used (globbing *all* history) *and the range would be ignored*.
291
287
292 With this enhancement, if a user specifies both a range and a glob pattern, then the glob pattern will be applied to the specified range of history.
288 With this enhancement, if a user specifies both a range and a glob pattern, then the glob pattern will be applied to the specified range of history.
293
289
294 Don't start a multi line cell with sunken parenthesis
290 Don't start a multi line cell with sunken parenthesis
295 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
291 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
296
292
297 From now on IPython will not ask for the next line of input when given a single
293 From now on IPython will not ask for the next line of input when given a single
298 line with more closing than opening brackets. For example, this means that if
294 line with more closing than opening brackets. For example, this means that if
299 you (mis)type ']]' instead of '[]', a ``SyntaxError`` will show up, instead of
295 you (mis)type ``]]`` instead of ``[]``, a ``SyntaxError`` will show up, instead of
300 the ``...:`` prompt continuation.
296 the ``...:`` prompt continuation.
301
297
302 IPython shell for ipdb interact
298 IPython shell for ipdb interact
303 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
299 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
304
300
305 The ipdb ``interact`` starts an IPython shell instead of Python's built-in ``code.interact()``.
301 The ipdb ``interact`` starts an IPython shell instead of Python's built-in ``code.interact()``.
306
302
307 Automatic Vi prompt stripping
303 Automatic Vi prompt stripping
308 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
304 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
309
305
310 When pasting code into IPython, it will strip the leading prompt characters if
306 When pasting code into IPython, it will strip the leading prompt characters if
311 there are any. For example, you can paste the following code into the console -
307 there are any. For example, you can paste the following code into the console -
312 it will still work, even though each line is prefixed with prompts (`In`,
308 it will still work, even though each line is prefixed with prompts (`In`,
313 `Out`)::
309 `Out`)::
314
310
315 In [1]: 2 * 2 == 4
311 In [1]: 2 * 2 == 4
316 Out[1]: True
312 Out[1]: True
317
313
318 In [2]: print("This still works as pasted")
314 In [2]: print("This still works as pasted")
319
315
320
316
321 Previously, this was not the case for the Vi-mode prompts::
317 Previously, this was not the case for the Vi-mode prompts::
322
318
323 In [1]: [ins] In [13]: 2 * 2 == 4
319 In [1]: [ins] In [13]: 2 * 2 == 4
324 ...: Out[13]: True
320 ...: Out[13]: True
325 ...:
321 ...:
326 File "<ipython-input-1-727bb88eaf33>", line 1
322 File "<ipython-input-1-727bb88eaf33>", line 1
327 [ins] In [13]: 2 * 2 == 4
323 [ins] In [13]: 2 * 2 == 4
328 ^
324 ^
329 SyntaxError: invalid syntax
325 SyntaxError: invalid syntax
330
326
331 This is now fixed, and Vi prompt prefixes - ``[ins]`` and ``[nav]`` - are
327 This is now fixed, and Vi prompt prefixes - ``[ins]`` and ``[nav]`` - are
332 skipped just as the normal ``In`` would be.
328 skipped just as the normal ``In`` would be.
333
329
334 IPython shell can be started in the Vi mode using ``ipython
330 IPython shell can be started in the Vi mode using ``ipython --TerminalInteractiveShell.editing_mode=vi``,
335 --TerminalInteractiveShell.editing_mode=vi``
331 You should be able to change mode dynamically with ``%config TerminalInteractiveShell.editing_mode='vi'``
336
332
337 Empty History Ranges
333 Empty History Ranges
338 ~~~~~~~~~~~~~~~~~~~~
334 ~~~~~~~~~~~~~~~~~~~~
339
335
340 A number of magics that take history ranges can now be used with an empty
336 A number of magics that take history ranges can now be used with an empty
341 range. These magics are:
337 range. These magics are:
342
338
343 * ``%save``
339 * ``%save``
344 * ``%load``
340 * ``%load``
345 * ``%pastebin``
341 * ``%pastebin``
346 * ``%pycat``
342 * ``%pycat``
347
343
348 Using them this way will make them take the history of the current session up
344 Using them this way will make them take the history of the current session up
349 to the point of the magic call (such that the magic itself will not be
345 to the point of the magic call (such that the magic itself will not be
350 included).
346 included).
351
347
352 Therefore it is now possible to save the whole history to a file using simple
348 Therefore it is now possible to save the whole history to a file using simple
353 ``%save <filename>``, load and edit it using ``%load`` (makes for a nice usage
349 ``%save <filename>``, load and edit it using ``%load`` (makes for a nice usage
354 when followed with :kbd:`F2`), send it to dpaste.org using ``%pastebin``, or
350 when followed with :kbd:`F2`), send it to dpaste.org using ``%pastebin``, or
355 view the whole thing syntax-highlighted with a single ``%pycat``.
351 view the whole thing syntax-highlighted with a single ``%pycat``.
356
352
357 Traceback improvements
353 Traceback improvements
358 ~~~~~~~~~~~~~~~~~~~~~~
354 ~~~~~~~~~~~~~~~~~~~~~~
359
355
360
356
361 UPDATE THIS IN INPUT.
362
363 Previously, error tracebacks for errors happening in code cells were showing a hash, the one used for compiling the Python AST::
357 Previously, error tracebacks for errors happening in code cells were showing a hash, the one used for compiling the Python AST::
364
358
365 In [1]: def foo():
359 In [1]: def foo():
366 ...: return 3 / 0
360 ...: return 3 / 0
367 ...:
361 ...:
368
362
369 In [2]: foo()
363 In [2]: foo()
370 ---------------------------------------------------------------------------
364 ---------------------------------------------------------------------------
371 ZeroDivisionError Traceback (most recent call last)
365 ZeroDivisionError Traceback (most recent call last)
372 <ipython-input-2-c19b6d9633cf> in <module>
366 <ipython-input-2-c19b6d9633cf> in <module>
373 ----> 1 foo()
367 ----> 1 foo()
374
368
375 <ipython-input-1-1595a74c32d5> in foo()
369 <ipython-input-1-1595a74c32d5> in foo()
376 1 def foo():
370 1 def foo():
377 ----> 2 return 3 / 0
371 ----> 2 return 3 / 0
378 3
372 3
379
373
380 ZeroDivisionError: division by zero
374 ZeroDivisionError: division by zero
381
375
382 The error traceback is now correctly formatted, showing the cell number in which the error happened::
376 The error traceback is now correctly formatted, showing the cell number in which the error happened::
383
377
384 In [1]: def foo():
378 In [1]: def foo():
385 ...: return 3 / 0
379 ...: return 3 / 0
386 ...:
380 ...:
387
381
388 Input In [2]: foo()
382 Input In [2]: foo()
389 ---------------------------------------------------------------------------
383 ---------------------------------------------------------------------------
390 ZeroDivisionError Traceback (most recent call last)
384 ZeroDivisionError Traceback (most recent call last)
391 input In [2], in <module>
385 input In [2], in <module>
392 ----> 1 foo()
386 ----> 1 foo()
393
387
394 Input In [1], in foo()
388 Input In [1], in foo()
395 1 def foo():
389 1 def foo():
396 ----> 2 return 3 / 0
390 ----> 2 return 3 / 0
397
391
398 ZeroDivisionError: division by zero
392 ZeroDivisionError: division by zero
399
393
400 Miscellaneous
394 Miscellaneous
401 ~~~~~~~~~~~~~
395 ~~~~~~~~~~~~~
402
396
403 - ``~`` is now expanded when part of a path in most magics :ghpull:`13385`
397 - ``~`` is now expanded when part of a path in most magics :ghpull:`13385`
404 - ``%/%%timeit`` magic now adds comma every thousands to make reading long number easier :ghpull:`13379`
398 - ``%/%%timeit`` magic now adds comma every thousands to make reading long number easier :ghpull:`13379`
405 - ``"info"`` messages can now be customised to hide some fields :ghpull:`13343`
399 - ``"info"`` messages can now be customised to hide some fields :ghpull:`13343`
406 - ``collections.UserList`` now pretty-prints :ghpull:`13320`
400 - ``collections.UserList`` now pretty-prints :ghpull:`13320`
407 - The debugger now have a persistent history, which should make it less
401 - The debugger now have a persistent history, which should make it less
408 annoying to retype commands :ghpull:`13246`
402 annoying to retype commands :ghpull:`13246`
409 - ``!pip`` ``!conda`` ``!cd`` or ``!ls`` are likely doing the wrong thing, we
403 - ``!pip`` ``!conda`` ``!cd`` or ``!ls`` are likely doing the wrong thing, we
410 now warn users if they use it. :ghpull:`12954`
404 now warn users if they use it. :ghpull:`12954`
411 - make ``%precision`` work for ``numpy.float64`` type :ghpull:`12902`
405 - make ``%precision`` work for ``numpy.float64`` type :ghpull:`12902`
412
406
413
407
414
408
415
409
416 Numfocus Small Developer Grant
410 Numfocus Small Developer Grant
417 ------------------------------
411 ------------------------------
418
412
419 To prepare for Python 3.10 we have also started working on removing reliance and
413 To prepare for Python 3.10 we have also started working on removing reliance and
420 any dependency that is not Python 3.10 compatible; that include migrating our
414 any dependency that is not Python 3.10 compatible; that include migrating our
421 test suite to pytest, and starting to remove nose. This also mean that the
415 test suite to pytest, and starting to remove nose. This also mean that the
422 ``iptest`` command is now gone, and all testing is via pytest.
416 ``iptest`` command is now gone, and all testing is via pytest.
423
417
424 This was in bog part thanks the NumFOCUS Small Developer grant, we were able to
418 This was in bog part thanks the NumFOCUS Small Developer grant, we were able to
425 allocate 4000 to hire `Nikita Kniazev @Kojoley <https://github.com/Kojoley>`__
419 allocate 4000 to hire `Nikita Kniazev (@Kojoley) <https://github.com/Kojoley>`__
426 who did a fantastic job at updating our code base, migrating to pytest, pushing
420 who did a fantastic job at updating our code base, migrating to pytest, pushing
427 our coverage, and fixing a large number of bugs. I highly recommend contacting
421 our coverage, and fixing a large number of bugs. I highly recommend contacting
428 them if you need help with C++ and Python projects
422 them if you need help with C++ and Python projects
429
423
430 You can find all relevant issues and PRs with the SDG 2021 tag:
424 You can find all relevant issues and PRs with the SDG 2021 tag `<https://github.com/ipython/ipython/issues?q=label%3A%22Numfocus+SDG+2021%22+>`__
431
432 https://github.com/ipython/ipython/issues?q=label%3A%22Numfocus+SDG+2021%22+
433
425
434 Removing support for Older Python
426 Removing support for Older Python
435 ---------------------------------
427 ---------------------------------
436
428
437
429
438 We are also removing support for Python up to 3.7 allowing internal code to use more
430 We are also removing support for Python up to 3.7 allowing internal code to use more
439 efficient ``pathlib``, and make better use of type annotations.
431 efficient ``pathlib``, and make better use of type annotations.
440
432
441 .. image:: ../_images/8.0/pathlib_pathlib_everywhere.jpg
433 .. image:: ../_images/8.0/pathlib_pathlib_everywhere.jpg
442 :alt: "Meme image of Toy story with Woody and Buzz, with the text 'pathlib, pathlib everywhere'"
434 :alt: "Meme image of Toy Story with Woody and Buzz, with the text 'pathlib, pathlib everywhere'"
443
435
444
436
445 IMAGE : Pathlib, pathlib everywhere.
446
447 We have about 34 PRs only to update some logic tu update some function from managing strings to
437 We have about 34 PRs only to update some logic tu update some function from managing strings to
448 using Pathlib.
438 using Pathlib.
449
439
450 The completer has also seen significant updates and make use of newer Jedi API
440 The completer has also seen significant updates and make use of newer Jedi API
451 offering faster and more reliable tab completion.
441 offering faster and more reliable tab completion.
452
442
453 For the terminal users this also enable the auto-suggestion feature, described
454 below, which show "ghost text" ahead of your cursor you can accept without
455 having to press the tab key or ask the completer to suggest completions.
456
457
458
443
459 .. DO NOT EDIT THIS LINE BEFORE RELEASE. FEATURE INSERTION POINT.
444 .. DO NOT EDIT THIS LINE BEFORE RELEASE. FEATURE INSERTION POINT.
460
445
461 As a reminder, IPython master has diverged from the 7.x branch, thus master may
446 As a reminder, IPython master has diverged from the 7.x branch, thus master may
462 have more feature and API changes.
447 have more feature and API changes.
463
448
464 Backwards incompatible changes
449 Backwards incompatible changes
465 ------------------------------
450 ------------------------------
466
451
467 .. DO NOT EDIT THIS LINE BEFORE RELEASE. INCOMPAT INSERTION POINT.
452 .. DO NOT EDIT THIS LINE BEFORE RELEASE. INCOMPAT INSERTION POINT.
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
General Comments 0
You need to be logged in to leave comments. Login now