##// END OF EJS Templates
Refactor multiline input and prompt management.
Fernando Perez -
Show More
1 NO CONTENT: modified file chmod 100644 => 100755
@@ -54,8 +54,9 b' class DisplayHook(Configurable):'
54 54 """
55 55
56 56 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
57
57 58 # Each call to the In[] prompt raises it by 1, even the first.
58 prompt_count = Int(0)
59 #prompt_count = Int(0)
59 60
60 61 def __init__(self, shell=None, cache_size=1000,
61 62 colors='NoColor', input_sep='\n',
@@ -114,6 +115,14 b' class DisplayHook(Configurable):'
114 115 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
115 116 self.shell.user_ns.update(to_user_ns)
116 117
118 @property
119 def prompt_count(self):
120 return self.shell.execution_count
121
122 @prompt_count.setter
123 def _set_prompt_count(self, val):
124 raise ValueError('prompt count is read only')
125
117 126 def _set_prompt_str(self,p_str,cache_def,no_cache_def):
118 127 if p_str is None:
119 128 if self.do_full_cache:
@@ -397,6 +397,9 b' class InteractiveShell(Configurable, Magic):'
397 397 # Indentation management
398 398 self.indent_current_nsp = 0
399 399
400 # Increasing execution counter
401 self.execution_count = 0
402
400 403 def init_environment(self):
401 404 """Any changes we need to make to the user's environment."""
402 405 pass
@@ -978,6 +981,9 b' class InteractiveShell(Configurable, Magic):'
978 981 self.input_hist_raw[:] = []
979 982 self.output_hist.clear()
980 983
984 # Reset counter used to index all histories
985 self.execution_count = 0
986
981 987 # Restore the user namespaces to minimal usability
982 988 self.init_user_ns()
983 989
@@ -2187,42 +2193,68 b' class InteractiveShell(Configurable, Magic):'
2187 2193 # original cell may contain non-python syntax).
2188 2194 ipy_cell = ''.join(blocks)
2189 2195
2196 # Each cell is a *single* input, regardless of how many lines it has
2197 self.execution_count += 1
2198
2199 # Store raw and processed history
2200 self.input_hist_raw.append(cell)
2201 self.input_hist.append(ipy_cell)
2202
2203 # All user code execution must happen with our context managers active
2204 with nested(self.builtin_trap, self.display_trap):
2190 2205 # Single-block input should behave like an interactive prompt
2191 2206 if len(blocks) == 1:
2192 self.runlines(blocks[0])
2193 return
2207 return self.run_one_block(blocks[0])
2194 2208
2195 # In multi-block input, if the last block is a simple (one-two lines)
2196 # expression, run it in single mode so it produces output. Otherwise
2197 # just feed the whole thing to runcode.
2198 # This seems like a reasonable usability design.
2209 # In multi-block input, if the last block is a simple (one-two
2210 # lines) expression, run it in single mode so it produces output.
2211 # Otherwise just feed the whole thing to runcode. This seems like
2212 # a reasonable usability design.
2199 2213 last = blocks[-1]
2200 2214 last_nlines = len(last.splitlines())
2201 2215
2202 2216 # Note: below, whenever we call runcode, we must sync history
2203 2217 # ourselves, because runcode is NOT meant to manage history at all.
2204 2218 if last_nlines < 2:
2205 # Here we consider the cell split between 'body' and 'last', store
2206 # all history and execute 'body', and if successful, then proceed
2207 # to execute 'last'.
2219 # Here we consider the cell split between 'body' and 'last',
2220 # store all history and execute 'body', and if successful, then
2221 # proceed to execute 'last'.
2208 2222
2209 # Raw history must contain the unmodified cell
2210 raw_body = '\n'.join(cell.splitlines()[:-last_nlines])+'\n'
2211 self.input_hist_raw.append(raw_body)
2212 2223 # Get the main body to run as a cell
2213 2224 ipy_body = ''.join(blocks[:-1])
2214 self.input_hist.append(ipy_body)
2215 2225 retcode = self.runcode(ipy_body, post_execute=False)
2216 2226 if retcode==0:
2217 2227 # And the last expression via runlines so it produces output
2218 self.runlines(last)
2228 self.run_one_block(last)
2219 2229 else:
2220 # Run the whole cell as one entity, storing both raw and processed
2221 # input in history
2222 self.input_hist_raw.append(cell)
2223 self.input_hist.append(ipy_cell)
2230 # Run the whole cell as one entity, storing both raw and
2231 # processed input in history
2224 2232 self.runcode(ipy_cell)
2225 2233
2234 def run_one_block(self, block):
2235 """Run a single interactive block.
2236
2237 If the block is single-line, dynamic transformations are applied to it
2238 (like automagics, autocall and alias recognition).
2239 """
2240 if len(block.splitlines()) <= 1:
2241 out = self.run_single_line(block)
2242 else:
2243 out = self.runcode(block)
2244 return out
2245
2246 def run_single_line(self, line):
2247 """Run a single-line interactive statement.
2248
2249 This assumes the input has been transformed to IPython syntax by
2250 applying all static transformations (those with an explicit prefix like
2251 % or !), but it will further try to apply the dynamic ones.
2252
2253 It does not update history.
2254 """
2255 tline = self.prefilter_manager.prefilter_line(line)
2256 return self.runsource(tline)
2257
2226 2258 def runlines(self, lines, clean=False):
2227 2259 """Run a string of one or more lines of source.
2228 2260
@@ -2421,6 +2453,7 b' class InteractiveShell(Configurable, Magic):'
2421 2453 more = self.runsource('\n'.join(self.buffer), self.filename)
2422 2454 if not more:
2423 2455 self.resetbuffer()
2456 self.execution_count += 1
2424 2457 return more
2425 2458
2426 2459 def resetbuffer(self):
@@ -214,9 +214,11 b' which already exists. But you must first start the logging process with'
214 214 # but if the opposite is true (a macro can produce multiple inputs
215 215 # with no output display called), then bring the output counter in
216 216 # sync:
217 last_num = len(input_hist)-1
218 if in_num != last_num:
219 in_num = self.shell.displayhook.prompt_count = last_num
217 ## last_num = len(input_hist)-1
218 ## if in_num != last_num:
219 ## pass # dbg
220 ## #in_num = self.shell.execution_count = last_num
221
220 222 new_i = '_i%s' % in_num
221 223 if continuation:
222 224 self._i00 = '%s%s\n' % (self.shell.user_ns[new_i],line_mod)
@@ -372,15 +372,7 b' class Prompt1(BasePrompt):'
372 372 self.col_p_ni = self.col_p.replace('\001','').replace('\002','')
373 373 self.col_norm_ni = Colors.normal
374 374
375 def peek_next_prompt(self):
376 """Get the next prompt, but don't increment the counter."""
377 self.cache.prompt_count += 1
378 next_prompt = str_safe(self.p_str)
379 self.cache.prompt_count -= 1
380 return next_prompt
381
382 375 def __str__(self):
383 self.cache.prompt_count += 1
384 376 self.cache.last_prompt = str_safe(self.p_str_nocolor).split('\n')[-1]
385 377 return str_safe(self.p_str)
386 378
@@ -228,6 +228,11 b' class TerminalInteractiveShell(InteractiveShell):'
228 228 # exit_now is set by a call to %Exit or %Quit, through the
229 229 # ask_exit callback.
230 230
231 # Before showing any prompts, if the counter is at zero, we execute an
232 # empty line to ensure the user only sees prompts starting at one.
233 if self.execution_count == 0:
234 self.push_line('\n')
235
231 236 while not self.exit_now:
232 237 self.hooks.pre_prompt_hook()
233 238 if more:
@@ -238,8 +238,9 b' class Kernel(Configurable):'
238 238 status = u'ok'
239 239
240 240 reply_content[u'status'] = status
241 # Compute the execution counter so clients can display prompts
242 reply_content['execution_count'] = shell.displayhook.prompt_count
241
242 # Return the execution counter so clients can display prompts
243 reply_content['execution_count'] = shell.execution_count
243 244
244 245 # FIXME - fish exception info out of shell, possibly left there by
245 246 # runlines. We'll need to clean up this logic later.
General Comments 0
You need to be logged in to leave comments. Login now