Gmail Calendar Documents Reader Web more »
Recently Visited Groups | Help | Sign in
Google Groups Home
Run @button's in ileo, and tab completion
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  8 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Ville M. Vainio  
View profile  
 More options Sep 6 2008, 7:39 am
From: "Ville M. Vainio" <vivai...@gmail.com>
Date: Sat, 6 Sep 2008 14:39:52 +0300
Local: Sat, Sep 6 2008 7:39 am
Subject: Run @button's in ileo, and tab completion
I would like to do the following things:

ILeo buttons
=======
Create @button nodes that would be pushed to ipython instead of normal
execution mechanism. How can I do that without adding lots of verbiage
in the @button nodes themselves? Can I create buttons directly without
relying on @button nodes, e.g. with something like:

c.new_button('hello', my_callback)

Tab completion
=======

I'd like to do proper tab completion in ILeo windows. I.e, when the
user presses some character sequence (ctrl + space), something special
gets called that relays the contents of the line up to the current
cursor position to ipython. I'd like this to be "enablable" for
selected nodes - the idea is that once you run alt+I once on a node,
it would set the tab completer to that of ileo.

--
Ville M. Vainio - vivainio.googlepages.com
blog=360.yahoo.com/villevainio - g[mail | talk]='vivainio'


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Edward K. Ream  
View profile  
 More options Sep 6 2008, 9:18 am
From: "Edward K. Ream" <edream...@gmail.com>
Date: Sat, 6 Sep 2008 08:18:39 -0500
Local: Sat, Sep 6 2008 9:18 am
Subject: Re: Run @button's in ileo, and tab completion
On Sat, Sep 6, 2008 at 6:39 AM, Ville M. Vainio <vivai...@gmail.com> wrote:

> Can I create buttons directly without relying on @button nodes, e.g. with something like:

> c.new_button('hello', my_callback)

Of course.  You don't think the @button code does all the work itself, do you?

Let me show you, Ville, and more importantly, less experienced Leo
users, how I answer such questions.  Leo's source code, if printed out
50 lines per page, would comprise a book of well over 1000 pages.  I
don't begin to try to remember the details of this code.

Instead, I start with some broad generalities, and then use Leo itself
to explore Leo's code.

In this case, I start with the following:

1. @button nodes are created by the mod_scripting plugin.  All I
remember is that there are a lot of helper methods, and a lot of
callbacks.  It's impossible for me to keep the code straight, but the
individual pieces are fairly small and self contained.

2. @button nodes are created *in* a Leo frame, so the actual code that
creates the buttons in leoFrame.py or leoTkinterFrame.py.  Maybe both,
I don't remember.

That's *all* I start with!  No details.

To answer your question, I could start with 2, because that's were the
helper code actually is.  But what the heck, let's say I didn't know
2, and that all I know is 1.  That is, let's say all I know is that
the mod_scripting plugin creates @button nodes.

So I open leoPlugins.leo, and find the mod_scripting plugin.  I search
for mod_scripting.py, and eventually find the node.

Most of the immediate children of the @thin mod_scripting.py node are
boilerplate.  Only the 'class scriptingController' node could contain
what we want.  I open that node and see the node 'createAllButtons &
helpers.  I open that node and see the complicated code (lots of
children) I remembered.

I see the node called 'handleAtButtonNode @button'.  Since @button
nodes create other buttons, I know that this button will tell me how
to create buttons.

Near the end of the body text for that node I see the line::

b = self.createAtButtonHelper(p,h,statusLine,shortcut,verbose=False)

So I search for createAtButtonHelper.  Not surprisingly, it's in the
'Utils' node.  I won't give all the code here, but there are calls to
the following methods in it::

    b = self.createIconButton(...)
    self.iconBar.setCommandForButton(...)
    k.registerCommand(...)

This is the good stuff.  k.registerCommand creates a minibuffer
command bound to the button's command.  Obviously, createIconButton
contains the answer to your original question.  The createIconButton
method contains this line:

    b = self.iconBar.add(text=truncatedText,command=command,bg=bg)

So that's how it is done.  But what is self.iconBar?  Well, the first
place to look for the definition of an ivar is the ctor.  We're in
luck.  We see:

    self.iconBar = c.frame.getIconBarObject()

So we have been lead, at long last, to point 2.  That is, we now have
access to frame methods that allow us to create icon buttons.

**Important**: c.frame is a Leo frame.  It is created in
leoTkinterFrame.py, in a class that is a subclass of the base class in
leoFrame.leo.  If we didn't know that, we could find it out by looking
at the commander creation logic in leoCommands.py.

So let's look at leoTkinterFrame.py to see what we can see.  We see the node:

'leoTkinterFrame'

This node has a child: 'class tkIconBarClass'.  We are close.  Opening
this node we see the 'add' node whose docstring is:

    """Add a button containing text or a picture to the icon bar.

    Pictures take precedence over text"""

So the answer to your question is:

    iconBar = c.frame.getIconBarObject()
    iconBar.add(...)

The keyword arguments to the add method are extracted as follows:

    text = keys.get('text')
    imagefile = keys.get('imagefile')
    image = keys.get('image')
    command = keys.get('command')
    bg = keys.get('bg')

That is, the arguments are pretty much the same as the Tk.Button args.

I've gone through this in detail to illustrate that Leo makes it easy
to track down lots of details starting with only the most general
notions of what the code contains.

I answered the question *exactly* as I indicated, by opening Leo
nodes.  Two weeks from now I will have forgotten all the details
again, but that doesn't matter.  If I hadn't actually written this
post, I could have found the answer in less than two minutes.

Edward


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Edward K. Ream  
View profile  
 More options Sep 6 2008, 9:23 am
From: "Edward K. Ream" <edream...@gmail.com>
Date: Sat, 6 Sep 2008 08:23:51 -0500
Local: Sat, Sep 6 2008 9:23 am
Subject: Re: Run @button's in ileo, and tab completion
On Sat, Sep 6, 2008 at 6:39 AM, Ville M. Vainio <vivai...@gmail.com> wrote:

> Tab completion
> I'd like to do proper tab completion in ILeo windows. I.e, when the
> user presses some character sequence (ctrl + space), something special
> gets called that relays the contents of the line up to the current
> cursor position to ipython. I'd like this to be "enablable" for
> selected nodes - the idea is that once you run alt+I once on a node,
> it would set the tab completer to that of ileo.

Tab completion is complex.  See leoPy.leo, the class:

Code-->Gui Base classes-->@thin leoKeys.py-->class autoCompleterClass

In particular, see the helper methods, doTabCompletion, doBackspace
and computeCompletionList.  These are wildly complicated, and depend
on lots of arcane ivars.

Feel free to ask questions.  I have a fair ideas of where the bodies
are hidden in this code.

Edward


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Lew Maestas  
View profile  
 More options Sep 6 2008, 12:04 pm
From: Lew Maestas <lmaest...@comcast.net>
Date: Sat, 06 Sep 2008 09:04:47 -0700
Local: Sat, Sep 6 2008 12:04 pm
Subject: Re: Run @button's in ileo, and tab completion
Edward,

Can an edit of this post be put in the Leo documentation?


Edward K. Ream wrote:
On Sat, Sep 6, 2008 at 6:39 AM, Ville M. Vainio <vivainio@gmail.com> wrote:

  
Can I create buttons directly without relying on @button nodes, e.g. with something like:

c.new_button('hello', my_callback)
    
Of course.  You don't think the @button code does all the work itself, do you?

Let me show you, Ville, and more importantly, less experienced Leo
users, how I answer such questions.  Leo's source code, if printed out
50 lines per page, would comprise a book of well over 1000 pages.  I
don't begin to try to remember the details of this code.

Instead, I start with some broad generalities, and then use Leo itself
to explore Leo's code.

In this case, I start with the following:

1. @button nodes are created by the mod_scripting plugin.  All I
remember is that there are a lot of helper methods, and a lot of
callbacks.  It's impossible for me to keep the code straight, but the
individual pieces are fairly small and self contained.

2. @button nodes are created *in* a Leo frame, so the actual code that
creates the buttons in leoFrame.py or leoTkinterFrame.py.  Maybe both,
I don't remember.

That's *all* I start with!  No details.

To answer your question, I could start with 2, because that's were the
helper code actually is.  But what the heck, let's say I didn't know
2, and that all I know is 1.  That is, let's say all I know is that
the mod_scripting plugin creates @button nodes.

So I open leoPlugins.leo, and find the mod_scripting plugin.  I search
for mod_scripting.py, and eventually find the node.

Most of the immediate children of the @thin mod_scripting.py node are
boilerplate.  Only the 'class scriptingController' node could contain
what we want.  I open that node and see the node 'createAllButtons &
helpers.  I open that node and see the complicated code (lots of
children) I remembered.

I see the node called 'handleAtButtonNode @button'.  Since @button
nodes create other buttons, I know that this button will tell me how
to create buttons.

Near the end of the body text for that node I see the line::

b = self.createAtButtonHelper(p,h,statusLine,shortcut,verbose=False)

So I search for createAtButtonHelper.  Not surprisingly, it's in the
'Utils' node.  I won't give all the code here, but there are calls to
the following methods in it::

    b = self.createIconButton(...)
    self.iconBar.setCommandForButton(...)
    k.registerCommand(...)

This is the good stuff.  k.registerCommand creates a minibuffer
command bound to the button's command.  Obviously, createIconButton
contains the answer to your original question.  The createIconButton
method contains this line:

    b = self.iconBar.add(text=truncatedText,command=command,bg=bg)

So that's how it is done.  But what is self.iconBar?  Well, the first
place to look for the definition of an ivar is the ctor.  We're in
luck.  We see:

    self.iconBar = c.frame.getIconBarObject()

So we have been lead, at long last, to point 2.  That is, we now have
access to frame methods that allow us to create icon buttons.

**Important**: c.frame is a Leo frame.  It is created in
leoTkinterFrame.py, in a class that is a subclass of the base class in
leoFrame.leo.  If we didn't know that, we could find it out by looking
at the commander creation logic in leoCommands.py.

So let's look at leoTkinterFrame.py to see what we can see.  We see the node:

'leoTkinterFrame'

This node has a child: 'class tkIconBarClass'.  We are close.  Opening
this node we see the 'add' node whose docstring is:

    """Add a button containing text or a picture to the icon bar.

    Pictures take precedence over text"""

So the answer to your question is:

    iconBar = c.frame.getIconBarObject()
    iconBar.add(...)

The keyword arguments to the add method are extracted as follows:

    text = keys.get('text')
    imagefile = keys.get('imagefile')
    image = keys.get('image')
    command = keys.get('command')
    bg = keys.get('bg')

That is, the arguments are pretty much the same as the Tk.Button args.

I've gone through this in detail to illustrate that Leo makes it easy
to track down lots of details starting with only the most general
notions of what the code contains.

I answered the question *exactly* as I indicated, by opening Leo
nodes.  Two weeks from now I will have forgotten all the details
again, but that doesn't matter.  If I hadn't actually written this
post, I could have found the answer in less than two minutes.

Edward
  

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ville M. Vainio  
View profile  
 More options Sep 7 2008, 5:59 am
From: "Ville M. Vainio" <vivai...@gmail.com>
Date: Sun, 7 Sep 2008 12:59:36 +0300
Local: Sun, Sep 7 2008 5:59 am
Subject: Re: Run @button's in ileo, and tab completion
On Sat, Sep 6, 2008 at 4:23 PM, Edward K. Ream <edream...@gmail.com> wrote:

> Tab completion is complex.  See leoPy.leo, the class:

> Code-->Gui Base classes-->@thin leoKeys.py-->class autoCompleterClass

> In particular, see the helper methods, doTabCompletion, doBackspace
> and computeCompletionList.  These are wildly complicated, and depend
> on lots of arcane ivars.

I guessed as much. Would it make sense to expose some kind of "simple"
api for stuff like this? In ipython, we abstracted various things to
ipapi that can be used to extend ipython. I think this would be a boon
to leo as well (and especially ileo, since completion there does not
require "analysis" of any kind).

As I said, all I need would be is for leo to call callback/hook with
signature like

def complete(line-up-to-cursor, current_node) => list of strings

This should make writing leo's own completers easier as well (it
doesn't need to be "hard wired" to leo core).

--
Ville M. Vainio - vivainio.googlepages.com
blog=360.yahoo.com/villevainio - g[mail | talk]='vivainio'


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Edward K. Ream  
View profile  
 More options Sep 7 2008, 11:42 am
From: "Edward K. Ream" <edream...@gmail.com>
Date: Sun, 7 Sep 2008 10:42:47 -0500
Local: Sun, Sep 7 2008 11:42 am
Subject: Re: Run @button's in ileo, and tab completion
On Sun, Sep 7, 2008 at 4:59 AM, Ville M. Vainio <vivai...@gmail.com> wrote:

> As I said, all I need would be is for leo to call callback/hook with
> signature like

> def complete(line-up-to-cursor, current_node) => list of strings

I missed this the first time around.  Glad you asked again.

This should not be too difficult to do.  I'll do it after I fix the
two urgent bugs.

This is probably a matter of 5-20 lines of code.  More importantly,
this suggests an alternative to "always-on" autocompletion.  It would
be a nice generalization to allow the completion to be done anywhere
on a line, rather than having the logic start at the beginning of what
the code calls the autocompletion chain.

Actually, there is already logic to find the start of the chain, so
the whole thing may be quite easy to do without even having to handle
(explicitly) the behind-the-scenes ivars.

OTOH, I'm not sure how bound together the output code (writing to the
completion tab) is with the more fundamental code.  Some refactoring
might be required.  But probably not: at worst, the code could just
use a "suppress output" hack.  We shall see.

Edward


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ville M. Vainio  
View profile  
 More options Sep 13 2008, 12:29 pm
From: "Ville M. Vainio" <vivai...@gmail.com>
Date: Sat, 13 Sep 2008 19:29:05 +0300
Local: Sat, Sep 13 2008 12:29 pm
Subject: Re: Run @button's in ileo, and tab completion
On Sat, Sep 6, 2008 at 4:18 PM, Edward K. Ream <edream...@gmail.com> wrote:

>> Can I create buttons directly without relying on @button nodes, e.g. with something like:

>> c.new_button('hello', my_callback)

> Of course.  You don't think the @button code does all the work itself, do you?

Ok, it was indeed as simple as doing:

def mkbutton(text, node_to_push):
    ib = c.frame.getIconBarObject()
    ib.add(text = text, command = node_to_push.ipush)

Some notes:

- Perhaps stuff like this could be abstracted away from gui classes to "leo API"
- "callback" would be more descriptive keyword arg name for arg() than
'command' (since passing a normal callable to it seems to be ok).

--
Ville M. Vainio - vivainio.googlepages.com
blog=360.yahoo.com/villevainio - g[mail | talk]='vivainio'


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Edward K. Ream  
View profile  
 More options Sep 15 2008, 10:02 am
From: "Edward K. Ream" <edream...@gmail.com>
Date: Mon, 15 Sep 2008 09:02:21 -0500
Local: Mon, Sep 15 2008 10:02 am
Subject: Re: Run @button's in ileo, and tab completion
On Sat, Sep 13, 2008 at 11:29 AM, Ville M. Vainio <vivai...@gmail.com> wrote:

> Ok, it was indeed as simple as doing:

> def mkbutton(text, node_to_push):
>    ib = c.frame.getIconBarObject()
>    ib.add(text = text, command = node_to_push.ipush)

> Some notes:

> - Perhaps stuff like this could be abstracted away from gui classes to "leo API"

I think what you are asking is for the tkIconBarClass class to be a
subclass of an inconBarClass, defined in leoFrame.py.  This is the
general way that Leo handles such matters.

I was a bit surprised that such a class doesn't exist.  But then I saw
the icon bar convenience methods.  So the following should also work:

c.frame.addIconButton(text=text,command=node_to_push.ipush)

I'm inclined to leave the code alone. YMMV.

> - "callback" would be more descriptive keyword arg name for arg() than
> 'command' (since passing a normal callable to it seems to be ok).

The argument is called "command" because that's the term used by Tk.
It's not worth changing, imo.

Edward


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google