Show More
@@ -87,6 +87,14 b' else:' | |||||
87 |
|
87 | |||
88 | _use_simple_prompt = ('IPY_TEST_SIMPLE_PROMPT' in os.environ) or (not _is_tty) |
|
88 | _use_simple_prompt = ('IPY_TEST_SIMPLE_PROMPT' in os.environ) or (not _is_tty) | |
89 |
|
89 | |||
|
90 | def black_reformat_handler(text_before_cursor): | |||
|
91 | import black | |||
|
92 | formatted_text = black.format_str(text_before_cursor, mode=black.FileMode()) | |||
|
93 | if not text_before_cursor.endswith('\n') and formatted_text.endswith('\n'): | |||
|
94 | formatted_text = formatted_text[:-1] | |||
|
95 | return formatted_text | |||
|
96 | ||||
|
97 | ||||
90 | class TerminalInteractiveShell(InteractiveShell): |
|
98 | class TerminalInteractiveShell(InteractiveShell): | |
91 | space_for_menu = Integer(6, help='Number of line at the bottom of the screen ' |
|
99 | space_for_menu = Integer(6, help='Number of line at the bottom of the screen ' | |
92 | 'to reserve for the completion menu' |
|
100 | 'to reserve for the completion menu' | |
@@ -120,6 +128,11 b' class TerminalInteractiveShell(InteractiveShell):' | |||||
120 | help="Shortcut style to use at the prompt. 'vi' or 'emacs'.", |
|
128 | help="Shortcut style to use at the prompt. 'vi' or 'emacs'.", | |
121 | ).tag(config=True) |
|
129 | ).tag(config=True) | |
122 |
|
130 | |||
|
131 | autoformatter = Unicode(None, | |||
|
132 | help="Autoformatter to reformat Terminal code. Can be `'black'` or `None`", | |||
|
133 | allow_none=True | |||
|
134 | ).tag(config=True) | |||
|
135 | ||||
123 | mouse_support = Bool(False, |
|
136 | mouse_support = Bool(False, | |
124 | help="Enable mouse support in the prompt\n(Note: prevents selecting text with the mouse)" |
|
137 | help="Enable mouse support in the prompt\n(Note: prevents selecting text with the mouse)" | |
125 | ).tag(config=True) |
|
138 | ).tag(config=True) | |
@@ -150,6 +163,16 b' class TerminalInteractiveShell(InteractiveShell):' | |||||
150 | if self.pt_app: |
|
163 | if self.pt_app: | |
151 | self.pt_app.editing_mode = u_mode |
|
164 | self.pt_app.editing_mode = u_mode | |
152 |
|
165 | |||
|
166 | @observe('autoformatter') | |||
|
167 | def _autoformatter_changed(self, change): | |||
|
168 | formatter = change.new | |||
|
169 | if formatter is None: | |||
|
170 | self.reformat_handler = lambda x:x | |||
|
171 | elif formatter == 'black': | |||
|
172 | self.reformat_handler = black_reformat_handler | |||
|
173 | else: | |||
|
174 | raise ValueError | |||
|
175 | ||||
153 | @observe('highlighting_style') |
|
176 | @observe('highlighting_style') | |
154 | @observe('colors') |
|
177 | @observe('colors') | |
155 | def _highlighting_style_changed(self, change): |
|
178 | def _highlighting_style_changed(self, change): | |
@@ -246,6 +269,7 b' class TerminalInteractiveShell(InteractiveShell):' | |||||
246 | self.display_formatter.ipython_display_formatter.enabled = False |
|
269 | self.display_formatter.ipython_display_formatter.enabled = False | |
247 |
|
270 | |||
248 | def init_prompt_toolkit_cli(self): |
|
271 | def init_prompt_toolkit_cli(self): | |
|
272 | self.reformat_handler = lambda x:x | |||
249 | if self.simple_prompt: |
|
273 | if self.simple_prompt: | |
250 | # Fall back to plain non-interactive output for tests. |
|
274 | # Fall back to plain non-interactive output for tests. | |
251 | # This is very limited. |
|
275 | # This is very limited. |
@@ -44,6 +44,15 b' def create_ipython_shortcuts(shell):' | |||||
44 | & insert_mode |
|
44 | & insert_mode | |
45 | ))(return_handler) |
|
45 | ))(return_handler) | |
46 |
|
46 | |||
|
47 | def reformat_and_execute(event): | |||
|
48 | reformat_text_before_cursor(event.current_buffer, event.current_buffer.document, shell) | |||
|
49 | event.current_buffer.validate_and_handle() | |||
|
50 | ||||
|
51 | kb.add('escape', 'enter', filter=(has_focus(DEFAULT_BUFFER) | |||
|
52 | & ~has_selection | |||
|
53 | & insert_mode | |||
|
54 | ))(reformat_and_execute) | |||
|
55 | ||||
47 | kb.add('c-\\')(force_exit) |
|
56 | kb.add('c-\\')(force_exit) | |
48 |
|
57 | |||
49 | kb.add('c-p', filter=(vi_insert_mode & has_focus(DEFAULT_BUFFER)) |
|
58 | kb.add('c-p', filter=(vi_insert_mode & has_focus(DEFAULT_BUFFER)) | |
@@ -86,24 +95,21 b' def create_ipython_shortcuts(shell):' | |||||
86 | return kb |
|
95 | return kb | |
87 |
|
96 | |||
88 |
|
97 | |||
|
98 | def reformat_text_before_cursor(buffer, document, shell): | |||
|
99 | text = buffer.delete_before_cursor(len(document.text[:document.cursor_position])) | |||
|
100 | try: | |||
|
101 | formatted_text = shell.reformat_handler(text) | |||
|
102 | buffer.insert_text(formatted_text) | |||
|
103 | except Exception as e: | |||
|
104 | buffer.insert_text(text) | |||
|
105 | ||||
|
106 | ||||
89 | def newline_or_execute_outer(shell): |
|
107 | def newline_or_execute_outer(shell): | |
90 |
|
108 | |||
91 | import black |
|
|||
92 | def newline_or_execute(event): |
|
109 | def newline_or_execute(event): | |
93 | """When the user presses return, insert a newline or execute the code.""" |
|
110 | """When the user presses return, insert a newline or execute the code.""" | |
94 | b = event.current_buffer |
|
111 | b = event.current_buffer | |
95 | d = b.document |
|
112 | d = b.document | |
96 | def try_reformat(): |
|
|||
97 | try: |
|
|||
98 | tbc = b.delete_before_cursor(len(d.text[:d.cursor_position])) |
|
|||
99 | fmt= black.format_str(tbc, mode=black.FileMode()) |
|
|||
100 | if not tbc.endswith('\n') and fmt.endswith('\n'): |
|
|||
101 | fmt = fmt[:-1] |
|
|||
102 | b.insert_text(fmt) |
|
|||
103 | #print(f'no eexc |{tbc[-1]}|,|{d.text[-1]}|, |{fmt[-3:-1]}|') |
|
|||
104 | except Exception as e: |
|
|||
105 | b.insert_text(tbc) |
|
|||
106 |
|
||||
107 |
|
113 | |||
108 | if b.complete_state: |
|
114 | if b.complete_state: | |
109 | cc = b.complete_state.current_completion |
|
115 | cc = b.complete_state.current_completion | |
@@ -120,7 +126,11 b' def newline_or_execute_outer(shell):' | |||||
120 | else: |
|
126 | else: | |
121 | check_text = d.text[:d.cursor_position] |
|
127 | check_text = d.text[:d.cursor_position] | |
122 | status, indent = shell.check_complete(check_text) |
|
128 | status, indent = shell.check_complete(check_text) | |
123 |
|
129 | |||
|
130 | # if all we have after the cursor is whitespace: reformat current text | |||
|
131 | # before cursor | |||
|
132 | if d.text[d.cursor_position:].isspace(): | |||
|
133 | reformat_text_before_cursor(b, d, shell) | |||
124 | if not (d.on_last_line or |
|
134 | if not (d.on_last_line or | |
125 | d.cursor_position_row >= d.line_count - d.empty_line_count_at_the_end() |
|
135 | d.cursor_position_row >= d.line_count - d.empty_line_count_at_the_end() | |
126 | ): |
|
136 | ): | |
@@ -131,11 +141,10 b' def newline_or_execute_outer(shell):' | |||||
131 | return |
|
141 | return | |
132 |
|
142 | |||
133 | if (status != 'incomplete') and b.accept_handler: |
|
143 | if (status != 'incomplete') and b.accept_handler: | |
134 | try_reformat() |
|
144 | reformat_text_before_cursor(b, d, shell) | |
135 | b.validate_and_handle() |
|
145 | b.validate_and_handle() | |
136 | else: |
|
146 | else: | |
137 | if shell.autoindent: |
|
147 | if shell.autoindent: | |
138 | try_reformat() |
|
|||
139 | b.insert_text('\n' + indent) |
|
148 | b.insert_text('\n' + indent) | |
140 | else: |
|
149 | else: | |
141 | b.insert_text('\n') |
|
150 | b.insert_text('\n') |
General Comments 0
You need to be logged in to leave comments.
Login now