Show More
@@ -13,8 +13,8 b'' | |||||
13 | from __future__ import print_function |
|
13 | from __future__ import print_function | |
14 |
|
14 | |||
15 | # Stdlib imports |
|
15 | # Stdlib imports | |
16 | import fnmatch |
|
|||
17 | import os |
|
16 | import os | |
|
17 | import re | |||
18 | import sqlite3 |
|
18 | import sqlite3 | |
19 |
|
19 | |||
20 | # Our own packages |
|
20 | # Our own packages | |
@@ -122,47 +122,15 b' class HistoryManager(Configurable):' | |||||
122 | self.db.execute("""UPDATE singletons SET value=? WHERE |
|
122 | self.db.execute("""UPDATE singletons SET value=? WHERE | |
123 | name='session_number'""", (self.session_number+1,)) |
|
123 | name='session_number'""", (self.session_number+1,)) | |
124 | self.db.commit() |
|
124 | self.db.commit() | |
125 |
|
||||
126 | def get_db_history(self, session, start=1, stop=None, raw=True): |
|
|||
127 | """Retrieve input history from the database by session. |
|
|||
128 |
|
||||
129 | Parameters |
|
|||
130 | ---------- |
|
|||
131 | session : int |
|
|||
132 | Session number to retrieve. If negative, counts back from current |
|
|||
133 | session (so -1 is previous session). |
|
|||
134 | start : int |
|
|||
135 | First line to retrieve. |
|
|||
136 | stop : int |
|
|||
137 | Last line to retrieve. If None, retrieve to the end of the session. |
|
|||
138 | raw : bool |
|
|||
139 | If True, return raw input |
|
|||
140 |
|
||||
141 | Returns |
|
|||
142 | ------- |
|
|||
143 | An iterator over the desired lines. |
|
|||
144 | """ |
|
|||
145 | toget = 'source_raw' if raw else 'source' |
|
|||
146 | if session < 0: |
|
|||
147 | session += self.session_number |
|
|||
148 |
|
||||
149 | if stop: |
|
|||
150 | cur = self.db.execute("SELECT " + toget + """ FROM history WHERE |
|
|||
151 | session==? AND line BETWEEN ? and ?""", |
|
|||
152 | (session, start, stop)) |
|
|||
153 | else: |
|
|||
154 | cur = self.db.execute("SELECT " + toget + """ FROM history WHERE |
|
|||
155 | session==? AND line>=?""", (session, start)) |
|
|||
156 | return (x[0] for x in cur) |
|
|||
157 |
|
125 | |||
158 |
def |
|
126 | def get_hist_tail(self, n=10, raw=True): | |
159 | """Get the last n lines from the history database.""" |
|
127 | """Get the last n lines from the history database.""" | |
160 | toget = 'source_raw' if raw else 'source' |
|
128 | toget = 'source_raw' if raw else 'source' | |
161 |
cur = self.db.execute("SELECT " + toget + |
|
129 | cur = self.db.execute("SELECT session, line, " + toget +\ | |
162 |
|
|
130 | " FROM history ORDER BY session DESC, line DESC LIMIT ?""", (n,)) | |
163 |
return |
|
131 | return reversed(cur.fetchall()) | |
164 |
|
132 | |||
165 |
def g |
|
133 | def get_hist_search(self, pattern="*", raw=True): | |
166 | """Search the database using unix glob-style matching (wildcards * and |
|
134 | """Search the database using unix glob-style matching (wildcards * and | |
167 | ?, escape using \). |
|
135 | ?, escape using \). | |
168 |
|
136 | |||
@@ -170,42 +138,14 b' class HistoryManager(Configurable):' | |||||
170 | ------- |
|
138 | ------- | |
171 | An iterator over tuples: (session, line_number, command) |
|
139 | An iterator over tuples: (session, line_number, command) | |
172 | """ |
|
140 | """ | |
173 | return self.db.execute("""SELECT session, line, source_raw FROM history |
|
141 | toget = "source_raw" if raw else source | |
174 | WHERE source_raw GLOB ?""", (pattern,)) |
|
142 | return self.db.execute("SELECT session, line, " +toget+ \ | |
175 |
|
143 | "FROM history WHERE" +toget+ "GLOB ?", (pattern,)) | ||
176 | def get_history(self, start=1, stop=None, raw=False, output=True): |
|
144 | ||
177 | """Get the history list. |
|
145 | def _get_hist_session(self, start=1, stop=None, raw=True, output=False): | |
178 |
|
146 | """Get input and output history from the current session. Called by | ||
179 | Get the input and output history. |
|
147 | get_history, and takes similar parameters.""" | |
180 |
|
148 | input_hist = self.input_hist_raw if raw else self.input_hist_parsed | ||
181 | Parameters |
|
|||
182 | ---------- |
|
|||
183 | start : int |
|
|||
184 | From (prompt number in the current session). Negative numbers count |
|
|||
185 | back from the end. |
|
|||
186 | stop : int |
|
|||
187 | To (prompt number in the current session, exclusive). Negative |
|
|||
188 | numbers count back from the end, and None goes to the end. |
|
|||
189 | raw : bool |
|
|||
190 | If True, return the raw input. |
|
|||
191 | output : bool |
|
|||
192 | If True, then return the output as well. |
|
|||
193 | this_session : bool |
|
|||
194 | If True, indexing is from 1 at the start of this session. |
|
|||
195 | If False, indexing is from 1 at the start of the whole history. |
|
|||
196 |
|
||||
197 | Returns |
|
|||
198 | ------- |
|
|||
199 | If output is True, then return a dict of tuples, keyed by the prompt |
|
|||
200 | numbers and with values of (input, output). If output is False, then |
|
|||
201 | a dict, keyed by the prompt number with the values of input. |
|
|||
202 | """ |
|
|||
203 | if raw: |
|
|||
204 | input_hist = self.input_hist_raw |
|
|||
205 | else: |
|
|||
206 | input_hist = self.input_hist_parsed |
|
|||
207 | if output: |
|
|||
208 | output_hist = self.output_hist |
|
|||
209 |
|
149 | |||
210 | n = len(input_hist) |
|
150 | n = len(input_hist) | |
211 | if start < 0: |
|
151 | if start < 0: | |
@@ -215,13 +155,69 b' class HistoryManager(Configurable):' | |||||
215 | elif stop < 0: |
|
155 | elif stop < 0: | |
216 | stop += n |
|
156 | stop += n | |
217 |
|
157 | |||
218 | hist = {} |
|
|||
219 | for i in range(start, stop): |
|
158 | for i in range(start, stop): | |
220 | if output: |
|
159 | if output: | |
221 |
|
|
160 | line = (input_hist[i], self.output_hist.get(i)) | |
222 | else: |
|
161 | else: | |
223 |
|
|
162 | line = input_hist[i] | |
224 | return hist |
|
163 | yield (0, i, line) | |
|
164 | ||||
|
165 | def get_history(self, session=0, start=1, stop=None, raw=True,output=False): | |||
|
166 | """Retrieve input by session. | |||
|
167 | ||||
|
168 | Parameters | |||
|
169 | ---------- | |||
|
170 | session : int | |||
|
171 | Session number to retrieve. The current session is 0, and negative | |||
|
172 | numbers count back from current session, so -1 is previous session. | |||
|
173 | start : int | |||
|
174 | First line to retrieve. | |||
|
175 | stop : int | |||
|
176 | Last line to retrieve. If None, retrieve to the end of the session. | |||
|
177 | raw : bool | |||
|
178 | If True, return untranslated input | |||
|
179 | output : bool | |||
|
180 | If True, attempt to include output. This will be 'real' Python | |||
|
181 | objects for the current session, or text reprs from previous | |||
|
182 | sessions if db_log_output was enabled at the time. Where no output | |||
|
183 | is found, None is used. | |||
|
184 | ||||
|
185 | Returns | |||
|
186 | ------- | |||
|
187 | An iterator over the desired lines. Each line is a 3-tuple, either | |||
|
188 | (session, line, input) if output is False, or | |||
|
189 | (session, line, (input, output)) if output is True. | |||
|
190 | """ | |||
|
191 | if session == 0 or session==self.session_number: # Current session | |||
|
192 | return self._get_hist_session(start, stop, raw, output) | |||
|
193 | if session < 0: | |||
|
194 | session += self.session_number | |||
|
195 | ||||
|
196 | # Assemble the SQL query: | |||
|
197 | sqlfrom = "history" | |||
|
198 | toget = 'source_raw' if raw else 'source' | |||
|
199 | if output: | |||
|
200 | sqlfrom = "history LEFT JOIN output_history USING (session, line)" | |||
|
201 | toget = "history.%s, output_history.output" % toget | |||
|
202 | if stop: | |||
|
203 | lineclause = "line BETWEEN ? and ?" | |||
|
204 | params = (session, start, stop) | |||
|
205 | else: | |||
|
206 | lineclause = "line>=?" | |||
|
207 | params = (session, start) | |||
|
208 | ||||
|
209 | cur = self.db.execute("SELECT %s FROM %s WHERE session==? AND %s"\ | |||
|
210 | %(toget, sqlfrom, lineclause), params) | |||
|
211 | if output: # Regroup into 3-tuples | |||
|
212 | return ((ses, lin (inp, out)) for ses, lin, inp, out in cur) | |||
|
213 | return cur | |||
|
214 | ||||
|
215 | def get_hist_from_rangestr(self, rangestr, raw=True, output=False): | |||
|
216 | """Get lines of history from a string of ranges, as used by magic | |||
|
217 | commands %hist, %save, %macro, etc.""" | |||
|
218 | for parts in extract_hist_ranges(rangestr): | |||
|
219 | for line in self.get_history(*parts, raw=raw, output=output): | |||
|
220 | yield line | |||
225 |
|
221 | |||
226 | def store_inputs(self, line_num, source, source_raw=None): |
|
222 | def store_inputs(self, line_num, source, source_raw=None): | |
227 | """Store source and raw input in history and create input cache |
|
223 | """Store source and raw input in history and create input cache | |
@@ -304,6 +300,52 b' class HistoryManager(Configurable):' | |||||
304 | self.output_hist.clear() |
|
300 | self.output_hist.clear() | |
305 | # The directory history can't be completely empty |
|
301 | # The directory history can't be completely empty | |
306 | self.dir_hist[:] = [os.getcwd()] |
|
302 | self.dir_hist[:] = [os.getcwd()] | |
|
303 | ||||
|
304 | # To match, e.g. ~5#8-~2#3 | |||
|
305 | range_re = re.compile(r""" | |||
|
306 | ((?P<startsess>~?\d+)\#)? | |||
|
307 | (?P<start>\d+) # Only the start line num is compulsory | |||
|
308 | ((?P<sep>[\-:]) | |||
|
309 | ((?P<endsess>~?\d+)\#)? | |||
|
310 | (?P<end>\d+))? | |||
|
311 | """, re.VERBOSE) | |||
|
312 | ||||
|
313 | def extract_hist_ranges(ranges_str): | |||
|
314 | """Turn a string of history ranges into 3-tuples of (session, start, stop). | |||
|
315 | ||||
|
316 | Examples | |||
|
317 | -------- | |||
|
318 | list(extract_input_ranges("~8#5-~7#4 2")) | |||
|
319 | [(-8, 5, None), (-7, 1, 4), (0, 2, 3)] | |||
|
320 | """ | |||
|
321 | print(ranges_str) | |||
|
322 | for range_str in ranges_str.split(): | |||
|
323 | rmatch = range_re.match(range_str) | |||
|
324 | start = int(rmatch.group("start")) | |||
|
325 | end = rmatch.group("end") | |||
|
326 | end = int(end) if end else start+1 # If no end specified, get (a, a+1) | |||
|
327 | if rmatch.group("sep") == "-": # 1-3 == 1:4 --> [1, 2, 3] | |||
|
328 | end += 1 | |||
|
329 | startsess = rmatch.group("startsess") or "0" | |||
|
330 | endsess = rmatch.group("endsess") or startsess | |||
|
331 | startsess = int(startsess.replace("~","-")) | |||
|
332 | endsess = int(endsess.replace("~","-")) | |||
|
333 | assert endsess >= startsess | |||
|
334 | ||||
|
335 | if endsess == startsess: | |||
|
336 | yield (startsess, start, end) | |||
|
337 | continue | |||
|
338 | # Multiple sessions in one range: | |||
|
339 | yield (startsess, start, None) | |||
|
340 | for sess in range(startsess+1, endsess): | |||
|
341 | yield (sess, 1, None) | |||
|
342 | yield (endsess, 1, end) | |||
|
343 | ||||
|
344 | def _format_lineno(session, line): | |||
|
345 | """Helper function to format line numbers properly.""" | |||
|
346 | if session == 0: | |||
|
347 | return str(line) | |||
|
348 | return "%s#%s" % (session, line) | |||
307 |
|
349 | |||
308 | @testdec.skip_doctest |
|
350 | @testdec.skip_doctest | |
309 | def magic_history(self, parameter_s = ''): |
|
351 | def magic_history(self, parameter_s = ''): | |
@@ -343,6 +385,9 b" def magic_history(self, parameter_s = ''):" | |||||
343 | -g: treat the arg as a pattern to grep for in (full) history. |
|
385 | -g: treat the arg as a pattern to grep for in (full) history. | |
344 | This includes the saved history (almost all commands ever written). |
|
386 | This includes the saved history (almost all commands ever written). | |
345 | Use '%hist -g' to show full saved history (may be very long). |
|
387 | Use '%hist -g' to show full saved history (may be very long). | |
|
388 | ||||
|
389 | -l: get the last n lines from all sessions. Specify n as a single arg, or | |||
|
390 | the default is the last 10 lines. | |||
346 |
|
391 | |||
347 | -f FILENAME: instead of printing the output to the screen, redirect it to |
|
392 | -f FILENAME: instead of printing the output to the screen, redirect it to | |
348 | the given file. The file is always overwritten, though IPython asks for |
|
393 | the given file. The file is always overwritten, though IPython asks for | |
@@ -361,7 +406,7 b" def magic_history(self, parameter_s = ''):" | |||||
361 | if not self.shell.displayhook.do_full_cache: |
|
406 | if not self.shell.displayhook.do_full_cache: | |
362 | print('This feature is only available if numbered prompts are in use.') |
|
407 | print('This feature is only available if numbered prompts are in use.') | |
363 | return |
|
408 | return | |
364 |
opts,args = self.parse_options(parameter_s,' |
|
409 | opts,args = self.parse_options(parameter_s,'noprtglf:',mode='string') | |
365 |
|
410 | |||
366 | # For brevity |
|
411 | # For brevity | |
367 | history_manager = self.shell.history_manager |
|
412 | history_manager = self.shell.history_manager | |
@@ -383,53 +428,52 b" def magic_history(self, parameter_s = ''):" | |||||
383 | close_at_end = True |
|
428 | close_at_end = True | |
384 |
|
429 | |||
385 | print_nums = 'n' in opts |
|
430 | print_nums = 'n' in opts | |
386 |
|
|
431 | get_output = 'o' in opts | |
387 | pyprompts = 'p' in opts |
|
432 | pyprompts = 'p' in opts | |
388 | # Raw history is the default |
|
433 | # Raw history is the default | |
389 | raw = not('t' in opts) |
|
434 | raw = not('t' in opts) | |
390 |
|
435 | |||
391 | default_length = 40 |
|
436 | default_length = 40 | |
392 | pattern = None |
|
437 | pattern = None | |
|
438 | ||||
|
439 | # Glob search: | |||
393 | if 'g' in opts: |
|
440 | if 'g' in opts: | |
394 | start = 1; stop = None |
|
441 | pattern = "*" + args + "*" if args else "*" | |
395 | parts = parameter_s.split(None, 1) |
|
|||
396 | if len(parts) == 1: |
|
|||
397 | parts += '*' |
|
|||
398 | head, pattern = parts |
|
|||
399 | pattern = "*" + pattern + "*" |
|
|||
400 | elif len(args) == 0: |
|
|||
401 | start = 1; stop = None |
|
|||
402 | elif len(args) == 1: |
|
|||
403 | start = -int(args[0]); stop=None |
|
|||
404 | elif len(args) == 2: |
|
|||
405 | start = int(args[0]); stop = int(args[1]) |
|
|||
406 | else: |
|
|||
407 | warn('%hist takes 0, 1 or 2 arguments separated by spaces.') |
|
|||
408 | print(self.magic_hist.__doc__, file=IPython.utils.io.Term.cout) |
|
|||
409 | return |
|
|||
410 |
|
442 | |||
411 | hist = history_manager.get_history(start, stop, raw, print_outputs) |
|
443 | # Display: | |
412 |
|
444 | matches_current_session = [] | ||
413 | width = len(str(max(hist.iterkeys()))) |
|
445 | for session, line, s in history_manager.get_hist_search(pattern, raw): | |
414 | line_sep = ['','\n'] |
|
446 | if session == history_manager.session_number: | |
415 |
|
447 | matches_current_session.append(line, s) | ||
416 | found = False |
|
448 | continue | |
417 | if pattern is not None: |
|
|||
418 | for session, line, s in history_manager.globsearch_db(pattern): |
|
|||
419 | print("%d#%d: %s" %(session, line, s.expandtabs(4)), file=outfile) |
|
449 | print("%d#%d: %s" %(session, line, s.expandtabs(4)), file=outfile) | |
420 | found = True |
|
450 | if matches_current_session: | |
|
451 | print("=== Current session: ===", file=outfile) | |||
|
452 | for line, s in matches_current_session: | |||
|
453 | print("%d: %s" %(line, s.expandtabs(4)), file=outfile) | |||
|
454 | return | |||
|
455 | ||||
|
456 | if 'l' in opts: # Get 'tail' | |||
|
457 | try: | |||
|
458 | n = int(args) | |||
|
459 | except ValueError, IndexError: | |||
|
460 | n = 10 | |||
|
461 | hist = history_manager.get_hist_tail(n, raw=raw) | |||
|
462 | else: | |||
|
463 | if args: # Get history by ranges | |||
|
464 | hist = history_manager.get_hist_from_rangestr(args, raw, get_output) | |||
|
465 | else: # Just get history for the current session | |||
|
466 | hist = history_manager.get_history(raw=raw, output=get_output) | |||
|
467 | # Pull hist into a list, so we can get the widest number in it. | |||
|
468 | hist = list(hist) | |||
421 |
|
469 | |||
422 | if found: |
|
470 | width = max(len(_format_lineno(s, l)) for s, l, _ in hist) | |
423 | print("===", file=outfile) |
|
|||
424 | print("shadow history ends, fetch by %rep session#line", |
|
|||
425 | file=outfile) |
|
|||
426 | print("=== start of normal history ===", file=outfile) |
|
|||
427 |
|
471 | |||
428 |
for |
|
472 | for session, lineno, inline in hist: | |
429 | # Print user history with tabs expanded to 4 spaces. The GUI clients |
|
473 | # Print user history with tabs expanded to 4 spaces. The GUI clients | |
430 | # use hard tabs for easier usability in auto-indented code, but we want |
|
474 | # use hard tabs for easier usability in auto-indented code, but we want | |
431 | # to produce PEP-8 compliant history for safe pasting into an editor. |
|
475 | # to produce PEP-8 compliant history for safe pasting into an editor. | |
432 |
if |
|
476 | if get_output: | |
433 | inline, output = inline |
|
477 | inline, output = inline | |
434 | inline = inline.expandtabs(4).rstrip() |
|
478 | inline = inline.expandtabs(4).rstrip() | |
435 |
|
479 | |||
@@ -437,15 +481,16 b" def magic_history(self, parameter_s = ''):" | |||||
437 | continue |
|
481 | continue | |
438 |
|
482 | |||
439 | multiline = "\n" in inline |
|
483 | multiline = "\n" in inline | |
|
484 | line_sep = '\n' if multiline else '' | |||
440 | if print_nums: |
|
485 | if print_nums: | |
441 |
print('%s:%s' % ( |
|
486 | print('%s:%s' % (_format_lineno(session, lineno).ljust(width), | |
442 | file=outfile, end='') |
|
487 | line_sep[multiline]), file=outfile, end='') | |
443 | if pyprompts: |
|
488 | if pyprompts: | |
444 | print(">>> ", end="", file=outfile) |
|
489 | print(">>> ", end="", file=outfile) | |
445 | if multiline: |
|
490 | if multiline: | |
446 | inline = "\n... ".join(inline.splitlines()) + "\n..." |
|
491 | inline = "\n... ".join(inline.splitlines()) + "\n..." | |
447 | print(inline, file=outfile) |
|
492 | print(inline, file=outfile) | |
448 |
if |
|
493 | if get_output and output: | |
449 | print(repr(output), file=outfile) |
|
494 | print(repr(output), file=outfile) | |
450 |
|
495 | |||
451 | if close_at_end: |
|
496 | if close_at_end: |
@@ -1551,7 +1551,7 b' class InteractiveShell(Configurable, Magic):' | |||||
1551 | readline.set_history_length(self.history_length) |
|
1551 | readline.set_history_length(self.history_length) | |
1552 |
|
1552 | |||
1553 | # Load the last 1000 lines from history |
|
1553 | # Load the last 1000 lines from history | |
1554 |
for cell in self.history_manager. |
|
1554 | for _, _, cell in self.history_manager.get_hist_tail(1000): | |
1555 | if cell.strip(): # Ignore blank lines |
|
1555 | if cell.strip(): # Ignore blank lines | |
1556 | for line in cell.splitlines(): |
|
1556 | for line in cell.splitlines(): | |
1557 | readline.add_history(line) |
|
1557 | readline.add_history(line) |
@@ -165,14 +165,15 b' python-profiler package from non-free.""")' | |||||
165 | out.sort() |
|
165 | out.sort() | |
166 | return out |
|
166 | return out | |
167 |
|
167 | |||
168 |
def extract_input_ |
|
168 | def extract_input_lines(self, range_str, raw=False): | |
169 | """Return as a string a set of input history slices. |
|
169 | """Return as a string a set of input history slices. | |
170 |
|
170 | |||
171 | Inputs: |
|
171 | Inputs: | |
172 |
|
172 | |||
173 |
- |
|
173 | - range_str: the set of slices is given as a string, like | |
174 |
|
|
174 | "~5#6-~4#2 4:8 9", since this function is for use by magic functions | |
175 | which get their arguments as strings. |
|
175 | which get their arguments as strings. The number before the # is the | |
|
176 | session number: ~n goes n back from the current session. | |||
176 |
|
177 | |||
177 | Optional inputs: |
|
178 | Optional inputs: | |
178 |
|
179 | |||
@@ -184,21 +185,9 b' python-profiler package from non-free.""")' | |||||
184 | N:M -> standard python form, means including items N...(M-1). |
|
185 | N:M -> standard python form, means including items N...(M-1). | |
185 |
|
186 | |||
186 | N-M -> include items N..M (closed endpoint).""" |
|
187 | N-M -> include items N..M (closed endpoint).""" | |
187 |
|
|
188 | lines = self.shell.history_manager.\ | |
188 |
|
189 | get_hist_from_rangestr(range_str, raw=raw) | ||
189 | cmds = [] |
|
190 | return "\n".join(x for _, _, x in lines) | |
190 | for chunk in slices: |
|
|||
191 | if ':' in chunk: |
|
|||
192 | ini,fin = map(int,chunk.split(':')) |
|
|||
193 | elif '-' in chunk: |
|
|||
194 | ini,fin = map(int,chunk.split('-')) |
|
|||
195 | fin += 1 |
|
|||
196 | else: |
|
|||
197 | ini = int(chunk) |
|
|||
198 | fin = ini+1 |
|
|||
199 | hist = history_manager.get_history((ini,fin), raw=raw, output=False) |
|
|||
200 | cmds.append('\n'.join(hist[i] for i in sorted(hist.iterkeys()))) |
|
|||
201 | return cmds |
|
|||
202 |
|
191 | |||
203 | def arg_err(self,func): |
|
192 | def arg_err(self,func): | |
204 | """Print docstring if incorrect arguments were passed""" |
|
193 | """Print docstring if incorrect arguments were passed""" | |
@@ -2036,11 +2025,11 b' Currently the magic system has the following functions:\\n"""' | |||||
2036 | if len(args) == 1: |
|
2025 | if len(args) == 1: | |
2037 | raise UsageError( |
|
2026 | raise UsageError( | |
2038 | "%macro insufficient args; usage '%macro name n1-n2 n3-4...") |
|
2027 | "%macro insufficient args; usage '%macro name n1-n2 n3-4...") | |
2039 | name,ranges = args[0], args[1:] |
|
2028 | name, ranges = args[0], " ".join(args[1:]) | |
2040 |
|
2029 | |||
2041 | #print 'rng',ranges # dbg |
|
2030 | #print 'rng',ranges # dbg | |
2042 |
lines = self.extract_input_ |
|
2031 | lines = self.extract_input_lines(ranges,'r' in opts) | |
2043 |
macro = Macro( |
|
2032 | macro = Macro(lines) | |
2044 | self.shell.define_macro(name, macro) |
|
2033 | self.shell.define_macro(name, macro) | |
2045 | print 'Macro `%s` created. To execute, type its name (without quotes).' % name |
|
2034 | print 'Macro `%s` created. To execute, type its name (without quotes).' % name | |
2046 | print 'Macro contents:' |
|
2035 | print 'Macro contents:' | |
@@ -2067,7 +2056,7 b' Currently the magic system has the following functions:\\n"""' | |||||
2067 | it asks for confirmation before overwriting existing files.""" |
|
2056 | it asks for confirmation before overwriting existing files.""" | |
2068 |
|
2057 | |||
2069 | opts,args = self.parse_options(parameter_s,'r',mode='list') |
|
2058 | opts,args = self.parse_options(parameter_s,'r',mode='list') | |
2070 | fname,ranges = args[0], args[1:] |
|
2059 | fname,ranges = args[0], " ".join(args[1:]) | |
2071 | if not fname.endswith('.py'): |
|
2060 | if not fname.endswith('.py'): | |
2072 | fname += '.py' |
|
2061 | fname += '.py' | |
2073 | if os.path.isfile(fname): |
|
2062 | if os.path.isfile(fname): | |
@@ -2075,7 +2064,7 b' Currently the magic system has the following functions:\\n"""' | |||||
2075 | if ans.lower() not in ['y','yes']: |
|
2064 | if ans.lower() not in ['y','yes']: | |
2076 | print 'Operation cancelled.' |
|
2065 | print 'Operation cancelled.' | |
2077 | return |
|
2066 | return | |
2078 |
cmds = |
|
2067 | cmds = self.extract_input_lines(ranges, 'r' in opts) | |
2079 | with open(fname,'w') as f: |
|
2068 | with open(fname,'w') as f: | |
2080 | f.write(cmds) |
|
2069 | f.write(cmds) | |
2081 | print 'The following commands were written to file `%s`:' % fname |
|
2070 | print 'The following commands were written to file `%s`:' % fname | |
@@ -2261,13 +2250,13 b' Currently the magic system has the following functions:\\n"""' | |||||
2261 |
|
2250 | |||
2262 | opts,args = self.parse_options(parameter_s,'prxn:') |
|
2251 | opts,args = self.parse_options(parameter_s,'prxn:') | |
2263 | # Set a few locals from the options for convenience: |
|
2252 | # Set a few locals from the options for convenience: | |
2264 |
opts_p = |
|
2253 | opts_prev = 'p' in opts | |
2265 |
opts_r = |
|
2254 | opts_raw = 'r' in opts | |
2266 |
|
2255 | |||
2267 | # Default line number value |
|
2256 | # Default line number value | |
2268 | lineno = opts.get('n',None) |
|
2257 | lineno = opts.get('n',None) | |
2269 |
|
2258 | |||
2270 | if opts_p: |
|
2259 | if opts_prev: | |
2271 | args = '_%s' % last_call[0] |
|
2260 | args = '_%s' % last_call[0] | |
2272 | if not self.shell.user_ns.has_key(args): |
|
2261 | if not self.shell.user_ns.has_key(args): | |
2273 | args = last_call[1] |
|
2262 | args = last_call[1] | |
@@ -2276,7 +2265,7 b' Currently the magic system has the following functions:\\n"""' | |||||
2276 | # let it be clobbered by successive '-p' calls. |
|
2265 | # let it be clobbered by successive '-p' calls. | |
2277 | try: |
|
2266 | try: | |
2278 | last_call[0] = self.shell.displayhook.prompt_count |
|
2267 | last_call[0] = self.shell.displayhook.prompt_count | |
2279 | if not opts_p: |
|
2268 | if not opts_prev: | |
2280 | last_call[1] = parameter_s |
|
2269 | last_call[1] = parameter_s | |
2281 | except: |
|
2270 | except: | |
2282 | pass |
|
2271 | pass | |
@@ -2290,8 +2279,7 b' Currently the magic system has the following functions:\\n"""' | |||||
2290 | # Mode where user specifies ranges of lines, like in %macro. |
|
2279 | # Mode where user specifies ranges of lines, like in %macro. | |
2291 | # This means that you can't edit files whose names begin with |
|
2280 | # This means that you can't edit files whose names begin with | |
2292 | # numbers this way. Tough. |
|
2281 | # numbers this way. Tough. | |
2293 | ranges = args.split() |
|
2282 | data = self.extract_input_lines(args, opts_raw) | |
2294 | data = '\n'.join(self.extract_input_slices(ranges,opts_r)) |
|
|||
2295 | elif args.endswith('.py'): |
|
2283 | elif args.endswith('.py'): | |
2296 | filename = make_filename(args) |
|
2284 | filename = make_filename(args) | |
2297 | use_temp = False |
|
2285 | use_temp = False |
General Comments 0
You need to be logged in to leave comments.
Login now