Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7ee3b4a

Browse files
committed
rudimentary history support (current session only)
1 parent e600447 commit 7ee3b4a

1 file changed

Lines changed: 71 additions & 7 deletions

File tree

bipython/__init__.py

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -610,10 +610,62 @@ def _prompt_result(self, text):
610610
callback(text)
611611

612612

613-
class IPythonHistory(object):
614-
# make this
613+
class NotIPythonKernel(Exception):
615614
pass
616615

616+
class IPythonHistory(repl.History):
617+
"""A history mechanism that interacts with IPython.
618+
619+
This relies on the standard IPython kernel, because it uses
620+
`get_ipyton().history_manager` to fetch results.
621+
622+
As a fall back, local readline completion should be implemented when a new
623+
instance of IPythonHistory can not initialize and raises an error.
624+
"""
625+
626+
def __init__(self, repl):
627+
"""The required argument is a handle on the repl, which will be ued to
628+
communicate with the IPython kernel. If a connection cannot be made,
629+
or no expected results are returned, we raise a NotIPythonKernel
630+
error, so that the vanilla readline completion can continue to be used
631+
as a fallback.
632+
"""
633+
msg_id = repl.send_ipython('', silent=False, user_expressions={ 'hist':
634+
"list(get_ipython().history_manager.get_range())"})
635+
# XXX: for now we only grab history from current sesssion
636+
#"list(get_ipython().history_manager.get_tail(100))"})
637+
#silent=True)
638+
639+
640+
output = repl.ipython_get_child_msg(msg_id)['content']
641+
hist = eval(output['user_expressions']['hist']['data']['text/plain'])
642+
self.hist = hist
643+
repl.debug_docstring = str(hist)
644+
repl.debug_docstring = ''
645+
self.entries = ['']
646+
self.index = 0
647+
self.saved_line = ''
648+
self.duplicates = True # allow duplicates
649+
self.repl = repl
650+
self.load()
651+
#raise NotIPythonKernel()
652+
653+
def load(self, *args, **kwargs):
654+
"""Load history from a live IPython session.
655+
656+
Arguments are ignored, and are only listed here for API compatibility
657+
with bpython's History class, which takes `filename` and `encoding`
658+
arguments, but those don't make sense in this instance.
659+
"""
660+
# XXX: stopgap: get the history from ipython, write it to a file, and
661+
# proceed with the normal load after that
662+
for line in self.hist:
663+
self.append(line[-1])
664+
self.repl.stdout_hist += "\n" + line[-1]
665+
666+
def save(self, *args, **kw):
667+
pass
668+
617669
class URWIDRepl(repl.Repl):
618670

619671
_time_between_redraws = .05 # seconds
@@ -663,9 +715,10 @@ def __init__(self, event_loop, palette, interpreter, config):
663715
self.exit_value = ()
664716

665717
load_urwid_command_map(config)
718+
self.debug_docstring = ''
666719
self.ipython = self.connect_ipython_kernel()
720+
667721
self.ipy_execution_count = '0'
668-
self.debug_docstring = ''
669722
self.docstring_widget = None
670723

671724
@property
@@ -768,15 +821,23 @@ def echo(x):
768821
self.km = km
769822
self.kc = kc
770823
print(km)
771-
msg_id = self.send_ipython('# bpython ' + version + ' connected')
824+
msg_id = self.send_ipython('# bpython ' + version + ' connected\n')
772825
try:
773826
child = self.ipython_get_child_msg(msg_id)
774827
except Empty:
775828
over_the_line()
776829

777830
self.send_ipython(bipy_func, silent=True)
778831
# TODO: get a proper history navigator
779-
#self.rl_history = IPythonHistory(kc)
832+
#
833+
try:
834+
self.rl_history = IPythonHistory(self)
835+
except NotIPythonKernel:
836+
# We must not be running an IPython Kernel
837+
#sys.stderr.write(
838+
self.debug_docstring = "could not access IPython history, falling back to readline"
839+
sys.stderr.flush()
840+
pass
780841
self.ipython_set_pid()
781842

782843
return km
@@ -1428,6 +1489,9 @@ def push(self, s, insert_into_history=True):
14281489
if hasattr(repl.Repl, 'insert_into_history'):
14291490
# this is only in unreleased version of bpython
14301491
self.insert_into_history(s)
1492+
# on the IPython side, at least for the Python kernel, history
1493+
# is managed for us by the history manager, so there's no need
1494+
# to do anything here.
14311495
if self.edit is not None:
14321496
self.edit.make_readonly()
14331497
self.buffer = []
@@ -1586,12 +1650,12 @@ def handle_input(self, event):
15861650
# "back" from bpython.cli
15871651
self.rl_history.enter(self.edit.get_edit_text())
15881652
self.edit.set_edit_text('')
1589-
self.edit.insert_text(self.rl_history.back())
1653+
self.edit.insert_text(self.rl_history.back()) # + "#previous")
15901654
elif urwid.command_map[event] == 'cursor down':
15911655
# "fwd" from bpython.cli
15921656
self.rl_history.enter(self.edit.get_edit_text())
15931657
self.edit.set_edit_text('')
1594-
self.edit.insert_text(self.rl_history.forward())
1658+
self.edit.insert_text(self.rl_history.forward()) # + "#next")
15951659
elif urwid.command_map[event] == 'next selectable':
15961660
self.tab()
15971661
elif urwid.command_map[event] == 'prev selectable':

0 commit comments

Comments
 (0)