From 30eccbc36fdb860bccbbd6b7ecb226203f0d386f 2011-10-16 21:59:17 From: Julian Taylor Date: 2011-10-16 21:59:17 Subject: [PATCH] reenable multiline history for terminals Add configuration variable InteractiveShell.multiline_history. If it is True cells spanning multiple lines will be saved in history as a single entry instead of one entry per line, as was the case in ipython < 0.11. closes gh-571 --- diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index c621b58..50425e4 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -307,6 +307,9 @@ class InteractiveShell(SingletonConfigurable, Magic): Automatically call the pdb debugger after every exception. """ ) + multiline_history = CBool(False, config=True, + help="Store multiple line spanning cells as a single entry in history." + ) prompt_in1 = Unicode('In [\\#]: ', config=True) prompt_in2 = Unicode(' .\\D.: ', config=True) @@ -1721,9 +1724,13 @@ class InteractiveShell(SingletonConfigurable, Magic): for _, _, cell in self.history_manager.get_tail(1000, include_latest=True): if cell.strip(): # Ignore blank lines - for line in cell.splitlines(): - self.readline.add_history(py3compat.unicode_to_str(line, - stdin_encoding)) + if self.multiline_history: + self.readline.add_history(py3compat.unicode_to_str(cell.rstrip(), + stdin_encoding)) + else: + for line in cell.splitlines(): + self.readline.add_history(py3compat.unicode_to_str(line, + stdin_encoding)) def set_next_input(self, s): """ Sets the 'default' input string for the next command line. diff --git a/IPython/frontend/terminal/interactiveshell.py b/IPython/frontend/terminal/interactiveshell.py index 22a4651..cd3e2f6 100644 --- a/IPython/frontend/terminal/interactiveshell.py +++ b/IPython/frontend/terminal/interactiveshell.py @@ -229,6 +229,15 @@ class TerminalInteractiveShell(InteractiveShell): # handling seems rather unpredictable... self.write("\nKeyboardInterrupt in interact()\n") + def _store_multiline_history(self, source_raw): + """Store multiple lines as a single entry in history""" + if self.multiline_history and self.has_readline: + hlen = self.readline.get_current_history_length() + lines = len(source_raw.splitlines()) + for i in range(1, min(hlen, lines) + 1): + self.readline.remove_history_item(hlen - i) + self.readline.add_history(source_raw.rstrip()) + def interact(self, display_banner=None): """Closely emulate the interactive Python console.""" @@ -281,7 +290,7 @@ class TerminalInteractiveShell(InteractiveShell): #double-guard against keyboardinterrupts during kbdint handling try: self.write('\nKeyboardInterrupt\n') - self.input_splitter.reset() + self._store_multiline_history(self.input_splitter.source_raw_reset()[1]) more = False except KeyboardInterrupt: pass @@ -309,6 +318,7 @@ class TerminalInteractiveShell(InteractiveShell): self.edit_syntax_error() if not more: source_raw = self.input_splitter.source_raw_reset()[1] + self._store_multiline_history(source_raw) self.run_cell(source_raw, store_history=True) # We are off again...