Proposal: OK, so the python language has officially moved into the next level. I look at IDLE and think, hmm great IDE but it could really use a spit shining. So here is a very simple script showing my ideas to improve IDLE.
Reason for change: The text widget and the prompt(>>>) should be separated. Trying to write a conditional in the interactive IDLE is a real pain. Not to mention that when you copy code from Interactive IDLE to the IDLE editor window the indention is eight spaces instead four and you've got that prompt(>>>) stuck in there. I have a solution for the problem though. I hope you are using fixed-width font Lst|<----- Text Widget ---->| | | >>>|if this: | ...| if that: | ...| ... | ...| elif that: | ...| ... | ...| else: | ...| ... | >>>| | >>>|x = 10 | >>>| | Basically you have a Listbox on the left for the prompt and a Text on the right. Disable the Listbox highlight and key press events and now we have a very friendly interactive IDLE! No more prompt hijacking your snippets, and no more eigtht space indention! Hip-Hip-Hooray! #-- Start Script --# from Tkinter import * import tkMessageBox as MB class CMD(Toplevel): def __init__(self, master): Toplevel.__init__(self, master) self.master = master self.startidx = '1.0' self.backidx = '1.0' self.title('IDLE 3000') self.listbox = Listbox(self, width=3, relief=FLAT, font= ('Courier New',12), takefocus=0) self.listbox.pack(fill=Y, side=LEFT) self.listbox.insert(0, '>>>') self.text = Text(self, relief=FLAT, spacing3=1, wrap=NONE, font=('Courier New',12)) self.text.pack(fill=BOTH, side=LEFT, expand=1) self.text.config(width=50, height=20) self.text.focus_set() self.listbox.bind("<KeyPress>" , lambda e: "break") self.listbox.bind("<Button-1>" , lambda e: "break") self.listbox.bind("<B1-Motion>" , lambda e: "break") self.listbox.bind("<ButtonRelease-1>" , lambda e: "break") self.listbox.bind("<B2-Motion>" , lambda e: "break") self.listbox.bind("<MouseWheel>" , lambda e: "break") self.text.bind('<Next>' , lambda e: "break")#pageup self.text.bind('<Prior>' , lambda e: "break")#pagedown self.text.bind('<Delete>' , lambda e: "break") self.text.bind('<Control-Home>' , lambda e: "break") self.text.bind('<Control-End>' , lambda e: "break") self.text.bind("<B2-Motion>" , lambda e: "break") self.text.bind('<Button-2>' , lambda e: "break") self.text.bind("<MouseWheel>" , lambda e: "break") self.text.bind("<Up>" , self.onUp) self.text.bind("<Down>" , self.onDown) self.text.bind("<Tab>" , self.onTab) self.text.bind("<Return>" , self.onReturn) self.text.bind("<BackSpace>", self.onBackSpace) self.protocol("WM_DELETE_WINDOW", self.onQuit) self.lift(master) self.master.withdraw() def fix_index(self, chars): self.backidx = '%d.0' %(int(self.backidx.split('.')[0])+1) self.text.insert(END, '\n') self.text.mark_set(INSERT, END) self.text.see(INSERT) self.listbox.insert(END, chars) self.listbox.see(self.listbox.size()) def onQuit(self): self.grab_release() self.master.destroy() def onTab(self, event=None): curline, cursor = self.text.index(INSERT).split('.')[0]+'.0', self.text.index(INSERT) self.text.insert(INSERT, ' ') return "break" def onDown(self, event): i = self.text.index(INSERT+'+1l') #;print 'New index: ', i self.text.mark_set(INSERT, i) self.text.see(i) self.listbox.see(int(i.split('.')[0])-1) return "break" def onUp(self, event=None): i = self.text.index(INSERT+'-1l') #;print 'New index: ', i self.text.mark_set(INSERT, i) self.text.see(i) self.listbox.see(int(i.split('.')[0])-1) return "break" def onBackSpace(self, event=None): if self.text.compare(self.text.index(INSERT), '!=', self.backidx): self.text.delete(self.text.index(INSERT+'-1c')) return "break" def onReturn(self, event=None): curline, cursor = self.text.index(INSERT).split('.')[0]+'.0', self.text.index(INSERT) text = self.text.get(self.startidx, END).strip() if self.text.compare(curline, '<', self.startidx):#'Out Of Zone' self.text.mark_set(INSERT, END+'-1c') self.text.see(INSERT) self.listbox.see(END) elif '.0' in cursor: #nothing typed on this line, try to exec command cmd = text.rstrip('\n') try: exec(cmd) except: self.master.bell() print '%s\n%s\n%s' %(sys.exc_traceback, sys.exc_type, sys.exc_value) finally: self.fix_index('>>>') self.startidx = self.text.index(INSERT) elif text != '':#something typed self.fix_index('...') else: #insert newline self.fix_index('>>>') return "break" if __name__ == '__main__': print 'main' root = Tk() MB.showinfo('IDLE 3000 Introduction',''' This Demo shows how i think the standard IDLE should behave. You will notice the prompt is outside of the text widget. This keeps the prompt from hijacking your code snippits when you copy-paste to the main editor window. This also keeps all indention at the Python recommended four spaces. Please note this demo is to only show the layout, it does not include syntax highlight, auto-tab, auto-dedent, or any other feature. This is not even the correct way to write a good editor. My only intention is to show a more user friendly layout have fun :) ''') cmd = CMD(root) root.mainloop() #-- End Script --# Issue #2: When you press MMB and there is a highlighted selection in the text it gets pasted over and over again @ the insertion cursor. This can be aggravating, and turn a clean script into a bowl of "Cheerios" breakfast cereal in no time. -- http://mail.python.org/mailman/listinfo/python-list