On Thursday, July 16, 2015 at 2:44:32 AM UTC-5, Israel Hands wrote:

Hi, I'm writing a very simple script and need to get interactive input from 
> the user. I have read the information in the docs and it seems a 
> complicated, can anyone point me to the simplest working example of a 
> script that uses interactivity?
>

Good question.  There should at least be a section in the scripting 
miscellany chapter <http://leoeditor.com/scripting-miscellany.html>, but at 
present there isn't.

Here is a relatively simple example.  I sniffed around Leo's sources for a 
template.  I picked @cmd('shell-command') pretty much at random, and then 
pared it down to this::

def interactive_example(event=None):
    '''Prompts for a number.'''
    k = c.k
    state_name = 'enter-a-number'
    state = k.getState(state_name)
    if state == 0:
        k.setLabelBlue('Enter a number: ')
        k.getArg(event, state_name, 1, interactive_example)
    else:
        n = k.arg
        k.clearState()
        k.showStateAndMode()
        c.frame.putStatusLine(n, bg='blue', fg='white')
        c.bodyWantsFocus()
        
interactive_example()

You can see this in action by executing the code above with Ctrl-B.

The challenge in any interaction is to coordinate keystrokes.  *All* 
keystrokes always go through k.masterKeyHandler.  So interactive code must 
do the correct incantations to make this work.  Let's look at this example 
line by line.

1. There must be a function (typically a method) to handle the 
interactions.  Usually the method implements a Leo command, which is why 
the event arg is supplied, but in this case the code actually doesn't ever 
use the event arg.

2. The first step in the code is to give your interaction a *unique name*, 
in this case, the string 'enter-a-number'.

3. Next, the code does:

state = k.getState(state_name)

Initially, state will be zero, because we aren't in the state.  So the code 
does:

k.setLabelBlue('Enter a number: ')
k.getArg(event, state_name, 1, interactive_example)

The first line puts a prompt into the minibuffer, the second calls the 
k.getArg to accumulate the desired value.  

k.getArg is a thin wrapper around the k.GetArg *class*, which has a 
gazillion options.  k.getArg will coordinate with k.masterKeyHandler to get 
the argument "interactively", that is, character by character.  k.getArg 
sets the state and state number using the second and third arguments.  
k.getArg supports Ctrl-G and Backspace by default, and can also handle tab 
completion as well as other esoterica.

When the user hits <Return> k.getArg will call the handler, the last arg in 
the call to k.getArg, with state == 1. The handler is interactive_example, so 
control reenters interactive_example, but this time with state == 1.  So 
now the following is executed:

n = k.arg
k.clearState()
k.showStateAndMode()
c.frame.putStatusLine(n, bg='blue', fg='white')
c.bodyWantsFocus()

k.getArg sets the k.arg value to the accumulated result.  g.getArg does no 
checking of the value of k.arg: that would be up to the handler.

The handler could call k.getArg again, with another state number if more 
interaction were desired.  When the interaction is finished, the handler 
must call k.clearState()
.
Leo's interaction mechanism is arguably too complex, but I think we're 
stuck with it.

Please feel free to ask more questions.

Edward

-- 
You received this message because you are subscribed to the Google Groups 
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/leo-editor.
For more options, visit https://groups.google.com/d/optout.

Reply via email to