1.50: scripting first test

Started by alex, July 26, 2011, 04:33:24 AM

Previous topic - Next topic

alex

Hi,

here I will publish first examples for scripting in HippoEDIT. First no documentation, only examples.
So, interested can check what will come and try it a little bit. But I do not promise that API ill not change until final release of 1.50.

To get brief overview of API function you can use this raw help file (chm file).
To execute scripts you need latest version of 1.50 alpha.
There are two ways to call script currently:
- open script file and use Tools->Execute "Current file" command
- Create a tool, taking script path into command window. It should work as normal tool, and called tool script.
- In next version will be introduced also so called service scripts. They will work based on events registration and can run resident in parallel.

HippoEDIT supports any installed active scripting engine. By default supported  JavaScript and VBScript. If you start any VBS or JS file inside of HippoEDIT with Execute command or as tool, HE will assume that it is HE script and will try to execute passing scripting objects. So it can work with any *.js or *.vbs file. But for convenience there are also dedicated schemes inherited from JS ans  VBS syntaxes and associated with *.hejs and *.hevbs extensions correspondingly. Dedicated schemes extended by HE specific syntax. Till now only HEJS schema is up to date. HEVBS will be updated later.

Script files support includes (see usage of include.js for example). Usage of include files from other supporting scripting language is also supported (you can include JS includes in VBS scripts for example).
HippoEDIT team
[url="http://www.hippoedit.com/"]http://www.hippoedit.com/[/url]

alex

#1
more scripts
HippoEDIT team
[url="http://www.hippoedit.com/"]http://www.hippoedit.com/[/url]

alex

small VBS example
HippoEDIT team
[url="http://www.hippoedit.com/"]http://www.hippoedit.com/[/url]

Stefan

#3
Thank you for your great work Alex!

This looks rather like an complicated syntax. I was more thinking about an simple 'one-line' syntax.
But as every time: if you do it you do it well.  Taking an closer lock the syntax seams as easy as HTML code.


I think with this HE scripting all will be possible.
I mean, other editors have scripting features too, but without an handy UI like you build for HE they are
limited to simple actions mostly and tricky to use for more feature-rich needs. We all know this simple InputBox questions,
most three or four in an row to prompt the user for his options only to script an simple text modification. With HippoEDIT
scripting GUI features the user can build very professional locking (and working) tools for his own needs without HE itself
will become an 'all-features-in-one-app-monster'.

Let's see how long it needs till THIS feature will seen in other editors too like so many in the past.

I can see the power of the programming language style syntax and have to play around to get used to it.

Here are some impressions for those who are not so familiar with scripting or don't want to download and test an alpha build,
(but don't be afraid, since the scripts are already wrote, your part only is to execute them)
Stefan, HippoEDIT beta tester 
HippoEDIT - the editor programmers wants to code thyself when they are dreaming.        -Don't just edit. HippoEDIT!-

Stefan

My first own dialog (well just copy and paste and a little modified.
[attach=1]


(Note: the alert() at the end of the code  is just non-working dummy code)
Stefan, HippoEDIT beta tester 
HippoEDIT - the editor programmers wants to code thyself when they are dreaming.        -Don't just edit. HippoEDIT!-

alex

#5
Hi Stefan,

if you only want to provide support for input fields and combos, yes it possible to go with "one-line" syntax. But if you want to provide similar level of flexibility as have plugins, it is impossible. Hippoedit provides a lot of controls with a lot of properties with layout possibilities, try to imagine syntax you need to invent for such "one-line" representation. And it should be well formed, with escaping and robust to accept some level of errors. And at the end you need to teach a user of how to use it.
Using XML is standard (for HE), well formed, and fast because already optimized in HE. So it was an  obvious and right choice. I have evaluated it for a long time beforehand.
Example from NotePad it is cryptic nightmare :)

I will try to publish syntax description for XML dialogs, with explanations for all properties.
And I have updated the initial post with raw chm with interface description.

About your examples:
- you (because I know your preferences) can also use VBS for scripting (forgot, the schema is not done for it, but it will work, even then not syntax highlighted). I just have more experience with JS.
- id property for dialog, used for persistence of size and dialog position, that is maybe why layout of your dialog is strange (buttons are not at the bottom)
- you can play with required fields, if they do not filled, "positive" buttons will be disabled. Yon need to use predefined "ok" "apply" as returnvals to make it working.
- you can also mark paragraph as required, than it will have red asterisk.
- for getting results from dialog, you can use as SettingsStorage object (CreateStorage), as automatic way, in which HE reads variables from script by id and updates them on "positive" dialog end.
- if you create a xml dialog, try to use special syntax ('@ - @'), which will enable specialized parser for it.

I will update dialog_actions.hejs with an example.

BR, Alex.
P.S: and thank a lot for a feedback :)
HippoEDIT team
[url="http://www.hippoedit.com/"]http://www.hippoedit.com/[/url]

Stefan

#6
Alex>About your examples:
Alex>- you (because I know your preferences) can also use VBS for scripting
I try to use (learn) JS too.


Alex>- id property for dialog, used for persistence of size and dialog position,
I do not see any mistake i have done. What should i change?

Alex>- you can play with required fields, if they do not filled, "positive" buttons will be disabled.
Alex>- you can also mark paragraph as required, than it will have red asterisk.
Alex>- if you create a xml dialog, try to use special syntax ('@ - @'), which will enable specialized parser for it.
Yes, already seen.

Alex>Yon need to use predefined "ok" "apply" as returnvals to make it working.
"My" returnvals are "Ok" and "Cancel" as copied from your script. Only i changed the button labels (title).
What do you mean? Have i make it wrong?

Alex>- for getting results from dialog, you can use as SettingsStorage object (CreateStorage), as automatic way,
Alex> in which HE reads variables from script by id and updates them on "positive" dialog end.
How? How can i get the value of ID "itb" ?

Code (javascript) Select

var myDialog = '@<dialog title="Insert text" id="test"> \
<paragraph text="Enter the text to be inserted before and/or after each selected line"/><spacer/> \
   <group><paragraph text="Before:" minwidth="6" align="left"/><edit id="itb" minwidth="35"/></group> \
   <group><paragraph text="After:" minwidth="6" align="left"/><edit id="ita" minwidth="35" /></group> \
   <group uniform="true" align="right|bottom"> \
   <button title="&amp;Lets go" returnval="ok" default="true"/> \
   <button title="&amp;No thanks" returnval="cancel"/> \
   </group> \
</dialog>@';

// write something to standard output:
var HEOutput = Application.Output();
HEOutput.writeln("HippoEDIT version: " + Application.Version);

// get the user input into "varMyOutputStorage " and write to output "HEOutput":
var varMyOutputStorage = CreateStorage();
HEOutput.writeln("My dialog returns: " + dialog(myDialog, varMyOutputStorage));


My output:
Code (text) Select

HippoEDIT version: 1.50.721
My dialog returns: 1
Stefan, HippoEDIT beta tester 
HippoEDIT - the editor programmers wants to code thyself when they are dreaming.        -Don't just edit. HippoEDIT!-

JJK

Hi all
I downloaded HeApi.chm but I can't read it under Windows 7.
I had installed Windows6.1-KB917607-x86.msu from Microsoft which is designed to read .hlp files under Windows 7, but it does not work.

Any idea ?
TIA

Stefan

Quote from: JJK on August 02, 2011, 11:20:25 PM
I downloaded HeApi.chm but I can't read it
1. Right click on the file, and click on Properties.
2. Under the General tab,
click on the Unblock button beside the message, "This file came from another computer and might blocked to help protect  this computer."
and click on OK.
Stefan, HippoEDIT beta tester 
HippoEDIT - the editor programmers wants to code thyself when they are dreaming.        -Don't just edit. HippoEDIT!-

alex

Hi Stefan,

id="test" - I noticed that your dialog is bigger than content and buttons are not aligned to bottom, this is or a bug, or you have used same id for a dialog with bigger size, and size was stored ans used for all dialogs with same id. And because dialog was not marked as resizable, there is no way to make it smaller (this is maybe a bug, I will check).

Quote"My" returnvals are "Ok" and "Cancel" as copied from your script. Only i changed the button labels (title).
What do you mean? Have i make it wrong?
Now I see, they are fine. Generally you can use as hard-coded enumerations, as any integer number there. Values from -1 till 9 are mapped to enumerations. Some enumerations are positive (as I mentioned "ok", "yes"), and there are some built-in extras for them, as auto-disable by missing required fields and auto apply of script variables on finish of the dialog using them.

QuoteHow? How can i get the value of ID "itb" ?
There are two ways: implicit and explicit.
- implicit:
add this code before calling of the dialog (line 17).
Code (javascript) Select
var itb="/*";
var ita="*/";

you do not need to assign values, they are optional and just read before and used as defaults.
With such code after start of your dialog you will have fields filled with "/*" and "*/" and if you will select "ok" button, modified values will be copied back.
There is one important point about such implicit way - it works ONLY for GLOBAL variables. For vars from withing functions, for example, it will not work.

- explicit:
Works always, and requires usage of settings storage object, the same way as you do if you want to save script values between sessions or share them between scripts.
Add this code before calling of the dialog:
Code (javascript) Select
var varMyOutputStorage = CreateStorage();
varMyOutputStorage.write("itb", "/*");
varMyOutputStorage.write("ita", "*/");

and this after calling of the dialog. Variables will be updated in any case, independent from return code. This is your job to check return code and read or not read variables back:
Code (javascript) Select
var varMyOutputStorage = CreateStorage();
var itb = varMyOutputStorage.read("itb");
var ita = varMyOutputStorage.read("ita");


if you do not want to initialize variables before, you can skip first part, and only read variables from storage later. They will be created automatically in the map, based on id properties in dialog definition.

P.S: I have updated your message with syntax highlighting for you code snippet. I thought you have already seen this - check toolbar. Also now in-line images are supported.

HippoEDIT team
[url="http://www.hippoedit.com/"]http://www.hippoedit.com/[/url]

Stefan

#10
Alex> id="test" - I noticed that your dialog is bigger
That was the only dialog and the only ID "test" in that script.
But today the dialog looks normal, as expected.
HE has waited for me over night with that script open, and i didn't modified the dialog,..
only the output code as your reply shows, started the script and... the buttons are at the bottom now.

[attach=1]


- - -

Thanks for your explanation, i got it working:

- implicit

Code (javascript) Select

// initialize the output vars, and set default values if wanted:
var ID_itb="not used by user";
var ID_ita="";

// build up your dialog and store it in var vMyDialog:
var vMyDialog = '@<dialog title="Insert text" id="test"> \
<paragraph text="Enter the text to be inserted before and/or after each selected line"/><spacer/> \
   <group><paragraph text="Before:" minwidth="6" align="left"/><edit id="ID_itb" minwidth="35"/></group> \
   <group><paragraph text="After:" minwidth="6" align="left"/><edit id="ID_ita" minwidth="35" /></group> \
   <group uniform="true" align="right|bottom"> \
   <button title="&amp;OK" returnval="ok" default="true"/> \
   <button title="&amp;Cancel" returnval="cancel"/> \
   </group> \
</dialog>@';

// execute the dialog:
var vErrorcode = dialog(vMyDialog);

// if [OK] is clicked...
if (vErrorcode==1){
// write to HEs standard output:
var vHEOutput = Application.Output();
vHEOutput.clear();
vHEOutput.writeln("HippoEDIT version: " + Application.Version);
vHEOutput.writeln("Returned error code: " + vErrorcode);
vHEOutput.writeln("Text to be inserted before: " + ID_itb);
vHEOutput.writeln("Text to be inserted after: " + ID_ita);
}


Execute this script and just pressing [OK] results into:

HippoEDIT version: 1.50.721
Returned error code: 1
Text to be inserted before: not used by user
Text to be inserted after:





- explicit

Code (javascript) Select

// build up your dialog and store it in var vMyDialog:
var vMyDialog = '@<dialog title="Insert text" id="test"> \
<paragraph text="Enter the text to be inserted before and/or after each selected line"/><spacer/> \
   <group><paragraph text="Before:" minwidth="6" align="left"/><edit id="ID_itb" minwidth="35"/></group> \
   <group><paragraph text="After:" minwidth="6" align="left"/><edit id="ID_ita" minwidth="35" /></group> \
   <group uniform="true" align="right|bottom"> \
   <button title="&amp;OK" returnval="ok" default="true"/> \
   <button title="&amp;Cancel" returnval="cancel"/> \
   </group> \
</dialog>@';

// create new instance of an settings storage object:
var vMyOutputStorage = CreateStorage();
// set default values (if wanted):
vMyOutputStorage.write("ID_itb", "default value for \"before\"");
//vMyOutputStorage.write("ID_ita", "default value for \"after\"");

// execute the dialog and use OutputStorage to store the user input:
var vErrorcode = dialog(vMyDialog, vMyOutputStorage);

// if [OK] is clicked...
if (vErrorcode==1){
// get the user input:
var vITB = vMyOutputStorage.read("ID_itb");      if (vITB==""){vITB="'Before' is not used by user";}
var vITA = vMyOutputStorage.read("ID_ita");      if (vITA==""){vITA="'After' is not used by user";}

// write to HEs standard output:
var vHEOutput = Application.Output();
vHEOutput.clear();
vHEOutput.writeln("HippoEDIT version: " + Application.Version);
vHEOutput.writeln("Returned error code: " + vErrorcode);
vHEOutput.writeln("Text to be inserted before: " + vITB);
vHEOutput.writeln("Text to be inserted after: " + vITA);
}


Execute this script and just pressing [OK] results into:

HippoEDIT version: 1.50.721
Returned error code: 1
Text to be inserted before: default value for "before"
Text to be inserted after: 'After' is not used by user


Where is the thump-up smiley?  ;D
Stefan, HippoEDIT beta tester 
HippoEDIT - the editor programmers wants to code thyself when they are dreaming.        -Don't just edit. HippoEDIT!-

JJK

Quote from: Stefan on August 03, 2011, 12:04:05 AM
1. Right click on the file, and click on Properties.
2. Under the General tab,
click on the Unblock button beside the message, "This file came from another computer and might blocked to help protect  this computer."
and click on OK.
Many thanks. It works well now.
I didn't know that feature :( but now I know it :) 

Ramon

#12
I just playin with this new feature.

When I use csript with script like bellow I do not see CMD window. But if I use adapted script for HE and run "Tools->Execute Test.js", CMD window has appear. What I need to do to hide CMD window.

Script for cscript:
Code (javascript) Select

var WshShell = new ActiveXObject("WScript.Shell");
var WshExec = WshShell.Exec("cmd /c dir c:\\");

while (!WshExec.StdOut.AtEndOfStream)
WScript.Echo( WshExec.StdOut.ReadLine() );


Script for HE:
Code (javascript) Select

var Output = Application.Output();
var WshShell = new ActiveXObject("WScript.Shell");
var WshExec = WshShell.Exec("cmd /c dir c:\\");

Output.clear();

while (!WshExec.StdOut.AtEndOfStream)
Output.writeln( WshExec.StdOut.ReadLine() );

alex

#13
Hi Ramon,

It does not work with first example, because HE does not know what to do with  WScript.Echo :) You send output to WScript and where it sends it further I have no clue :) But OK, maybe in this case I also need to catch standard output. The only problem, is it can conflict with usage of unnamed Output (same pane) from withing the script. But maybe that is fine. I will check.

About second example. I think this is too complicated :) Check scripting.hejs for example:
Code (javascript) Select
// capture cmd.exe and execute a command
var output_cmd = Application.Output("CMD");
output_cmd.Capture("cmd.exe", "", "exit");
Application.sleep(1000);
output_cmd.AddCommand("dir");
Application.ClosePane("", output_cmd);


There is also a way to just run tool in background and capture the standard output in string variable:
Code (javascript) Select
var sResult = CaptureOutput("test.bat");
See attached heapi.chm for parameters.

If you close standard pane, it is just hidden. If you close custom pane (named output fex), it is really closed.
For now to way to just hide it. Maybe I need to add this, but not yet done.

BR, Alex
HippoEDIT team
[url="http://www.hippoedit.com/"]http://www.hippoedit.com/[/url]

Stefan

Alex, the first script from Ramon was an example only, tested outside of HE by involving script.exe.

Common info:
WScript is an object of the Windows Scripting Host, meaning only available by using cScript.exe or wScript.exe
Since HippoEDIT is it own scripting host, the WScript object is not involved at all.


An other idea for
var WshExec = WshShell.Exec("cmd /c dir c:\\");

maybe
var WshExec = WshShell.RUN( strCommand, intWindowStyle, bWaitOnReturn);
where intWindowStyle could be '0' (Hides the window)

See
http://msdn.microsoft.com/en-us/library/d5fk67ky%28v=vs.85%29.aspx
Stefan, HippoEDIT beta tester 
HippoEDIT - the editor programmers wants to code thyself when they are dreaming.        -Don't just edit. HippoEDIT!-