[Idle-dev] IDLE 3000 (script included)

Mr. T rt8396 at gmail.com
Tue Jan 27 00:53:55 CET 2009


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!


from Tkinter import *

class CMD(Toplevel):
    def __init__(self, master, glo, loc):
        Toplevel.__init__(self, master)
        self.glo = glo
        self.loc = loc
        self.master = master
        self.startidx = '1.0'
        self.transient(master)
        self.lift(master)
        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=10)
        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.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)

    def on_quit(self):
        self.grab_release()
        if self.master:
            self.master.focus_set()
        self.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):
        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 fix_index(self, chars):
        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 onBackSpace(self, event=None):
        if self.text.compare(self.text.index(INSERT), '!=', self.startidx):
            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, self.glo, self.loc)
            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()
    cmd = CMD(root, globals(), locals())
    root.mainloop()

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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/idle-dev/attachments/20090126/d6e4fcbb/attachment-0001.htm>


More information about the IDLE-dev mailing list