Show More
@@ -87,6 +87,14 b' else:' | |||
|
87 | 87 | |
|
88 | 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 | 98 | class TerminalInteractiveShell(InteractiveShell): |
|
91 | 99 | space_for_menu = Integer(6, help='Number of line at the bottom of the screen ' |
|
92 | 100 | 'to reserve for the completion menu' |
@@ -120,6 +128,11 b' class TerminalInteractiveShell(InteractiveShell):' | |||
|
120 | 128 | help="Shortcut style to use at the prompt. 'vi' or 'emacs'.", |
|
121 | 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 | 136 | mouse_support = Bool(False, |
|
124 | 137 | help="Enable mouse support in the prompt\n(Note: prevents selecting text with the mouse)" |
|
125 | 138 | ).tag(config=True) |
@@ -150,6 +163,16 b' class TerminalInteractiveShell(InteractiveShell):' | |||
|
150 | 163 | if self.pt_app: |
|
151 | 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 | 176 | @observe('highlighting_style') |
|
154 | 177 | @observe('colors') |
|
155 | 178 | def _highlighting_style_changed(self, change): |
@@ -246,6 +269,7 b' class TerminalInteractiveShell(InteractiveShell):' | |||
|
246 | 269 | self.display_formatter.ipython_display_formatter.enabled = False |
|
247 | 270 | |
|
248 | 271 | def init_prompt_toolkit_cli(self): |
|
272 | self.reformat_handler = lambda x:x | |
|
249 | 273 | if self.simple_prompt: |
|
250 | 274 | # Fall back to plain non-interactive output for tests. |
|
251 | 275 | # This is very limited. |
@@ -44,6 +44,15 b' def create_ipython_shortcuts(shell):' | |||
|
44 | 44 | & insert_mode |
|
45 | 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 | 56 | kb.add('c-\\')(force_exit) |
|
48 | 57 | |
|
49 | 58 | kb.add('c-p', filter=(vi_insert_mode & has_focus(DEFAULT_BUFFER)) |
@@ -86,24 +95,21 b' def create_ipython_shortcuts(shell):' | |||
|
86 | 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 | 107 | def newline_or_execute_outer(shell): |
|
90 | 108 | |
|
91 | import black | |
|
92 | 109 | def newline_or_execute(event): |
|
93 | 110 | """When the user presses return, insert a newline or execute the code.""" |
|
94 | 111 | b = event.current_buffer |
|
95 | 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 | 114 | if b.complete_state: |
|
109 | 115 | cc = b.complete_state.current_completion |
@@ -121,6 +127,10 b' def newline_or_execute_outer(shell):' | |||
|
121 | 127 | check_text = d.text[:d.cursor_position] |
|
122 | 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 | 134 | if not (d.on_last_line or |
|
125 | 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 | 141 | return |
|
132 | 142 | |
|
133 | 143 | if (status != 'incomplete') and b.accept_handler: |
|
134 | try_reformat() | |
|
144 | reformat_text_before_cursor(b, d, shell) | |
|
135 | 145 | b.validate_and_handle() |
|
136 | 146 | else: |
|
137 | 147 | if shell.autoindent: |
|
138 | try_reformat() | |
|
139 | 148 | b.insert_text('\n' + indent) |
|
140 | 149 | else: |
|
141 | 150 | b.insert_text('\n') |
General Comments 0
You need to be logged in to leave comments.
Login now