Author Topic: 1.50: scripting first test  (Read 8292 times)

Offline alex

  • Developer
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2161
  • Karma: +37/-3
    • View Profile
    • HippoEDIT
Re: 1.50: scripting first test
« Reply #15 on: August 04, 2011, 11:46:25 am »
Hi Stefan,

thank for help here.

I think Ramons first example was correct. This should work correct (also used in my scripting.hejs):
Code: Javascript
  1. var WshShell = new ActiveXObject("WScript.Shell");
and you do not need to start cScript or wScript.exe. What xScript.exe are doing, is just starting as scripting host and initialize WshShell by internal objects, which are COM objects from some registered type library. The same does new ActiveXObject. So, this is a way how to execute/adopt scripts for WSH inside of HE.

But the problem is that WScript.Echo( WshExec.StdOut.ReadLine() ); uses standard output (console output), from WSH and normally I know how to catch it if it executes in other process (as done for tools), but currently for me is not sure how this should work, if it called in HE scripting host and where goes this Echo command. I will try to clarify this, because this can help to make easier scripts adoption....

BR, Alex

Offline Stefan

  • Administrator
  • Hero Member
  • *****
  • Posts: 775
  • Karma: +6/-0
    • View Profile
Re: 1.50: scripting first test
« Reply #16 on: August 04, 2011, 01:21:55 pm »
I don't know if i can make myself clear with all that 'host' and 'object'.


What i mean was:

"WScript.Shell" is not the same as the "WScript .dot" object in an script.


"WScript.Shell" is an string only to refer to the "WshShell object" registry entry
HKEY_CLASSES_ROOT\CLSID\{72C24DD5-D70A-438B-8A42-98424B88AFB8}\VersionIndependentProgID
to use this object for your script.



Where as "WScript .dot" as object in your script
is only instanced if you use the WSH as your host (via cscript/wscript)
but HE is its own host (as other text editors, or IE for that matter) and don't have access to this object.
http://msdn.microsoft.com/en-us/library/at5ydy31%28v=vs.85%29.aspx



So the simple use of
WScript.echo,
WScript.Quit,
WScript.BuildVersion, ... will not work inside HE.
http://www.devguru.com/technologies/wsh/quickref/wscript.html


Try 
C:\>cscript test.vbs

test.vbs
Code: Visual Basic
  1. Set WS = WScript.CreateObject("WScript.Shell") '//not need, only to see
  2.  
  3. WScript.echo WScript.Fullname & ", v:" & WScript.BuildVersion
  4. WScript.echo "Hi one"
  5. WScript.Quit
  6. WScript.echo "Hi two"

WScript Dot will only work for (c|w)script in WSH host. Not for other hosts.


I guess that's why (if i understand you right)
var WshShell = new WScript.CreateObject("WScript.Shell");
will not work
and you have created your own 'ActiveXObject' ?
var WshShell = new ActiveXObject("WScript.Shell");


Or, changes are good, you know more about that things under the hood... or i misunderstood the whole topic? Then excuse me.
« Last Edit: August 04, 2011, 01:59:22 pm by alex »

Offline alex

  • Developer
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2161
  • Karma: +37/-3
    • View Profile
    • HippoEDIT
Re: 1.50: scripting first test
« Reply #17 on: August 04, 2011, 02:08:11 pm »
Hi Stefan,

you are completely right, and I was wrong. I have overlooked, that Ramon has used WScript object directly. And yes, it is not possible to use it inside of HE (the script execution fails, because object is unknown, of course).
WScript is same as Application in HE. 

So, problem solved and no catch output necessary ;) What only can be done, is emulation of WScript object, by implementing same methods and forwarding them to HE specific methods.

BR, Alex

Offline Stefan

  • Administrator
  • Hero Member
  • *****
  • Posts: 775
  • Karma: +6/-0
    • View Profile
Re: 1.50: scripting first test
« Reply #18 on: August 10, 2011, 07:53:13 pm »
WOW the API chm is pretty full loaded with commands. You must have been very busy.

Would you please tell me how i can get and set selected text?
I only see "GetText start, end"

But i think about smtg like
varSel = GetSelectedText
and
SetSelectedText(varString)
to replace an selection.

Is this already there?

Offline alex

  • Developer
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2161
  • Karma: +37/-3
    • View Profile
    • HippoEDIT
Re: 1.50: scripting first test
« Reply #19 on: August 10, 2011, 08:16:55 pm »
Hi Stefan,

Selection does not belong to a Document but to a View (so called presentation). One document can have several Views and only one Active.
So, something like this should work:
Code: Javascript
  1. var ptStart, ptEnd;
  2. ActiveView.GetSelection(ptStart, ptEnd);
  3. ActiveView.Select(ptStart, ptEnd);
  4. ActiveDocument.GetText(ptStart, ptEnd);
  5. ActiveDocument.ReplaceText(ptStart, "New Text", ptEnd, 0);
  6. ActiveDocument.InsertText(ptStart, "Inserted Text", ptEnd, 0);

where point is structure with Line and Pos, but I am afraid that scripting (not a plugins), does not support structures, and I will need to replace this to two integer as line and position for start and end. I will check.

BR, Alex.

Offline alex

  • Developer
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2161
  • Karma: +37/-3
    • View Profile
    • HippoEDIT
Re: 1.50: scripting first test
« Reply #20 on: August 12, 2011, 03:00:46 am »
Hi Stefan,

I think I will need to replace all usages of POINT_T in API and my implementation by two int values for line and position... I was trying to change this fast, but I think I will not be able to update alpha before my vacation (from 13.08.2011 till 22.08.2011) - too many places should be adopted.
So, please wait with it till then.

BR, Alex.

Offline Stefan

  • Administrator
  • Hero Member
  • *****
  • Posts: 775
  • Karma: +6/-0
    • View Profile
Re: 1.50: scripting first test
« Reply #21 on: August 12, 2011, 10:47:31 am »
Of course take your time and have an nice vacation. Greetings to your family.


Just my thought:

But i don't understand your syntax:
ActiveView.GetSelection(ptStart, ptEnd);
ActiveDocument.GetText(ptStart, ptEnd);
ActiveDocument.ReplaceText(ptStart, "New Text", ptEnd, 0);

While it is good to know start and end point
sometimes i don't take care of this info
and only want to get or set (replace) the selected text
varSel = ActiveDocument.GetSelectedText
ActiveDocument.SetSelectedText varString
I want to make the syntax more easy to write for the most time, and use the extended syntax only f needed.

And the editor already knows the ptStart and ptEnd of an selection, why should the user execute this GetSelection command again?
F.ex.: In other editors i had to get the start and end point of an selection and calculate the selected lines on my own.
I hope HE will provide such infos just by build-in "variables"?
ActiveDocument.Info.CountLinesDocument
ActiveDocument.Info.CountLinesSelection
ActiveDocument.Info.CountByteDocument
ActiveDocument.Info.CountByteSelection

ActiveDocument.Info.SelectionStartLine
ActiveDocument.Info.SelectionStartColumn
ActiveDocument.Info.SelectionEndLine
ActiveDocument.Info.SelectionEndColumn

Yes, i have browse the heapi.chm, but i got lost somewhere.

As far as i  underst guess,
the last four infos i  should get by using
var ptStart, ptEnd;
ActiveView.GetSelection(ptStart, ptEnd);
???

But according your last post you have to modify it to smtg like:
var LineStart, LineEnd, ColumnStart, ColumnEnd;
ActiveView.GetSelection(LineStart, LineEnd, ColumnStart, ColumnEnd);
???

.

Offline alex

  • Developer
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2161
  • Karma: +37/-3
    • View Profile
    • HippoEDIT
Re: 1.50: scripting first test
« Reply #22 on: August 12, 2011, 01:32:11 pm »
Hi Stefan,

I have only provide you example function you can use.
To get selected text you need something like this:
Code: Javascript
  1. var ptStart, ptEnd;
  2. ActiveView.GetSelection(ptStart, ptEnd);
  3. var text = ActiveDocument.GetText(ptStart, ptEnd);

to replace selection:
Code: Javascript
  1. var ptStart, ptEnd;
  2. ActiveView.GetSelection(ptStart, ptEnd);
  3. ActiveDocument.ReplaceText(ptStart, "New Text", ptEnd, 0);

Quote
var LineStart, LineEnd, ColumnStart, ColumnEnd;
ActiveView.GetSelection(LineStart, LineEnd, ColumnStart, ColumnEnd);
Yes. In all places where before points were used.

HE will not provide all kinds of functions. Because this set will be unlimited and every user will want something different to simplify his life.
HE will only provide low level functions. But the user can create his own helper functions, wrapping HE functions and put them into include, for reuse. This is how it is designed. And the good thing that one can refer to js functions from js include in vb script for example. We can think about some generic include with such helper functions, that HE can pre-install. As example check include.js attached to post and used in scripting.hejs.


Offline Stefan

  • Administrator
  • Hero Member
  • *****
  • Posts: 775
  • Karma: +6/-0
    • View Profile
Re: 1.50: scripting first test
« Reply #23 on: August 26, 2011, 10:14:35 am »
Hi Alex, if you find some time please take an look:


I have only provide you example function you can use.
To get selected text you need something like this:

Alex> "Create a tool, taking script path into command window. It should work as normal tool, and called tool script."

When i execute this script via an tool at an document, HE jumps to the script and shows the red arrow:
ila_rendered

What did i wrong?

Offline alex

  • Developer
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2161
  • Karma: +37/-3
    • View Profile
    • HippoEDIT
Re: 1.50: scripting first test
« Reply #24 on: August 26, 2011, 01:25:28 pm »
Hi Stefan,

you did everything right. This is exactly the problem I have described before: var ptStart, and ptEnd should be structures of type POINT_T, but the problem is that scripting languages do not understand structures (but for plugins this was not a problem). So I was forced to updated signatures to use or expanded version with 4 variables for all positions (startline, startpos, endline, endpos) instead of two (pointStart, pointEnd), or as it will be to use objects instead of structures there. And this way will be published in new beta soon.

I have removed GetSelection method and instead provided object, that represents range, smt like this:
Code: Javascript
  1. var selection = ActiveView.Selection;
  2. selection.start.line
  3. selection.start.pos
  4. selection.Width
  5. selection.Height
  6. selection.Left
  7.  

There will be two new objects: Range and Position, which will be passed to and read from API. The only disadvantage, you need an extra call, if you like to create such object for passing it to API:
Code: Javascript
  1. var selection = CreateRange(nStartLine, nStartPos, nEndLine, nEndPos);
  2. var position1 = CreatePosition(nLine, nPos);
  3. position1.line = 2;
  4. position1.pos = 0;
  5. var position2 = CreatePosition(nLine2, nPos2);
  6. var range2 = CreateRangeEx(position1, position1);
  7.  

Will try to update alpha on Monday. BTW, the solution now is very similar that you have suggested with info object.
Another new thing which will come also with new update is WScript emulation: it will be possible to start scripts written for WSH inside of HE without any modification, because HE emulates WScript object by itself. Of course will be some limitations, but maybe I will cover them with time. Such approach with emulation will minimize jump-in time for people with experience in WScript.

BR, Alex

Offline Stefan

  • Administrator
  • Hero Member
  • *****
  • Posts: 775
  • Karma: +6/-0
    • View Profile
Re: 1.50: scripting first test
« Reply #25 on: September 01, 2011, 10:21:14 am »
Hi Alex, thanks for the update!

Are you ready for feedback... or it is to early to report malfunctions?



1.50.721  on XP SP3

1.)
Code: Javascript
  1. edit-2011-08-31.hejs
  2.  
  3. Got the yellow tool tip, but then
  4. "Schwerwiegender Fehler"
  5. ==> ActiveView.Select(sel);
  6.  
  7. or
  8.  
  9. Got the yellow tool tip,
  10. got output in output pane, but then
  11. "HE_ACTION_UNKNOWN is undefined"
  12. ==>ActiveDocument.ReplaceText(sel.start, "New Text", sel.end, HE_ACTION_UNKNOWN);

<EDIT
Alex> but excluding start/end of line
I had read/thought "start/end of FILE", sorry.
Now if i take your advice it works better.
But get still: "HE_ACTION_UNKNOWN is undefined"
</EDIT




2.)
Code: Javascript
  1. dialog_actions-2011-08-31.hejs
  2. "eMessageTypeInfo is undefined"
  3. ==>status("Result code: " + result, eMessageTypeInfo);



3.)
dialog_test-2011-08-31.hejs seams to work fine.


4.)
wscript_test.js
executing ends HE
« Last Edit: September 01, 2011, 10:38:18 am by Stefan »

Offline alex

  • Developer
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2161
  • Karma: +37/-3
    • View Profile
    • HippoEDIT
Re: 1.50: scripting first test
« Reply #26 on: September 01, 2011, 01:44:22 pm »
Hi Stefan,

main problem that you have not installed but only unpack binaries. Now installer also register type library and this step is missing, if you do not run it.
But generally you can achieve the same, if you will run Hippoedit.exe /Register  . This is a reason for "undefined" errors.

Problem with select comes because you call engine with invalid range. Maybe I will add some more meaningful error description in the future.
I have not add any error check in the example script, so if you decrease by one or increase by one selection range and goes out of line size of document size you will get it. For testing, just select some text in between of the line, before execution.

Crash with wscript_test.js I also reproduced.. Something strange, in debug was working. But I will fix it, should not be something serious. Just try the same, but with commented Quit (it cause the crash) to see the idea.
Added: It is very funny, but I am not able to reproduce this any more.. By me works. As release as debug. But probably there is something wrong...


You can also check updated dialog_actions.hejs for color_browser and font_browser.

BR, Alex.
« Last Edit: September 01, 2011, 02:18:08 pm by alex »

Offline Stefan

  • Administrator
  • Hero Member
  • *****
  • Posts: 775
  • Karma: +6/-0
    • View Profile
Re: 1.50: scripting first test
« Reply #27 on: September 01, 2011, 02:38:36 pm »
Hi Stefan,

main problem that you have not installed but only unpack binaries. Now installer also register type library and this step is missing, if you do not run it.
But generally you can achieve the same, if you will run Hippoedit.exe /Register  . This is a reason for "undefined" errors.

Ah, i see.
I do install 1.50 builds, but i work with limited user rights, of course ;-)
<edit to clarify> i have installed to X:\, where i have write access. (To "C:\Pro Fi" i wouldn't) - But i had still no write access to HKLM. </edit>
Anyway. runas /u:administrator "Hippoedit.exe /Register" did it. Much better now.


Quote
Problem with select comes because you call engine with invalid range. Maybe I will add some more meaningful error description in the future.
I have not add any error check in the example script, so if you decrease by one or increase by one selection range and goes out of line size of document size you will get it. For testing, just select some text in between of the line, before execution.
Yes you are right. Works.

Quote
Crash with wscript_test.js I also reproduced.. Something strange, in debug was working. But I will fix it, should not be something serious. Just try the same, but with commented Quit (it cause the crash) to see the idea.
Added: It is very funny, but I am not able to reproduce this any more.. By me works. As release as debug. But probably there is something wrong...
//WScript.Quit();
But still the same here. (as limited user)
But no matter for me. I have other things to check out.
<edit> Not related to limited user, the same with runas /u:Admin HE </edit>


Quote
You can also check updated dialog_actions.hejs for color_browser and font_browser.
Yes, have seen and used. Now i need to use that choice to do smtg. e.g.  alert me the choice taken...
I also have seen things like "ActiveDocument.BeginUndoGroup();", ... you have did much work for that 1.5 build it seams...


Now I going to see if I can take an selection, modify it and write back,... i think i had seen smtg in your example code to reuse...
« Last Edit: September 01, 2011, 02:44:47 pm by Stefan »

Offline alex

  • Developer
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2161
  • Karma: +37/-3
    • View Profile
    • HippoEDIT
Remove Empty Lines
« Reply #28 on: September 11, 2011, 04:23:33 am »
This is and example of first useful script which deletes empty lines from whole document or selection.
Script can be added as tool (select remove_empty_lines.hejs).


edit_helpers.hejs
Code: Javascript
  1. ////////////////////////////////////////////////////////////////////////
  2. // Helper function to check, if text contains only white space
  3. // characters or empty
  4. // sText - string to be checked
  5. // result - true, if text, contains only white space
  6. function isWhiteText(sText)
  7. {
  8.         var bWhiteSpace = true;
  9.         for (var i = 0; i < sText.length && bWhiteSpace; ++i)
  10.         {
  11.                 var c = sText.charAt(i);
  12.                 bWhiteSpace = c == " " || c == "\t";
  13.         }
  14.         return bWhiteSpace;
  15. }
  16.  
  17. ////////////////////////////////////////////////////////////////////////
  18. // Helper function to check if line contain only white space
  19. // doc    - document object
  20. // nLine  - line index to be checked
  21. // result - true, if line, contains only white space
  22. function isEmptyLine(doc, nLine)
  23. {
  24.         return isWhiteText(doc.GetLine(nLine));
  25. }
  26.  
  27. ////////////////////////////////////////////////////////////////////////
  28. // Often, selection ends up in 0 char of next line,
  29. // when we want to work only with lines above
  30. // but algorithms do not know that, so we help them by
  31. // correcting bottom bound of the range
  32. // doc            - document object
  33. // selRange   - range to be adjusted
  34. function AdjustSelection(doc, selRange)
  35. {
  36.         if ( selRange.Height > 0 && selRange.Right == 0)
  37.                 doc.MovePositionLine(selRange.end, -1);
  38.  
  39.         return selRange;
  40. }
  41.  

remove_empty_lines.hejs
Code: Javascript
  1. #include "edit_helpers.hejs"    // generic he edit helper functions
  2.  
  3. // if there is no active view, exit
  4. if ( ActiveView != null )
  5. {
  6.         // first get current selection
  7.         var sel = ActiveView.Selection;
  8.  
  9.         // if nothing is selected, let us assume, that whole document should be processed
  10.         if ( sel.IsEmpty )
  11.         {
  12.                 sel.Top          = 0;
  13.                 sel.Bottom   = ActiveDocument.LineCount - 1;
  14.         }
  15.         else
  16.         {
  17.                 AdjustSelection(ActiveDocument, sel);
  18.         }
  19.  
  20.         var nUndoActionType = AddUndoActionType("Remove Empty Lines");
  21.  
  22.         // start UndoGroup to be able to Undo all at once
  23.         ActiveDocument.BeginUndoGroup();  
  24.  
  25.         var nDeleted = 0;  
  26.         var nLineStart = sel.Top, nLineEnd = sel.Bottom;  
  27.         for (i = nLineStart; i <= nLineEnd;)
  28.         {
  29.                 if ( isEmptyLine(ActiveDocument, i) )
  30.                 {
  31.                         var rgDelete = CreateRange(i, 0, i + 1, 0);
  32.                         if ( i == ActiveDocument.LineCount - 1 )
  33.                         {
  34.                                 ActiveDocument.MovePositionLine(rgDelete.start, -1);
  35.                                 rgDelete.end = rgDelete.start;
  36.                                 ActiveDocument.MovePositionLine(rgDelete.end, 1);
  37.                         }
  38.  
  39.                         if ( !rgDelete.IsEmpty )
  40.                         {
  41.                                 ActiveDocument.DeleteText(rgDelete, nUndoActionType);
  42.                                 ++nDeleted;
  43.                         }
  44.                         --nLineEnd;
  45.                 }
  46.                 else
  47.                 {
  48.                         ++i;
  49.                 }
  50.         }
  51.  
  52.         ActiveDocument.FlushUndoGroup();
  53.  
  54.         status(nDeleted + " empty lines have been deleted", eMessageTypeInfo);
  55. }
  56. else
  57. {
  58.         status("There is no document selected", eMessageTypeError);
  59. }
  60.  

 

Related Topics

  Subject / Started by Replies Last post
18 Replies
7881 Views
Last post June 17, 2016, 11:09:59 pm
by alex
2 Replies
4568 Views
Last post October 07, 2009, 01:50:53 pm
by alex
8 Replies
5269 Views
Last post November 18, 2009, 03:35:00 am
by samuel1991
3 Replies
2303 Views
Last post November 30, 2011, 12:20:59 am
by alex
2 Replies
1842 Views
Last post July 07, 2013, 03:09:16 pm
by RJP74