Dialog API improvements

View: New views
11 Messages — Rating Filter:   Alert me  

Dialog API improvements

by Allan Odgaard-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

There have recently been a few patches to the Dialog plug-in that I  
have yet to role in.

Mainly because the current architecture does not scale well with new  
functionality.

We have spoken a bit about it on IRC, but since not all contributors  
are on IRC, I am moving the discussion to this list.

The restructuring I am envisioning is to move to a command based  
system so that the basic syntax is:

     tm_dialog «command» [«options»]

Additionally there will be:

     tm_dialog help «command»

And just tm_dialog to get a list of commands.

Each command will be responsible for a certain function. Presently we  
have these things (including pending patches):

     Synchronous nib loading
     Asynchronous nib loading
     Pop-up menu
     Type-to-narrow pop-up list
     File dialog (open/save)
     System dialog (color/font)
     HTML tool tips

In my mind, each should be a fully self-contained file providing that  
functionality. From an architectural POV I imagine that tm_dialog will  
basically connect to the Dialog plug-in using distributed-objects (as  
now) and send it:

     1. The full command line (i.e. with arguments)
     2. File handles for tm_dialog’s stdin, stdout, and stderr

Basically all work will then be done in the Dialog plug-in. Which will  
conceptually do:

     1. Check what command the command line arguments contain
     2. Lookup a class/object to handle that command in a dictionary
     3. Pass on the info to that class/object (if found).

So the main thing that needs to be worked out is a super class for the  
commands to subclass. This has two jobs:

     1. Provide a method for the subclass to register a command  
(called e.g. in +load)
     2. Provide an interface for the method that is called when the  
command should go into action

All in all that should be quite simple. Though we probably want a bit  
of sugar, such as converting the arguments to an NSDictionary (rather  
than have each command use getopt_long etc.) and maybe a few other  
things.

A minor concern is how a command can signal tm_dialog to wait for a  
semaphore, as is presently required by the nib-loading command (when  
given e.g. the -w option)

A bigger concern is what to do with backwards compatibility. Maybe it  
would be possible to let $DIALOG point at a script that rewrites the  
arguments, and then introduce a new variable for the new tm_dialog  
command.

_______________________________________________
textmate-plugins mailing list
textmate-plugins@...
http://lists.macromates.com/mailman/listinfo/textmate-plugins

Re: Dialog API improvements

by Allan Odgaard-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 20/09/2007, at 16:45, Allan Odgaard wrote:

> [...]
> The restructuring I am envisioning is to move to a command based  
> system so that the basic syntax is:
>     tm_dialog «command» [«options»]
> [...]

I should mention that another candidate is to use an object oriented  
approach, so we would have:

     tm_dialog create (window|menu|…)

And later that object could be manipulated with other commands.

Though given how only few of the commands follow the ‘create,  
manipulate, dispose’-cycle, it is probably not a good interface.

_______________________________________________
textmate-plugins mailing list
textmate-plugins@...
http://lists.macromates.com/mailman/listinfo/textmate-plugins

Re: Dialog API improvements

by Hans-Jörg Bibiko :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

my FIRST thought is something like that:


tm_dialog LISTTOKENS

tm_dialog UPDATETOKEN <token>

tm_dialog CLOSETOKEN <token>

tm_dialog WAITFORTOKEN <token>


tm_dialog SHOW PopupMenu WITH '{menuItems={title=A;};}'

tm_dialog SHOW RequestString WITH '{prompt=A;string=Hello;}' AS  
'centered modal'

tm_dialog SHOW OpenPanel AS 'modal centered' ADD Accessory.nib WITH  
'{...}'
tm_dialog WITH '{...}' SHOW OpenPanel AS 'modal centered'

tm_dialog SHOW SavePanel ADD Accessory.nib WITH '{...}' AS modal

tm_dialog SHOW InteractivePopupMenu WITH 'suggestions=(...);' AS  
'modal quiet'

tm_dialog SHOW HTMLTooltip WITH '{...}'

tm_dialog SHOW MyNib ASYNC CREATENEWITEMS '{...}' AS 'centered'  
WITHDEFAULTS '{...}'
tm_dialog AS centered SHOW MyNib CREATENEWITEMS '{...}' ASYNC


So you write a kind of an English sentence with variable word order.

The entire arguments could be parsed into a NSDictionary and sent to  
the 'super class' to dispatch.

Regards,

Hans
_______________________________________________
textmate-plugins mailing list
textmate-plugins@...
http://lists.macromates.com/mailman/listinfo/textmate-plugins

Re: Dialog API improvements

by Chris Thomas-7 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Sep 20, 2007, at 11:26 AM, Allan Odgaard wrote:

> On 20/09/2007, at 16:45, Allan Odgaard wrote:
>
>> [...]
>> The restructuring I am envisioning is to move to a command based  
>> system so that the basic syntax is:
>>    tm_dialog «command» [«options»]
>> [...]
>
> I should mention that another candidate is to use an object oriented  
> approach, so we would have:
>
>    tm_dialog create (window|menu|…)
>
> And later that object could be manipulated with other commands.
>
> Though given how only few of the commands follow the ‘create,  
> manipulate, dispose’-cycle, it is probably not a good interface.

Reverse the order and it can be done without forcing other commands to  
conform: "tm_dialog (window|menu) create". That's probably the most  
flexible solution.

But, it might be better to use the former approach with different  
verbs: "show" for synchronous and "create" for asynchronous.  
"tm_dialog show menu", for example, makes perfect sense and allows the  
"create" verb to be added later if there's ever a reason to manipulate  
a menu asynchronously.

The implementation in the Dialog plugin would use the second argument  
as a key for the command subclass, and then dispatch the command line  
to the subclass. This has the side effect of possibly slightly  
simplifying the implementation of "tm_dialog help <noun>".

Chris

_______________________________________________
textmate-plugins mailing list
textmate-plugins@...
http://lists.macromates.com/mailman/listinfo/textmate-plugins

Re: Dialog API improvements

by Joachim Mårtensson :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I prefer having the following interface

tm_dialog <option> --flag1
--flag2=/usr/bin/no/spaces/between/path/equal/and/flag

possibly with the special case

tm_dialog help <option>

which could be written as the not so special

tm_dialog <option> --help

the above has the benefit of not require a more involved parser.  I think
we should wait with the show and create keywords until there are enough
commands to warrant wandering of the 'tm_dialog <option> <--flag> path. I
do not think that the normal usage pattern of tm_dialog requires anything
more involved, I would guess that people write a command once and stores
it in a {rb,py}. Calling it by hand from the Command Line is probably a
very uncommon behavior (except when debugging). What I am trying to say is
that while more involved schemas look cool they are more complicated to
write and in the end there will be very few cheering for our insane coding
skills anyway.

here is some data-structures I wrote for an overhaul of the system
yesterday. I made the decision to not support tm_dialog show-dialog
nibFile.nib but instead enforce tm_dialog show-dialog --file=nibFile.nib

struct subCommand {
    const char *commandName;
    void (*func)(std::map<std::string,std::string> strings,
    std::map<std::string,bool> bools, int argc,  char * argv[]);
    const char* options[10];
    const char* mandatory[10];
};

static struct subCommand commands[] = {
/* name , call_funtion, optional flags, mandatory flags */
    {"create-alert", create_alert, {"parameters="}
    ,0},
    {"create-window",create_window,{"parameters=","center","defaults=","modal","quiet"},{"file="}},
    {"create-extended-popup",create_extended_popup,{"parameters="},0},
    {"create-menu",create_menu, {"parameters="},0},
    {"create-async-window",create_async_window,
        {"parameters=","center","defaults=","new-items="},{"file="}},
    {"close-window",close_window,
    {0},
    {"token="}},
    {"update-window",update_window,{0},{"token="}},
    {"wait-for-input",wait_for_input,{0},{"token="}},
    {"list-windows",list_window,{0},0}};
flags ending with = takes an argument.

I guess I could switch from stdlib types to cocoa ones, the struct
converted to some plist thing, perhaps the classes could conform to some
protocol so that they could supply which optional and mandatory flags they
support. and then a generic parser could be used if someone wanted that?

Joachim Mårtensson



_______________________________________________
textmate-plugins mailing list
textmate-plugins@...
http://lists.macromates.com/mailman/listinfo/textmate-plugins

Re: Dialog API improvements

by Chris Thomas-7 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Sep 20, 2007, at 11:34 PM, Joachim Mårtensson wrote:

> the above has the benefit of not require a more involved parser.  I  
> think
> we should wait with the show and create keywords until there are  
> enough
> commands to warrant wandering of the 'tm_dialog <option> <--flag>  
> path. I
> do not think that the normal usage pattern of tm_dialog requires  
> anything
> more involved, I would guess that people write a command once and  
> stores
> it in a {rb,py}. Calling it by hand from the Command Line is  
> probably a
> very uncommon behavior (except when debugging). What I am trying to  
> say is
> that while more involved schemas look cool they are more complicated  
> to
> write and in the end there will be very few cheering for our insane  
> coding
> skills anyway.

I prefer to stick with "--switch" for optional arguments, but I think  
you actually simplify the implementation slightly if you use an  
"object-oriented" syntax. The core dispatching code for a noun-verb  
("create|show|close window") would look something like:

@implementation TMUIServer
- (void)dispatchCommandLine:(NSArray *)commandLineItems
{
        // We must have a verb and a noun (TODO: handle --version)
        NSParameterAssert([commandLineItems count] > 2);
       
        NSString * verb = [commandLineItems objectAtIndex:0];
        NSString * noun = [commandLineItems objectAtIndex:1];
       
        // Find the command corresponding to the noun (TODO: this could be  
lazier and instantiate objects on demand)
        TMUICommand * UICommand = [sSubcommandDictionary objectForKey:noun];
       
        // Dispatch the verb to the noun
        NSString * methodName = [NSString stringWithFormat:@"perform
%@WithArguments:", [verb capitalizedString]];
        SEL methodSelector = NSSelectorFromString(methodName);
       
        if([UICommand respondsToSelector:methodSelector])
        {
                id error = objc_msgSend(UICommand, methodSelector, commandLineItems);
        }
        else
        {
                // raise exception...
        }
}
@end

Parsing the remainder of the arguments would be the subcommand's  
responsibility, probably using a method provided for that purpose in  
the base class. This structure provides the property that any changes  
to a subcommand, even to accept a different set of arguments, are  
limited to that subcommand's source code. It allows new commands to be  
added without modifying any common code.

You can do the same thing with a single subcommand name ("tm_dialog  
create-window file.nib") as a part of the command name by storing a  
"command -> [class, selector]" mapping instead of the simpler "noun ->  
class" mapping. But I think I still prefer the "noun verb" syntax,  
because it enforces two desirable attributes when creating new  
commands: (a) the command is readable in source code and (b) there is  
room for future expansion.

Chris

_______________________________________________
textmate-plugins mailing list
textmate-plugins@...
http://lists.macromates.com/mailman/listinfo/textmate-plugins

Re: Dialog API improvements

by Joachim Mårtensson :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> I prefer to stick with "--switch" for optional arguments, but I think
> you actually simplify the implementation slightly if you use an
> "object-oriented" syntax. The core dispatching code for a noun-verb
> ("create|show|close window") would look something like:
>
Ok I was under the impression that some nouns would go without verb,
making it non obvious when to use which, I am fine with the above.

> Parsing the remainder of the arguments would be the subcommand's
> responsibility, probably using a method provided for that purpose in
> the base class. This structure provides the property that any changes
> to a subcommand, even to accept a different set of arguments, are
> limited to that subcommand's source code. It allows new commands to be
> added without modifying any common code.
I agree with this as well.

>
> You can do the same thing with a single subcommand name ("tm_dialog
> create-window file.nib") as a part of the command name by storing a
> "command -> [class, selector]" mapping instead of the simpler "noun ->
> class" mapping. But I think I still prefer the "noun verb" syntax,
I find it a bit verbose and unfamilar (I do not think I have used many
shell commands that use
this structure), but I have no proplems accepting it if it is what people
want.

> because it enforces two desirable attributes when creating new
> commands: (a) the command is readable in source code and (b) there is
> room for future expansion.
>
> Chris
>
> _______________________________________________
> textmate-plugins mailing list
> textmate-plugins@...
> http://lists.macromates.com/mailman/listinfo/textmate-plugins
>


_______________________________________________
textmate-plugins mailing list
textmate-plugins@...
http://lists.macromates.com/mailman/listinfo/textmate-plugins

Re: Dialog API improvements

by Hans-Jörg Bibiko :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

HI,

OK, let me ask: Who are writing a tm_dialog command? I guess the  
majority of user is more or less skilled in writing source code. So,  
the 'old-fashioned' way by using argument options should not be a  
problem.

The only thing to do is to name these options more consistently.

OLD:
  -e, --alert
  -u, --menu
  -a, --async-window

  -c, --center
  -d, --defaults
  -n, --new-items
  -m, --modal
  -p, --parameters
  -q, --quiet

  -l, --list-windows
  -t, --update-window
  -x, --close-window
  -w, --wait-for-input

NEW:
  -s, --show <InlineMenu,OpenPanel {<accessory view  
nib>},RequestString,Alert,MyNIB,HTMLToolTip,InteractivePopUp...> => sync
  -i, --init <nib_file> => async

  -c, --center
  -d, --defaults <plist>
  -n, --new-items <plist>
  -m, --modal
  -p, --parameters <plist>
  -q, --quiet

  -l, --list-windows <token>
  -r, --refresh-window <token>
  -k, --kill-window <token>
  -w, --wait-for-input <token>


Note for options -s: if the first argument is a system panel like  
Open, Save, ColorPicker, etc. check whether it follows a nib file for  
the accessory view.

This would have the advantages that you can use both argument  
structures, meaning the backwards compatibility would be solved, and  
it would be easy to expand the existing source code.



Hans
_______________________________________________
textmate-plugins mailing list
textmate-plugins@...
http://lists.macromates.com/mailman/listinfo/textmate-plugins

Re: Dialog API improvements

by Rob Rix :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

>> You can do the same thing with a single subcommand name ("tm_dialog
>> create-window file.nib") as a part of the command name by storing a
>> "command -> [class, selector]" mapping instead of the simpler "noun  
>> ->
>> class" mapping. But I think I still prefer the "noun verb" syntax,
> I find it a bit verbose and unfamilar (I do not think I have used many
> shell commands that use
> this structure), but I have no proplems accepting it if it is what  
> people
> want.

e.g. git and svn have fairly verbose syntaxes; the various Rails  
scripts tend to also, although that's a less compelling case.

I'm in favour.

Rob
_______________________________________________
textmate-plugins mailing list
textmate-plugins@...
http://lists.macromates.com/mailman/listinfo/textmate-plugins

Re: Dialog API improvements

by Hans-Jörg Bibiko :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On 21.09.2007, at 09:21, Hans-Jörg Bibiko wrote:

> NEW:
>  -s, --show <InlineMenu,OpenPanel {<accessory view  
> nib>},RequestString,Alert,MyNIB,HTMLToolTip,InteractivePopUp...> =>  
> sync
>  -i, --init <nib_file> => async
>
>  -c, --center
>  -d, --defaults <plist>
>  -n, --new-items <plist>
>  -m, --modal
>  -p, --parameters <plist>
>  -q, --quiet
>
>  -l, --list-windows <token>
>  -r, --refresh-window <token>
>  -k, --kill-window <token>
>  -w, --wait-for-input <token>
>

Furthermore one could set not only $DIALOG but also the following  
variables in order to abbreviate common used commands:

$DILAOG_SHOWNIB nib plist => tm_dialog -m -s $1 -p $2
$DIALOG_INITNIB nib plist => tm_dialog -i $1 -p $2
$DIALOG_SHOWPANEL panel {nib} plist => tm_dialog -s $1 (argc==3)?
$2:"" -p (argc==3)?$3:$2
...

and I forgot the option -h for help. This option would open a pdf/
html/man... file showing a complete manual with examples for tm_dialog.

Chris' suggestion with:
- (void)dispatchCommandLine:(NSArray *)commandLineItems{}

is a very flexible approach and has many advantages.

The question is: What will the future bring us? As far as I  
understood the philosophy of tm_dialog it is a tool to provide the  
user 'only' with several kinds of dialog windows. There are some  
things which are in my mind and worth to be added to tm_dialog, e.g.  
to place the window to given origin point or place it under the  
caret's position, to change some attributes of the window or of nib  
components in respect of appearance, fading, resizing etc. but all  
these things can be specified within the PLIST. This would also mean  
that options like '-c' and '-q' could be set within the PLIST if one  
understand the PLIST as parameters which control the content AND the  
appearance of the given nib.

Other commands like Play a self-defined macro, or Execute a batch of  
bundle macros, snippets, commands, templates, etc. belongs to an  
other plug-in.

By my opinion: Keep things simple as possible.

--Hans

PS:
On totally other approach I read in the internet is to specify the  
behaviour of the nib within the nib as hidden Switches, Radio  
Buttons, etc.. That would mean you have Radio Buttons for Sync and  
Async; Switches for quiet, modal, and centered etc. These have a  
default and can be overwritten. But I believe this is not adoptable  
to tm_dialog.


_______________________________________________
textmate-plugins mailing list
textmate-plugins@...
http://lists.macromates.com/mailman/listinfo/textmate-plugins

Re: Dialog API improvements

by Allan Odgaard-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 20/09/2007, at 18:34, Chris Thomas wrote:

> [...]
> Reverse the order and it can be done without forcing other commands  
> to conform: "tm_dialog (window|menu) create". That's probably the  
> most flexible solution.
>
> But, it might be better to use the former approach with different  
> verbs: "show" for synchronous and "create" for asynchronous.  
> "tm_dialog show menu", for example, makes perfect sense and allows  
> the "create" verb to be added later if there's ever a reason to  
> manipulate a menu asynchronously.
>
> The implementation in the Dialog plugin would use the second  
> argument as a key for the command subclass, and then dispatch the  
> command line to the subclass. This has the side effect of possibly  
> slightly simplifying the implementation of "tm_dialog help <noun>".

I like this a lot, I’ll write some code to support this probably later  
tonight.

_______________________________________________
textmate-plugins mailing list
textmate-plugins@...
http://lists.macromates.com/mailman/listinfo/textmate-plugins