Commit 83118c6c authored by Kurt B. Kaiser's avatar Kurt B. Kaiser

Clear associated breakpoints when closing an edit window.

M Debugger.py      : Added clear_file_breaks()
M EditorWindow.py  : Clear breaks when closed, commments->docstrings,
                     comment out some debugging print statements
M PyShell.py       : comments->docstrings ; clarify extending EditorWindow
                     methods.
M RemoteDebugger.py: Add clear_all_file_breaks() functionality,
                     clarify some comments.
parent ab5dae35
...@@ -320,17 +320,27 @@ class Debugger: ...@@ -320,17 +320,27 @@ class Debugger:
text.tag_add("BREAK", "insert linestart", "insert lineend +1char") text.tag_add("BREAK", "insert linestart", "insert lineend +1char")
def clear_breakpoint_here(self, edit): def clear_breakpoint_here(self, edit):
text = edit.text text = edit.text
filename = edit.io.filename filename = edit.io.filename
if not filename: if not filename:
text.bell() text.bell()
return return
lineno = int(float(text.index("insert"))) lineno = int(float(text.index("insert")))
msg = self.idb.clear_break(filename, lineno) msg = self.idb.clear_break(filename, lineno)
if msg: if msg:
text.bell() text.bell()
return return
text.tag_remove("BREAK", "insert linestart",\ text.tag_remove("BREAK", "insert linestart",\
"insert lineend +1char") "insert lineend +1char")
def clear_file_breaks(self, edit):
text = edit.text
filename = edit.io.filename
if not filename:
text.bell()
return
msg = self.idb.clear_all_file_breaks(filename)
if msg:
text.bell()
return
text.tag_delete("BREAK")
...@@ -490,15 +490,15 @@ class EditorWindow: ...@@ -490,15 +490,15 @@ class EditorWindow:
self.per.insertfilter(self.undo) self.per.insertfilter(self.undo)
def ResetColorizer(self): def ResetColorizer(self):
#this function is called from configDialog.py "Update the colour theme if it is changed"
#to update the colour theme if it is changed # Called from configDialog.py
if self.color: if self.color:
self.color = self.ColorDelegator() self.color = self.ColorDelegator()
self.per.insertfilter(self.color) self.per.insertfilter(self.color)
def ResetFont(self): def ResetFont(self):
#this function is called from configDialog.py "Update the text widgets' font if it is changed"
#to update the text widgets' font if it is changed # Called from configDialog.py
fontWeight='normal' fontWeight='normal'
if idleConf.GetOption('main','EditorWindow','font-bold',type='bool'): if idleConf.GetOption('main','EditorWindow','font-bold',type='bool'):
fontWeight='bold' fontWeight='bold'
...@@ -507,8 +507,8 @@ class EditorWindow: ...@@ -507,8 +507,8 @@ class EditorWindow:
fontWeight)) fontWeight))
def ResetKeybindings(self): def ResetKeybindings(self):
#this function is called from configDialog.py "Update the keybindings if they are changed"
#to update the keybindings if they are changed # Called from configDialog.py
self.Bindings.default_keydefs=idleConf.GetCurrentKeySet() self.Bindings.default_keydefs=idleConf.GetCurrentKeySet()
keydefs = self.Bindings.default_keydefs keydefs = self.Bindings.default_keydefs
for event, keylist in keydefs.items(): for event, keylist in keydefs.items():
...@@ -540,7 +540,7 @@ class EditorWindow: ...@@ -540,7 +540,7 @@ class EditorWindow:
#print 'accel now:',accel,'\n' #print 'accel now:',accel,'\n'
def ResetExtraHelpMenu(self): def ResetExtraHelpMenu(self):
#load or update the Extra Help menu if required "Load or update the Extra Help menu if required"
menuList=idleConf.GetAllExtraHelpSourcesList() menuList=idleConf.GetAllExtraHelpSourcesList()
helpMenu=self.menudict['help'] helpMenu=self.menudict['help']
cascadeIndex=helpMenu.index(END)-1 cascadeIndex=helpMenu.index(END)-1
...@@ -564,7 +564,7 @@ class EditorWindow: ...@@ -564,7 +564,7 @@ class EditorWindow:
return DisplayExtraHelp return DisplayExtraHelp
def UpdateRecentFilesList(self,newFile=None): def UpdateRecentFilesList(self,newFile=None):
#load or update the recent files list, and menu if required "Load or update the recent files list, and menu if required"
rfList=[] rfList=[]
if os.path.exists(self.recentFilesPath): if os.path.exists(self.recentFilesPath):
RFfile=open(self.recentFilesPath,'r') RFfile=open(self.recentFilesPath,'r')
...@@ -578,8 +578,9 @@ class EditorWindow: ...@@ -578,8 +578,9 @@ class EditorWindow:
rfList.remove(newFile) rfList.remove(newFile)
rfList.insert(0,newFile) rfList.insert(0,newFile)
rfList=self.__CleanRecentFiles(rfList) rfList=self.__CleanRecentFiles(rfList)
print self.top.instanceDict #print self.flist.inversedict
print self #print self.top.instanceDict
#print self
if rfList: if rfList:
for instance in self.top.instanceDict.keys(): for instance in self.top.instanceDict.keys():
instance.menuRecentFiles.delete(1,END) instance.menuRecentFiles.delete(1,END)
...@@ -695,10 +696,12 @@ class EditorWindow: ...@@ -695,10 +696,12 @@ class EditorWindow:
return reply return reply
def _close(self): def _close(self):
print self.io.filename #print self.io.filename
if self.io.filename: if self.io.filename:
self.UpdateRecentFilesList(newFile=self.io.filename) self.UpdateRecentFilesList(newFile=self.io.filename)
shell = self.flist.pyshell
if shell and shell.interp.debugger:
shell.interp.debugger.clear_file_breaks(self)
WindowList.unregister_callback(self.postwindowsmenu) WindowList.unregister_callback(self.postwindowsmenu)
if self.close_hook: if self.close_hook:
self.close_hook() self.close_hook()
...@@ -756,7 +759,6 @@ class EditorWindow: ...@@ -756,7 +759,6 @@ class EditorWindow:
methodname = methodname + "_event" methodname = methodname + "_event"
if hasattr(ins, methodname): if hasattr(ins, methodname):
self.text.bind(vevent, getattr(ins, methodname)) self.text.bind(vevent, getattr(ins, methodname))
if hasattr(ins, "menudefs"): if hasattr(ins, "menudefs"):
self.fill_menus(ins.menudefs, keydefs) self.fill_menus(ins.menudefs, keydefs)
return ins return ins
...@@ -771,8 +773,10 @@ class EditorWindow: ...@@ -771,8 +773,10 @@ class EditorWindow:
apply(text.event_add, (event,) + tuple(keylist)) apply(text.event_add, (event,) + tuple(keylist))
def fill_menus(self, defs=None, keydefs=None): def fill_menus(self, defs=None, keydefs=None):
# Fill the menus. Menus that are absent or None in """Add appropriate entries to the menus and submenus
# self.menudict are ignored.
Menus that are absent or None in self.menudict are ignored.
"""
if defs is None: if defs is None:
defs = self.Bindings.menudefs defs = self.Bindings.menudefs
if keydefs is None: if keydefs is None:
......
...@@ -119,8 +119,7 @@ class PyShellEditorWindow(EditorWindow): ...@@ -119,8 +119,7 @@ class PyShellEditorWindow(EditorWindow):
class PyShellFileList(FileList): class PyShellFileList(FileList):
"Extend base class: file list when a shell is present"
# File list when a shell is present
EditorWindow = PyShellEditorWindow EditorWindow = PyShellEditorWindow
...@@ -136,8 +135,7 @@ class PyShellFileList(FileList): ...@@ -136,8 +135,7 @@ class PyShellFileList(FileList):
class ModifiedColorDelegator(ColorDelegator): class ModifiedColorDelegator(ColorDelegator):
"Extend base class: colorizer for the shell window itself"
# Colorizer for the shell window itself
def __init__(self): def __init__(self):
ColorDelegator.__init__(self) ColorDelegator.__init__(self)
...@@ -161,8 +159,7 @@ class ModifiedColorDelegator(ColorDelegator): ...@@ -161,8 +159,7 @@ class ModifiedColorDelegator(ColorDelegator):
}) })
class ModifiedUndoDelegator(UndoDelegator): class ModifiedUndoDelegator(UndoDelegator):
"Extend base class: forbid insert/delete before the I/O mark"
# Forbid insert/delete before the I/O mark
def insert(self, index, chars, tags=None): def insert(self, index, chars, tags=None):
try: try:
...@@ -283,12 +280,12 @@ class ModifiedInterpreter(InteractiveInterpreter): ...@@ -283,12 +280,12 @@ class ModifiedInterpreter(InteractiveInterpreter):
gid = 0 gid = 0
def execsource(self, source): def execsource(self, source):
# Like runsource() but assumes complete exec source "Like runsource() but assumes complete exec source"
filename = self.stuffsource(source) filename = self.stuffsource(source)
self.execfile(filename, source) self.execfile(filename, source)
def execfile(self, filename, source=None): def execfile(self, filename, source=None):
# Execute an existing file "Execute an existing file"
if source is None: if source is None:
source = open(filename, "r").read() source = open(filename, "r").read()
try: try:
...@@ -300,7 +297,7 @@ class ModifiedInterpreter(InteractiveInterpreter): ...@@ -300,7 +297,7 @@ class ModifiedInterpreter(InteractiveInterpreter):
self.runcode(code) self.runcode(code)
def runsource(self, source): def runsource(self, source):
# Extend base class to stuff the source in the line cache first "Extend base class method: Stuff the source in the line cache first"
filename = self.stuffsource(source) filename = self.stuffsource(source)
self.more = 0 self.more = 0
self.save_warnings_filters = warnings.filters[:] self.save_warnings_filters = warnings.filters[:]
...@@ -313,7 +310,7 @@ class ModifiedInterpreter(InteractiveInterpreter): ...@@ -313,7 +310,7 @@ class ModifiedInterpreter(InteractiveInterpreter):
self.save_warnings_filters = None self.save_warnings_filters = None
def stuffsource(self, source): def stuffsource(self, source):
# Stuff source in the filename cache "Stuff source in the filename cache"
filename = "<pyshell#%d>" % self.gid filename = "<pyshell#%d>" % self.gid
self.gid = self.gid + 1 self.gid = self.gid + 1
lines = string.split(source, "\n") lines = string.split(source, "\n")
...@@ -321,8 +318,12 @@ class ModifiedInterpreter(InteractiveInterpreter): ...@@ -321,8 +318,12 @@ class ModifiedInterpreter(InteractiveInterpreter):
return filename return filename
def showsyntaxerror(self, filename=None): def showsyntaxerror(self, filename=None):
# Extend base class to color the offending position """Extend base class method: Add Colorizing
# (instead of printing it and pointing at it with a caret)
Color the offending position instead of printing it and pointing at it
with a caret.
"""
text = self.tkconsole.text text = self.tkconsole.text
stuff = self.unpackerror() stuff = self.unpackerror()
if not stuff: if not stuff:
...@@ -357,7 +358,7 @@ class ModifiedInterpreter(InteractiveInterpreter): ...@@ -357,7 +358,7 @@ class ModifiedInterpreter(InteractiveInterpreter):
return None return None
def showtraceback(self): def showtraceback(self):
# Extend base class method to reset output properly "Extend base class method to reset output properly"
self.tkconsole.resetoutput() self.tkconsole.resetoutput()
self.checklinecache() self.checklinecache()
InteractiveInterpreter.showtraceback(self) InteractiveInterpreter.showtraceback(self)
...@@ -379,7 +380,7 @@ class ModifiedInterpreter(InteractiveInterpreter): ...@@ -379,7 +380,7 @@ class ModifiedInterpreter(InteractiveInterpreter):
return self.debugger return self.debugger
def runcommand(self, code): def runcommand(self, code):
# This runs the code without invoking the debugger. "Run the code without invoking the debugger"
# The code better not raise an exception! # The code better not raise an exception!
if self.tkconsole.executing: if self.tkconsole.executing:
tkMessageBox.showerror( tkMessageBox.showerror(
...@@ -395,7 +396,7 @@ class ModifiedInterpreter(InteractiveInterpreter): ...@@ -395,7 +396,7 @@ class ModifiedInterpreter(InteractiveInterpreter):
return 1 return 1
def runcode(self, code): def runcode(self, code):
# Override base class method "Override base class method"
if self.tkconsole.executing: if self.tkconsole.executing:
tkMessageBox.showerror( tkMessageBox.showerror(
"Already executing", "Already executing",
...@@ -403,7 +404,7 @@ class ModifiedInterpreter(InteractiveInterpreter): ...@@ -403,7 +404,7 @@ class ModifiedInterpreter(InteractiveInterpreter):
"please wait until it is finished.", "please wait until it is finished.",
master=self.tkconsole.text) master=self.tkconsole.text)
return return
#
self.checklinecache() self.checklinecache()
if self.save_warnings_filters is not None: if self.save_warnings_filters is not None:
warnings.filters[:] = self.save_warnings_filters warnings.filters[:] = self.save_warnings_filters
...@@ -414,7 +415,7 @@ class ModifiedInterpreter(InteractiveInterpreter): ...@@ -414,7 +415,7 @@ class ModifiedInterpreter(InteractiveInterpreter):
self.active_seq = self.rpcclt.asynccall("exec", "runcode", self.active_seq = self.rpcclt.asynccall("exec", "runcode",
(code,), {}) (code,), {})
return return
#
try: try:
self.tkconsole.beginexecuting() self.tkconsole.beginexecuting()
try: try:
...@@ -433,12 +434,12 @@ class ModifiedInterpreter(InteractiveInterpreter): ...@@ -433,12 +434,12 @@ class ModifiedInterpreter(InteractiveInterpreter):
self.showtraceback() self.showtraceback()
except: except:
self.showtraceback() self.showtraceback()
#
finally: finally:
self.tkconsole.endexecuting() self.tkconsole.endexecuting()
def write(self, s): def write(self, s):
# Override base class write "Override base class method"
self.tkconsole.console.write(s) self.tkconsole.console.write(s)
class PyShell(OutputWindow): class PyShell(OutputWindow):
...@@ -565,7 +566,7 @@ class PyShell(OutputWindow): ...@@ -565,7 +566,7 @@ class PyShell(OutputWindow):
##sys.settrace(self._cancel_check) ##sys.settrace(self._cancel_check)
def endexecuting(self): def endexecuting(self):
# Helper for ModifiedInterpreter "Helper for ModifiedInterpreter"
##sys.settrace(None) ##sys.settrace(None)
##self._cancel_check = None ##self._cancel_check = None
self.executing = 0 self.executing = 0
...@@ -573,7 +574,7 @@ class PyShell(OutputWindow): ...@@ -573,7 +574,7 @@ class PyShell(OutputWindow):
self.showprompt() self.showprompt()
def close(self): def close(self):
# Extend base class method "Extend EditorWindow.close()"
if self.executing: if self.executing:
# XXX Need to ask a question here # XXX Need to ask a question here
if not tkMessageBox.askokcancel( if not tkMessageBox.askokcancel(
...@@ -586,9 +587,10 @@ class PyShell(OutputWindow): ...@@ -586,9 +587,10 @@ class PyShell(OutputWindow):
if self.reading: if self.reading:
self.top.quit() self.top.quit()
return "cancel" return "cancel"
return OutputWindow.close(self) return EditorWindow.close(self)
def _close(self): def _close(self):
"Extend EditorWindow._close(), shut down debugger and execution server"
self.close_debugger() self.close_debugger()
self.interp.kill_subprocess() self.interp.kill_subprocess()
# Restore std streams # Restore std streams
...@@ -601,10 +603,10 @@ class PyShell(OutputWindow): ...@@ -601,10 +603,10 @@ class PyShell(OutputWindow):
self.auto = None self.auto = None
self.flist.pyshell = None self.flist.pyshell = None
self.history = None self.history = None
OutputWindow._close(self) # Really EditorWindow._close EditorWindow._close(self)
def ispythonsource(self, filename): def ispythonsource(self, filename):
# Override this so EditorWindow never removes the colorizer "Override EditorWindow method: never remove the colorizer"
return 1 return 1
def short_title(self): def short_title(self):
...@@ -781,9 +783,6 @@ class PyShell(OutputWindow): ...@@ -781,9 +783,6 @@ class PyShell(OutputWindow):
i = i-1 i = i-1
line = line[:i] line = line[:i]
more = self.interp.runsource(line) more = self.interp.runsource(line)
# XXX This was causing extra prompt with shell KBK
# if not more:
# self.showprompt()
def cancel_check(self, frame, what, args, def cancel_check(self, frame, what, args,
dooneevent=tkinter.dooneevent, dooneevent=tkinter.dooneevent,
......
...@@ -101,6 +101,9 @@ class IdbAdapter: ...@@ -101,6 +101,9 @@ class IdbAdapter:
def clear_break(self, filename, lineno): def clear_break(self, filename, lineno):
msg = self.idb.clear_break(filename, lineno) msg = self.idb.clear_break(filename, lineno)
def clear_all_file_breaks(self, filename):
msg = self.idb.clear_all_file_breaks(filename)
#----------called by a FrameProxy---------- #----------called by a FrameProxy----------
def frame_attr(self, fid, name): def frame_attr(self, fid, name):
...@@ -148,14 +151,6 @@ class IdbAdapter: ...@@ -148,14 +151,6 @@ class IdbAdapter:
dict = dicttable[did] dict = dicttable[did]
value = dict[key] value = dict[key]
value = repr(value) value = repr(value)
# try:
# # Test for picklability
# import cPickle
# pklstr = cPickle.dumps(value)
# except:
# print >>sys.__stderr__, "** dict_item pickle failed: ", value
# raise
# #value = None
return value return value
#----------end class IdbAdapter---------- #----------end class IdbAdapter----------
...@@ -165,9 +160,9 @@ def start_debugger(conn, gui_adap_oid): ...@@ -165,9 +160,9 @@ def start_debugger(conn, gui_adap_oid):
"""Start the debugger and its RPC link in the Python subprocess """Start the debugger and its RPC link in the Python subprocess
Start the subprocess side of the split debugger and set up that side of the Start the subprocess side of the split debugger and set up that side of the
RPC link by instantiating the GUIProxy, Idle debugger, and IdbAdapter RPC link by instantiating the GUIProxy, Idb debugger, and IdbAdapter
objects and linking them together. Register the IdbAdapter to handle RPC objects and linking them together. Register the IdbAdapter to handle RPC
requests from the split Debugger GUI via the IdbProxy. requests from the split debugger GUI via the IdbProxy.
""" """
gui_proxy = GUIProxy(conn, gui_adap_oid) gui_proxy = GUIProxy(conn, gui_adap_oid)
...@@ -316,12 +311,16 @@ class IdbProxy: ...@@ -316,12 +311,16 @@ class IdbProxy:
def clear_break(self, filename, lineno): def clear_break(self, filename, lineno):
msg = self.call("clear_break", filename, lineno) msg = self.call("clear_break", filename, lineno)
def clear_all_file_breaks(self, filename):
msg = self.call("clear_all_file_breaks", filename)
def start_remote_debugger(conn, pyshell): def start_remote_debugger(conn, pyshell):
"""Start the subprocess debugger, initialize the debugger GUI and RPC link """Start the subprocess debugger, initialize the debugger GUI and RPC link
Request the RPCServer start the Python subprocess debugger and link. Set Request the RPCServer start the Python subprocess debugger and link. Set
up the Idle side of the split debugger by instantiating the IdbProxy, up the Idle side of the split debugger by instantiating the IdbProxy,
Debugger GUI, and Debugger GUIAdapter objects and linking them together. debugger GUI, and debugger GUIAdapter objects and linking them together.
Register the GUIAdapter to handle debugger GUI interaction requests coming Register the GUIAdapter to handle debugger GUI interaction requests coming
from the subprocess debugger via the GUIProxy. from the subprocess debugger via the GUIProxy.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment