Default/Portable installation StdLib

Propose new features and changes
Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Default/Portable installation StdLib

Post by Coco » 14 Nov 2015, 23:58

Not really sure if this should be a poll or not, I(or a mod/admin) can change it later on if necessary. I would like to make a suggestion on including some core lib scripts w/ the basic AHK installation and ZIP download. By "core", particularly a function version of all AHK commands(only those retained in v2) and of course naming(and syntax) should follow that of v2(e.g.: FileSelectFile becomes FileSelect and so on..). Some pros and cons:
PROS:
  • Addresses some limitations/quirks. Like passing/forcing expressions etc. (e.g.: SetTimer(Func("foo").Bind(args*), -1))
  • Scripts written onwards should be easier to port to v2
  • Easier transition to v2
  • I know there are still others
CONS:
  • Bloat, Installation size - they're just text files so this shouldn't be that big of an issue
  • Portability - compiler addresses this or if compiling is not an option, it's easy to write a "release" script or a script consolidator
  • Who'll perform the command-to-function port? - I'm willing to do this
What do you think?

Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: Default/Portable installation StdLib

Post by Coco » 06 Mar 2016, 12:13

I decided to work on this - Github repo

Edit: (I'm including the Notes, limitations and todos here for reference)
Notes, limitations, todo:
  • ListVars() can only list global variables.
  • FileInstall() will only perform a FileCopy.
  • Gui("Add", ...) - the control's associated variable must be global. Declaring as static is currently impossible.
  • GuiControl() and GuiControlGet() can only operate on global variables(control's associated variable). Use ControlHwnd or ClassNN instead if needed.
  • Fix WinSetXXX() return values. In v2.0-a, ErrorLevel is returned. However, most of WinSet sub-commands in v1.1 do not use ErrorLevel. Perhaps ErrorLevel can be determined using A_LastError.
  • In v2, Func("MenuSelect").MinParams returns 0. However when called using command syntax, an error is thrown when a required parameter is omitted. There are probably other commands/functions that behave like this. Best to check using Func object properties.
  • Random() limitation -> how to mimic Random,, NewSeed?
Last edited by Coco on 07 Mar 2016, 12:11, edited 1 time in total.

lexikos
Posts: 9559
Joined: 30 Sep 2013, 04:07
Contact:

Re: Default/Portable installation StdLib

Post by lexikos » 06 Mar 2016, 20:34

Where would you prefer to discuss your script/the limitations/todos listed at GitHub? In GitHub Issues, here or in another topic?

Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: Default/Portable installation StdLib

Post by Coco » 07 Mar 2016, 12:00

lexikos wrote:Where would you prefer to discuss your script/the limitations/todos listed at GitHub? In GitHub Issues, here or in another topic?
For visibility, so that others(including non-GitHub users) can chime in, I guess the forum is the best place. I'm not so sure if we should continue it here on this topic or split it up though... I've included the limitations/todos in my previous post, we can split it up from there if we decide to split this into a new topic.

lexikos
Posts: 9559
Joined: 30 Sep 2013, 04:07
Contact:

Re: Default/Portable installation StdLib

Post by lexikos » 07 Mar 2016, 19:10

Fix WinSetXXX() return values. In v2.0-a, ErrorLevel is returned. However, most of WinSet sub-commands in v1.1 do not use ErrorLevel. Perhaps ErrorLevel can be determined using A_LastError.
WinSet doesn't update A_LastError. For the sub-commands which don't set ErrorLevel, I think it would be sufficient to consider it a success if the window exists. For efficiency, you could use WinExist() first and pass ahk_id to WinSet.
FileInstall() will only perform a FileCopy.
Whether for v2 or for this script, Ahk2Exe will need to be extended to parse expressions like FileInstall("Some\Path.ext", ...) if that syntax will be supported. If that was done, this script could use the Win32 resource API to extract the file data.

An alternative would be to have a more general function for extracting resources, and require the script to use the "upcoming" resource directives, but I suppose then you'd need to repeat the resource name/path.

lexikos
Posts: 9559
Joined: 30 Sep 2013, 04:07
Contact:

Re: Default/Portable installation StdLib

Post by lexikos » 07 Mar 2016, 20:59

In v2, Func("MenuSelect").MinParams returns 0. However when called using command syntax, an error is thrown when a required parameter is omitted.
MinParams is 0 because WinTitle and WinText can be omitted, as in MenuSelect(,, "File", "Open"), which operates on the Last Found Window. That you can't omit the third parameter is only one of many requirements that are enforced at load time for specific commands, but not for the corresponding function (including MenuSelect()). Some checks are only done at load time, and only for args which are not variables/expressions.

For commands, only optional parameters can be completely blank; to pass an empty value to a mandatory parameter, you have to use a variable or expression.
Random() limitation -> how to mimic Random,, NewSeed?
Similarly, Input OutputVar starts collecting input with default options, while Input just cancels a previous call to the Input command (or does nothing).

lexikos
Posts: 9559
Joined: 30 Sep 2013, 04:07
Contact:

Re: Default/Portable installation StdLib

Post by lexikos » 08 Mar 2016, 01:48

InputBox in v2 validates its options. There's probably not much need to duplicate the behaviour to that extent, but in this case we can simplify (or at least shorten ;)) your code and gain validation at the same time. Instead of a parsing loop, we can use a single regex:

Code: Select all

Options := "x0 y0 w100 h100 T10.0 Password*"
Valid := RegExMatch(Options, "i)^\s*(?:(?:X(?<X>\S*)|Y(?<Y>\S*)|W(?<W>\S*)|H(?<H>\S*)|T(?<T>\S*)|(?<P>Password\S?))\s*)*$", _)
ListVars
Pause
I think this is consistent with what v2-alpha accepts. Of course, InputBox in v1 still doesn't support Password* and you would need to use % _P ? "HIDE" : "" for the HIDE parameter.

Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: Default/Portable installation StdLib

Post by Coco » 09 Mar 2016, 12:09

lexikos wrote:WinSet doesn't update A_LastError. For the sub-commands which don't set ErrorLevel, I think it would be sufficient to consider it a success if the window exists. For efficiency, you could use WinExist() first and pass ahk_id to WinSet.
I see. Regarding WinExist(), I guess I would need to store the current "LastFound window" first then restore it back before returning. Otherwise the function might interfere with the user's script functionality, in rare cases. Another thing, which is more efficient, passing ahk_id %Hwnd% or omitting all the window parameters to take advantage of the "LastFound window" feature? The docs says that the script performs better with the latter..
lexikos wrote:Whether for v2 or for this script, Ahk2Exe will need to be extended to parse expressions like FileInstall("Some\Path.ext", ...) if that syntax will be supported. If that was done, this script could use the Win32 resource API to extract the file data.

An alternative would be to have a more general function for extracting resources, and require the script to use the "upcoming" resource directives, but I suppose then you'd need to repeat the resource name/path.
I see. For now I'll just retain the FileCopy behavior and wait for Ahk2Exe's progress.
lexikos wrote:MinParams is 0 because WinTitle and WinText can be omitted, as in MenuSelect(,, "File", "Open"), which operates on the Last Found Window. That you can't omit the third parameter is only one of many requirements that are enforced at load time for specific commands, but not for the corresponding function (including MenuSelect()). Some checks are only done at load time, and only for args which are not variables/expressions.
Thanks for the confirmation. I'd have to review some of the functions. I think I might have overlooked some aside from MenuSelect().
lexikos wrote:InputBox in v2 validates its options. There's probably not much need to duplicate the behaviour to that extent, but in this case we can simplify (or at least shorten ;)) your code and gain validation at the same time. Instead of a parsing loop, we can use a single regex:

Code: Select all

Options := "x0 y0 w100 h100 T10.0 Password*"
Valid := RegExMatch(Options, "i)^\s*(?:(?:X(?<X>\S*)|Y(?<Y>\S*)|W(?<W>\S*)|H(?<H>\S*)|T(?<T>\S*)|(?<P>Password\S?))\s*)*$", _)
ListVars
Pause
I think this is consistent with what v2-alpha accepts. Of course, InputBox in v1 still doesn't support Password* and you would need to use % _P ? "HIDE" : "" for the HIDE parameter.
Thanks, applied your suggestion in this commit. I modified your pattern a little bit to clone v2's strict validation. Added error handling as well for invalid options.

lexikos
Posts: 9559
Joined: 30 Sep 2013, 04:07
Contact:

Re: Default/Portable installation StdLib

Post by lexikos » 09 Mar 2016, 16:22

I hadn't considered the Last Found Window. Yes, using it is marginally faster. Either way should be somewhat faster than using the title, which requires enumerating windows, retrieving and comparing the title of each window. But saving and restoring it might make it slower overall. You can avoid that by using WinGet ID.

If you want to know which commands have MinParams = 0, just look in g_act in globaldata.cpp. There are some comments explaining it for some commands.

If you add the pattern (?<Err>\S+)(*ACCEPT) into the regex, it can capture the first invalid option (by causing matching to immediately succeed without further processing).

Code: Select all

Options := "x0 y0 w100 first h100 T10.0 Password* second"
RegExMatch(Options, "i)^\s*(?:(?:X(?<X>-?\d+)|Y(?<Y>-?\d+)|W(?<W>\d+)"
    . "|H(?<H>\d+)|T(?<T>\d+(?:\.\d+)?)|(?<P>Password\S?)"
    . "|(?<Err>\S+)(*ACCEPT)"
    . ")\s*)*$", _)
ListVars
Pause
It would probably be more correct to use [ `t]* in place of \s.

Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: Default/Portable installation StdLib

Post by Coco » 10 Mar 2016, 10:48

lexikos wrote:I hadn't considered the Last Found Window. Yes, using it is marginally faster. Either way should be somewhat faster than using the title, which requires enumerating windows, retrieving and comparing the title of each window. But saving and restoring it might make it slower overall. You can avoid that by using WinGet ID.
Thanks. I'll go with WinGet ID, saving/restoring the Last Found Window would require several calls to WinExist(). Offtopic, reminds me of a previous wish I had about context managers -> something like using Hwnd := WinExist(...) { } would be a handy feature in similar cases, allowing AHK to restore the original Last Found Window automatically after the block.
lexikos wrote:If you want to know which commands have MinParams = 0, just look in g_act in globaldata.cpp. There are some comments explaining it for some commands.
Nice, thanks, makes it easier :)
lexikos wrote:If you add the pattern (?<Err>\S+)(*ACCEPT) into the regex, it can capture the first invalid option (by causing matching to immediately succeed without further processing).

Code: Select all

Options := "x0 y0 w100 first h100 T10.0 Password* second"
RegExMatch(Options, "i)^\s*(?:(?:X(?<X>-?\d+)|Y(?<Y>-?\d+)|W(?<W>\d+)"
    . "|H(?<H>\d+)|T(?<T>\d+(?:\.\d+)?)|(?<P>Password\S?)"
    . "|(?<Err>\S+)(*ACCEPT)"
    . ")\s*)*$", _)
ListVars
Pause
It would probably be more correct to use [ `t]* in place of \s.
Thanks again, I modified the pattern to to ensure that option(s) are either followed by space(s)/tab(s) or end-of-string($). The \s*/[ \t]*(being 0 or more) in the subpattern allows something like "x0y0w400t2.0" which should be invalid:

Code: Select all

RegExMatch(Options, "i)^[ \t]*(?:(?:X(?<X>-?\d+)|Y(?<Y>-?\d+)|W(?<W>\d+)"
    . "|H(?<H>\d+)|T(?<T>\d+(?:\.\d+)?)|(?<P>Password\S?)"
    . "|(?<Err>\S+)(*ACCEPT)"
    . ")(?=[ \t]|$)[ \t]*)*$", _) ; look-ahead ensures that each option is either followed by space(s)/tab(s) or end-of-string

lexikos
Posts: 9559
Joined: 30 Sep 2013, 04:07
Contact:

Re: Default/Portable installation StdLib

Post by lexikos » 11 Mar 2016, 00:56

Re FileInstall: HotKeyIt has updated his Ahk2Exe for v2 to support the function syntax.

Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: Default/Portable installation StdLib

Post by Coco » 13 Mar 2016, 03:42

lexikos wrote:I think it would be sufficient to consider it a success if the window exists
I've applied the updates for WinSetXXX().
lexikos wrote:Re FileInstall: HotKeyIt has updated his Ahk2Exe for v2 to support the function syntax.
Thanks, I'll look into FileInstall().

Btw, in v2, how to do a Random,, NewSeed when using function syntax? Random("", NewSeed)? Random(NewSeed, "")? Or is it only supported when using command syntax?

lexikos
Posts: 9559
Joined: 30 Sep 2013, 04:07
Contact:

Re: Default/Portable installation StdLib

Post by lexikos » 13 Mar 2016, 04:27

There is no way to "omit" the OutputVar when using the function syntax, so it is not supported. It is the same for Input.

My thought is that the syntax of these commands needs to be changed, but I don't know how exactly.

Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

Re: Default/Portable installation StdLib

Post by Coco » 13 Mar 2016, 07:13

lexikos wrote:There is no way to "omit" the OutputVar when using the function syntax, so it is not supported. It is the same for Input.
I see, I need to fix Input()
lexikos wrote:My thought is that the syntax of these commands needs to be changed, but I don't know how exactly.
How about:
Input:
InputWait, OutputVar [, Options, EndKeys, MatchList ] / OutputVar := InputWait( [, Options, EndKeys, MatchList ] )
InputCancel / InputCancel() OR InputStop / InputStop()

Random:
Based on C# Random Class
Random, Seed / Random( Seed )
RandomNext, OutputVar [, Min, Max ] / OutputVar := RandomNext( [, Min, Max ] )
OR
RandomNum, OutputVar [, Min, Max ] / OutputVar := RandomNum( [, Min, Max ] )

I kinda like InputWait as it really tells what the command does...

lexikos
Posts: 9559
Joined: 30 Sep 2013, 04:07
Contact:

Re: Default/Portable installation StdLib

Post by lexikos » 02 Dec 2022, 21:40

With the syntax of v2 now being stable, I would be amenable to the inclusion of a v1 standard library that replicates the syntax and behaviour of the v2 functions where possible, if there is anyone willing to develop and maintain it. I do not have sufficient interest to develop it myself in script or in C++.

iseahound
Posts: 1434
Joined: 13 Aug 2016, 21:04
Contact:

Re: Default/Portable installation StdLib

Post by iseahound » 05 Dec 2022, 00:08

Are you referring to something like this? https://github.com/cocobelgica/AutoHotkey-Future/tree/master/Lib
I also seem to remember a library by titan / polyethylene

lexikos
Posts: 9559
Joined: 30 Sep 2013, 04:07
Contact:

Re: Default/Portable installation StdLib

Post by lexikos » 05 Dec 2022, 02:22

That is Coco's attempt at implementing it, as described in the second post of this topic.
I wrote:if there is anyone willing to develop and maintain it.
The ancient library by Titan just wraps the v1 commands as functions.
I wrote:a v1 standard library that replicates the syntax and behaviour of the v2 functions
Is there some part of my description that needs clarification?

Post Reply

Return to “Wish List”