Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

AutoHotkey v2 Alpha Release


  • Please log in to reply
870 replies to this topic
  • Guests
  • Last active:
  • Joined: --

[*:2fjagsz4]Loop File, FilePattern - may be confused with Loop Read?
[*:2fjagsz4]Loop Files, FilePattern

How about:
Loop Folder, [i]FilePattern[/i]


Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
v2.0-a025-0e3ca95:
[*:6ltpk5io]Added capability to call functions using traditional command syntax, with some limitations.
[*:6ltpk5io]Added capability to call commands using function() syntax.
[*:6ltpk5io]Fixed 'var x' in global scope.
[*:6ltpk5io]Fixed: ErrorLevel not initialized when a new thread starts.
[*:6ltpk5io]Fixed: Contents of ErrorLevel not freed when the thread ends.
[*:6ltpk5io]Added Files, Reg, Read and Parse as sub-commands of Loop.
[*:6ltpk5io]Combined RootKey and SubKey params of LoopReg and Reg commands.
[*:6ltpk5io]Combined IncludeFolders/Subkeys? and Recurse? params to aid memorization.
[*:6ltpk5io]Changed For-loop to localize its variables.
[*:6ltpk5io]Renamed Asc() to Ord() -- it's not ASCII anymore.
[*:6ltpk5io]Updated Ord() and Chr() to support supplementary characters.
[*:6ltpk5io]Replaced the final parameter of StrReplace with OutputVarCount and Limit, similar to RegExReplace.
[*:6ltpk5io]Changed InputBox to use a flex-list of options similar to Gui Show etc.
[*:6ltpk5io]Merged v1.1.05.00.Command()
All commands can now be called as functions, except for control flow statements such as Return and Exit. ExitApp is also excluded, for consistency. Currently commands and functions are still separate, but commands are automatically wrapped on first use as a function (if no function with the same name exists). The translation rules are:
[*:6ltpk5io]If the command's first parameter is an output variable and the second parameter is not, it becomes the return value. Otherwise, any value which the command stores in ErrorLevel is returned and ErrorLevel itself is restored to its former value.
[*:6ltpk5io]The remaining output variables are handled like ByRef parameters, except that an exception is thrown if the function is called incorrectly. Passing an empty string is equivalent to omitting the parameter, but any other value (which is not a variable reference) is not allowed.
[*:6ltpk5io]Commands which normally accept an input variable do not require a variable reference; an internal temporary variable is used automatically.
[*:6ltpk5io]If a runtime error occurs, an exception is always thrown even if try is not used.Although it's basically one big hack, it seems to work very well. Unfortunately the converse functionality isn't quite as complete:

Function, Args
All functions can now be called as commands, including library functions which haven't been manually #included. The translation rules are currently:
[*:6ltpk5io]The return value is always discarded.
Update: In alpha 26 and later, an output variable is inserted at the beginning of the parameter list if the function is built-in or contains a "return".
[*:6ltpk5io]All parameters support % for forcing an expression, and are not expressions by default.
[*:6ltpk5io]ByRef parameters are treated like input variables. Expressions such as % var := "value" aren't fully supported (the variable reference is not passed to the function). However, % var is okay due to an optimization which converts it to a non-expression.
[*:6ltpk5io]All other parameters default to normal text mode. This includes all parameters of built-in functions, so to pass a variable reference, you must write % var or %var% (but again, % var := "value" will only pass the value).
[*:6ltpk5io]The args are parsed before the function name can be resolved (and the number of parameters determined), so literal commas must always be escaped, even in the function's final parameter.Most of the built-in functions probably need an output variable to be useful and virtually all of them return something useful, if not necessary. However, if the output variable is always present, command syntax is less appealing for user-defined functions which have no return value. For example, AlertBox,, Text isn't very nice, especially if, like me, you prefer to omit the initial comma.

Registry Commands
I believe it is more convenient and intuitive for the root key and subkey to be specified together than as two separate parameters. Instead of RootKey, Key, write RootKey\Key. To connect to a remote registry, use \\ComputerName\RootKey\Key instead of \\ComputerName:RootKey, Key.

Loop Sub-commands
Loop Files, FilePattern [, Mode]
Loop Reg, RootKey\Key [, Mode]
Loop Read, InputFile [, OutputFile]
Loop Parse, InputVar [, Delimiters, OmitChars]

Mode supersedes the old IncludeSubkeys?/IncludeFolders? and Recurse? parameters. Its meaning is more obvious when reading the source code and it should be easier to remember. Instead of a number, it is a case-insensitive string of characters separated by optional spaces or tabs, in any order:
[*:6ltpk5io]F (file) or V (value): include files or registry values.
[*:6ltpk5io]D (directory) or K (key): include directories or registry keys.
[*:6ltpk5io]R (recurse): recurse into subdirectories or subkeys.For example, Loop Files, *, FDR recursively loops through all files and folders in the working directory.

Currently the compact form (LoopFiles, LoopReg, LoopRead and LoopParse) is still supported since it doesn't require any extra code. This may or may not be removed, depending on community feedback.

StrReplace
StrReplace, OutputVar, InputVar, SearchText [, ReplaceText, OutputVarCount, Limit]

Usage is now almost the same as RegExReplace (when function syntax is used). If Limit is omitted, the default is unlimited. ErrorLevel can be used as the OutputVarCount; otherwise ErrorLevel is not affected. These changes were very simple because it was apparently already designed to support a variable limit. I opted not to implement a StartingPosition parameter since it wasn't as simple, and it can be added later without causing problems. I'm not sure how useful it would be, anyway.

InputBox
InputBox, OutputVar [, Title, Prompt, Options, Default]

That's quite a few less parameters to memorize. The Options parameter accepts a string of zero or more case-insensitive options delimited by a space or tab, similar to Gui control options. For example, this includes all supported options: x0 y0 w100 h100 T10.0 Password*. T is timeout and Password has the same usage as the equivalent Edit control option.

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
Great work and an awesome release, thank you very much ;)

maul.esel
  • Members
  • 790 posts
  • Last active: Jan 05 2013 09:26 PM
  • Joined: 28 Feb 2011
Yeah thanks :) Especially that thing on InputBox is very useful.

Is LoopParse, ... now equivalent to Loop, Parse, ...? And will both of them stay :?:
Join the discussion on The future of AutoHotkey
Posted Image Visit me on github Posted Image
Win7 HP SP1 64bit | AHK_L U 64bit

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
Great changes! I would vote to remove the LoopParse,LoopReg,.. syntax for a clearer language definition, but I don't feel very strong about it.

maul.esel
  • Members
  • 790 posts
  • Last active: Jan 05 2013 09:26 PM
  • Joined: 28 Feb 2011
Yeah, one of them could be removed. I liked LoopReg, LoopParse more, but I really don't care a lot ;-)
Join the discussion on The future of AutoHotkey
Posted Image Visit me on github Posted Image
Win7 HP SP1 64bit | AHK_L U 64bit

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
While thinking about this I thought it would be nice if someone wrote libraries for accessing the file system and registry through objects.

Frankie
  • Members
  • 2930 posts
  • Last active: Feb 05 2015 02:49 PM
  • Joined: 02 Nov 2008
Wow! This includes so many changes that have been discussed on the last forty or so pages, and countless Wish List threads. If this isn't progress: I don't know what is.

Thanks for the great work!
aboutscriptappsscripts
Request Video Tutorials Here or View Current Tutorials on YouTube
Any code ⇈ above ⇈ requires AutoHotkey_L to run

fincs
  • Moderators
  • 1662 posts
  • Last active:
  • Joined: 05 May 2007

[*:22306i84]Added capability to call functions using traditional command syntax, with some limitations.
[*:22306i84]Added capability to call commands using function() syntax.

:shock:

I never thought support for it was coming so fast!

I suppose it should now be possible to create a fully AHK v1-compatible scripted Progress/SplashImage/SplashText replacement to be distributed in the standard library.

EDIT:
SplashTextOn, 100, 100, Title, Text...`nWhat is it?`nIs it cake?`nIs it pie?
Sleep, 1000
SplashTextOff

SplashTextOff()
{
	global __SplashTextHWND
	if __SplashTextHWND, Gui %__SplashTextHWND%:Destroy
	__SplashTextHWND := ""
}

SplashTextOn(Width := 200, Height := 0, Title := "", Text := "")
{
	global __SplashTextHWND
	if __SplashTextHWND, Gui %__SplashTextHWND%:Destroy
	Gui, New, +Hwnd__SplashTextHWND +Owner%A_ScriptHwnd% -SysMenu -MinimizeBox +AlwaysOnTop +Disabled, % Title
	Gui, Font, s10 w0, % FontExist("Segoe UI") ? "Segoe UI" : ""
	Gui, Add, Text, x0 h0 w%Width% h%Height% +Center, % Text
	Gui, Show, w%Width% h%Height%
}

FontExist(fontname)
{
	static cb := RegisterCallback("_FontExistCb")
	VarSetCapacity(LOGFONT, 92, 0)
	NumPut(1, LOGFONT, 27, "UChar")
	StrPut(fontname, &LOGFONT + 28, 32)
	DllCall("EnumFontFamiliesEx", "ptr", DllCall("GetDC", "ptr", 0, "ptr"), "ptr", &LOGFONT, "ptr", cb, "int*", fontExists, "uint", 0)
	return fontExists
}

_FontExistCb(lpelfe, lpntme, FontType, lParam)
{
	NumPut(1, lParam, "Int")
	return 0
}

EDIT2: Turns out it wouldn't be fully compatible, parameters "that can be expressions" aren't supported in function command calls :(

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

Turns out it wouldn't be fully compatible, parameters "that can be expressions" aren't supported in function command calls :(

There isn't any way to indicate that a parameter should be an expression. It could be based on the parameter's default value, but that doesn't seem ideal.

On the other hand, some users find it difficult to remember which parameters are expressions, which are text and which are variables. It may be convenient for numeric parameters to be automatically expression-capable, but it's not very beginner-friendly. What are your views on requiring % for expressions?

On a related note, I've been considering whether args which are input vars should become expressions or normal text args. Currently the list of commands which use input vars in v2 is fairly short, and all of them expect strings:

Loop Parse
SplitPath
StrLower
StrUpper
StrReplace

Sort - it's first arg is marked as an input variable, but is also used for output. There probably isn't any good reason not to split it into input/output as with other commands, which would make the function usage out := Sort(in) rather than Sort(in_out).

Note that changing them to use normal text args would also allow % to force an expression.

Another problem with the current function-as-command functionality is the lack of an output variable for the return value. Your SplashText example shouldn't have one, but most built-in functions and some user-defined functions should. How do we determine whether a given function-command should or shouldn't have an output var? For user-defined functions it could be based on the presence of return somevalue, but it might be too obscure, and there might be some cases where the return value isn't important (and should be omitted with the command style).

Frankie
  • Members
  • 2930 posts
  • Last active: Feb 05 2015 02:49 PM
  • Joined: 02 Nov 2008

Another problem with the current function-as-command functionality is the lack of an output variable for the return value. Your SplashText example shouldn't have one, but most built-in functions and some user-defined functions should. How do we determine whether a given function-command should or shouldn't have an output var? For user-defined functions it could be based on the presence of return somevalue, but it might be too obscure, and there might be some cases where the return value isn't important (and should be omitted with the command style).

I think the importance of by reference parameters will be increased with this, but for return values they can be seen with a built-in-variable. I don't have any ideas on the name, but an example could be "A_LastReturn". Output of commands, almost necessarily, takes additional lines to handle; I don't think an explicit output variable for the return is a good idea.

The difference between command usage and function usage is quite large. Functions are often used when the output is to be used right away, e.g., math will be done on the result and stored in a variable, thus eliminating a line of code. Commands are often strung together in a set of lines where the output variable of one becomes the input of another; in this case we like to set a different output variable from input, so byref is preferred as opposed to something rewritten with the next command. From this perspective adding an explicit output parameter seems to make sense, and it can be skipped by the usual double comma ("command,, p2").

As you can tell: I don't have a strong opinion on the subject as neither of the above approaches are elegant. What other solutions could there be?
aboutscriptappsscripts
Request Video Tutorials Here or View Current Tutorials on YouTube
Any code ⇈ above ⇈ requires AutoHotkey_L to run

guest3456
  • Members
  • 1704 posts
  • Last active: Nov 19 2015 11:58 AM
  • Joined: 10 Mar 2011
calling commands as functions, ie Command() is far more useful and intuitive imo than calling a funciton as a command. i reckon that the second shouldn't even be supported, moving everything to a function standard and simplifying everyones life (including Lexikos') :)

re: super globals, confirm i've got this right:

myvar := 1                ;// global
global myvar2 := 2       ;// super-global
return

myfunc() {
   msgbox, %myvar%   ;// uninitialized local
   msgbox, %myvar2%   ;// displays "2"
}


Crash&Burn
  • Members
  • 228 posts
  • Last active: Jul 16 2014 10:10 PM
  • Joined: 02 Aug 2009

Loop Sub-commands
Loop Files, FilePattern [, Mode]
Loop Reg, RootKey\Key [, Mode]
Loop Read, InputFile [, OutputFile]
Loop Parse, InputVar [, Delimiters, OmitChars]

Why not break from the Loop idiom?

A few things that come to mind:
(1) Possible "Loop Files"[*:2q910cg6]FindFile(s), FilePattern [, Mode]
[*:2q910cg6]FileSeek, FilePattern [, Mode]
[*:2q910cg6]Find, FilePattern [, Mode]
[*:2q910cg6]Dir, FilePattern [, Mode](2) RegSeek, RootKey\Key [, Mode]
(3) ParseFile, inputFile [, OutputFile]
(4) ParseVar, inputVar [, Delims, OmitChars ]

In fact, it makes me wonder at the possibility of using regex right in the command itself ?
e.g. FindFiles, /FOO.*\.(txt|bak)$/

I also notice there's almost an overlap in LoopReg and "RegRead".

If nothing else, I'd vote for LoopITEM instead of Loop, ITEM - it's cleaner. And my suggestion above, in possibly renaming some of them makes it easier at a glance to discern what the code is supposed to be doing.


I also agree with guest3456, It isn't important at all to enable calling "user-functions()" as commands. In fact I believe the whole idea runs contrary to some of AHK 2.0 stated goals to simplify and get rid of AHK's awkward syntax and inconsistencies (in places). Being able to call all functions as commands is not something anyone that writes a function (I think?) would even want.

maul.esel
  • Members
  • 790 posts
  • Last active: Jan 05 2013 09:26 PM
  • Joined: 28 Feb 2011
If removing those, I would suggest to replace them by functions that return an array, so that you can do
for file in FindFiles("*.txt")

    MsgBox % file
But I wouldn't remove them at all :)
Join the discussion on The future of AutoHotkey
Posted Image Visit me on github Posted Image
Win7 HP SP1 64bit | AHK_L U 64bit

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009

If removing those, I would suggest to replace them by functions that return an array, so that you can do

for file in FindFiles("*.txt")

    MsgBox % file
But I wouldn't remove them at all :)

+1