diff --git a/IPython/frontend/cocoa/cocoa_frontend.py b/IPython/frontend/cocoa/cocoa_frontend.py index 5f617e7..cea94d9 100644 --- a/IPython/frontend/cocoa/cocoa_frontend.py +++ b/IPython/frontend/cocoa/cocoa_frontend.py @@ -29,6 +29,7 @@ import uuid from Foundation import NSObject, NSMutableArray, NSMutableDictionary,\ NSLog, NSNotificationCenter, NSMakeRange,\ NSLocalizedString, NSIntersectionRange + from AppKit import NSApplicationWillTerminateNotification, NSBeep,\ NSTextView, NSRulerView, NSVerticalRuler @@ -181,17 +182,26 @@ class IPythonCocoaController(NSObject, FrontEndBase): if(self.is_complete(self.currentBlock())): self.execute(self.currentBlock(), blockID=self.currentBlockID) - self.currentBlockID = self.nextBlockID() + self.startNewBlock() + return True return False elif(selector == 'moveUp:'): - self.replaceCurrentBlockWithString(textView, self.get_history_item_previous(self.currentBlock())) + prevBlock = self.get_history_previous(self.currentBlock()) + if(prevBlock != None): + self.replaceCurrentBlockWithString(textView, prevBlock) + else: + NSBeep() return True elif(selector == 'moveDown:'): - self.replaceCurrentBlockWithString(textView, self.get_history_item_next(self.currentBlock())) + nextBlock = self.get_history_next(self.currentBlock()) + if(nextBlock != None): + self.replaceCurrentBlockWithString(textView, nextBlock) + else: + NSBeep() return True elif(selector == 'moveToBeginningOfParagraph:'): @@ -265,6 +275,13 @@ class IPythonCocoaController(NSObject, FrontEndBase): return (completions,0) + def startNewBlock(self): + """""" + + self.currentBlockID = self.nextBlockID() + + + def nextBlockID(self): return uuid.uuid4() @@ -312,7 +329,8 @@ class IPythonCocoaController(NSObject, FrontEndBase): def render_error(self, failure): - self.insert_text(str(failure)) + self.insert_text('\n\n'+str(failure)+'\n\n') + self.startNewBlock() return failure @@ -344,6 +362,7 @@ class IPythonCocoaController(NSObject, FrontEndBase): def replaceCurrentBlockWithString(self, textView, string): textView.replaceCharactersInRange_withString_(self.currentBlockRange(), string) + self.currentBlockRange().length = len(string) r = NSMakeRange(textView.textStorage().length(), 0) textView.scrollRangeToVisible_(r) textView.setSelectedRange_(r) diff --git a/IPython/frontend/frontendbase.py b/IPython/frontend/frontendbase.py index ea8aeb8..12e1dc3 100644 --- a/IPython/frontend/frontendbase.py +++ b/IPython/frontend/frontendbase.py @@ -20,16 +20,15 @@ __docformat__ = "restructuredtext en" #------------------------------------------------------------------------------- import string import uuid +import _ast +import zope.interface as zi from IPython.kernel.core.history import FrontEndHistory from IPython.kernel.core.util import Bunch - from IPython.kernel.engineservice import IEngineCore -import zope.interface as zi - -import _ast +from twisted.python.failure import Failure ############################################################################## # TEMPORARY!!! fake configuration, while we decide whether to use tconfig or @@ -115,11 +114,11 @@ class IFrontEnd(zi.Interface): pass - def get_history_item_previous(currentBlock): + def get_history_previous(currentBlock): """Returns the block previous in the history.""" pass - def get_history_item_next(currentBlock): + def get_history_next(currentBlock): """Returns the next block in the history.""" pass @@ -226,38 +225,52 @@ class FrontEndBase(object): Result: Deferred result of self.interpreter.execute """ - # if(not isinstance(block, _ast.AST)): - # block = self.compile_ast(block) + + if(not self.is_complete(block)): + return Failure(Exception("Block is not compilable")) if(blockID == None): blockID = uuid.uuid4() #random UUID d = self.engine.execute(block) d.addCallback(self._add_block_id, blockID) + d.addCallback(self._add_history, block=block) d.addCallback(self.update_cell_prompt) d.addCallbacks(self.render_result, errback=self.render_error) return d + def _add_block_id(self, result, blockID): - """add_block_id""" + """Add the blockID to result""" result['blockID'] = blockID return result + def _add_history(self, result, block=None): + """Add block to the history""" + + assert(block != None) + self.history.add_items([block]) + self.history_cursor += 1 + + return result + - def get_history_item_previous(self, currentBlock): + def get_history_previous(self, currentBlock): """ Returns previous history string and decrement history cursor. """ + print self.history command = self.history.get_history_item(self.history_cursor - 1) + print command if command is not None: self.history.input_cache[self.history_cursor] = currentBlock self.history_cursor -= 1 return command - def get_history_item_next(self, currentBlock): + def get_history_next(self, currentBlock): """ Returns next history string and increment history cursor. """ command = self.history.get_history_item(self.history_cursor + 1)