LuaFy – a free Lua scripting plug-in for FileMaker Pro®

FileMaker Functions Provided by LuaFy

LuaFy_ResumeFunction() LuaFy Plus
Download and Feature List
Purchase a License to LuaFy Plus
Functions Provided by LuaFy
Lua Libraries Provided by LuaFy
Lua Integration with FileMaker
Usage Examples
What is Lua?
Origin Story
Version History & Old Versions

All LuaFy functions are registered with the FileMaker API as being able to be run on FileMaker Server in addition to FileMaker Pro. The functions are available in all FileMaker calculation dialogs.

LuaFy_Version ( {versionFormat} )

Gives version information about LuaFy. The amount of information it returns depends on the (optional) argument you provide.

no argument, "", or "short"only version number, e.g. "1.0"
"long"name and version, e.g. "LuaFy 1.0"
"longer"name, version, and authorship info

LuaFy_Version( "LuaFy Plus"; UserIDString1; UserIDString2; LicenseCode )

This input mode of LuaFy_Version() is used to enter your license for LuaFy Plus. The exact text you need to enter for each argument will be provided when you purchase a license to LuaFy Plus.

LuaFy_RunScript ( luaScriptText {; arg...} )

luaScriptText is a string of text containing all of the Lua code you want to execute.

Example: LuaFy_RunScript( " return 'Hello world!' ")
Result: Hello world!

Example: LuaFy_RunScript("local x,y,z = ...;return x + y + z"; 1; 2; 3)
Result: 6

Pass values to LuaFy: You can pass an unlimited number of FileMaker values to Lua as additional arguments to this function. All FileMaker data types except Containers can be passed as arguments. These passed argument values are accessible using Lua's standard vararg mechanism "...", e.g. "x, y, z = ..." will put the first three arguments you pass into the Lua variables x, y, and z. FileMaker Text and Numbers are passed as native Lua string and number types. Since Lua has no native date, time, or timestamp data type, LuaFy expands Lua with a "userdata" type called luafy.timestamp that can hold FileMaker Timestamp, Date, or Time values. Any FileMaker Date, Time, or Timestamp value passed as an argument to your script is automatically converted to a luafy.timestamp value.

The only FileMaker value that cannot be passed to Lua is a Container. (This may be added in a future version of LuaFy.)

Return values from LuaFy: If you want to return a value to FileMaker from your Lua script, use Lua's "return" keyword. Lua values returned to FileMaker can be of type string, boolean, number, luafy.timestamp, or nil. If you return multiple values, only the first value is returned to FileMaker, and the rest are discarded. Lua's string and number convert to the corresponding FileMaker Text and Number types. Lua's boolean converts to a FileMaker Number value with 0 (false) or 1(true). A luafy.timestamp value is converted to a FileMaker Timestamp (which is easily converted to a FileMaker Date or Time). The other Lua fundamental data types (function, userdata, thread, and table) return an empty result if you try to return them directly to FileMaker. LuaFy provides a convenience function luafy.tolist() to convert a simple table to a string value built like a FileMaker List to return a table to FileMaker easily.

Note that Lua's "stdout" is not implemented, but real file operations are available. Since stdout is not defined, Lua's print() and io.write() to stdout won't work either. io.write() to a real file works fine.

LuaFy_RunFile ( filePath {; arg...} )

This behaves exactly like LuaFy_RunScript() except that the Lua script text is read from the filename you specify. The first argument can be an absolute path to the file. You can provide a path that is relative to the path of the active FileMaker file if the file is hosted locally (i.e. if Get(FilePath) starts with "file:", the file is local). Windows users should note that the path uses "/" instead of "\" in the path. Absolute paths are recognized as starting with "/" or having a ":" as the second character (e.g. C:/somewhere/something.lua).

Example: LuaFy_RunFile("myfile.lua"; 1; 2; 3)

Example: LuaFy_RunFile("Scripts/script01.lua"; "hello"; Contact::Name)

Example: LuaFy_RunFile("/Users/jexample/Documents/Scripts/script01.lua"; "hello"; Contact::Name) for Mac OS X.

Example: LuaFy_RunFile("C:/Documents and Settings/Joe Example/My Documents/Scripts/script01.lua"; "hello"; Contact::Name) for Windows.

LuaFy_CallFunction ( luaFunctionName {; arg...} )

Execute a specific Lua function with the function arguments you provide. The returned value is the value calculated by the function.

The luaFunctionName is any function already defined in your Lua environment. This can be one of the built-in Lua functions or a function you have defined in a previous call to LuaFy_RunScript() or LuaFy_RunFile(). luaFunctionName is limited to values like "myFunction" or "myTable.myFunction". Other less direct ways of accessing functions are not supported by LuaFy_CallFunction() (e.g. tableOfFunctions[3] or a.b.fn).

While you can achieve essentially the same result using LuaFy_RunScript(), this function provides a shorter method which is functionally similar to FileMaker Pro Advanced's Custom Functions. Once the functions are already defined in Lua, you can call them with parameters in a simple way.

Example: LuaFy_CallFunction("string.gsub"; "This is an example sentence."; "(exam%a+)"; "excellent")
Result: This is an excellent sentence.

LuaFy_ResumeFunction LuaFy Plus
LuaFy_ResumeFunction ( {arg...} ) LuaFy Plus

One feature that is unique to LuaFy_CallFunction() and is not available to LuaFy_RunScript() or LuaFy_RunFile() is the ability to use Lua's "coroutine.yield()" statement in your Lua function to give control back to FileMaker before the Lua function has completed. Internally LuaFy_CallFunction() creates a new Lua thread and a calls your function as a Lua coroutine. If it encounters a "coroutine.yield(arg)" statement in your Lua function, the function pauses there, LuaFy_CallFunction() returns arg to FileMaker, and LuaFy_LastError gives "3200: Coroutine yielded.". When you want to resume running your LuaFy_CallFunction() Lua function where it left off, call LuaFy_ResumeFunction( {arg...} ). Any arguments you provide to LuaFy_ResumeFunction() will be returned by coroutine.yield() when your function resumes. If you have multiple "coroutine.yield()" statements in your function you call LuaFy_ResumeFunction repeatedly until it returns your function result and LuaFy_LastError returns 0.

Both when encountering a "coroutine.yield(argument)" statement, the argument is passed back as the value returned to LuaFy_CallFunction() or LuaFy_ResumeFunction(). The arguments provided to LuaFy_ResumeFunction() becomes the results of "coroutine.yield(argument)" statement. This follows the same pattern as Lua's normal coroutine yield/resume system.

LuaFy_CallFunction() followed by repeated calls to LuaFy_ResumeFunction() in a looping FileMaker script allows you to carry out lengthy tasks in Lua and still provide feedback to the user about the calculations progress or allow the user to cancel the script.

Note that using "coroutine.yield()" directly in the script run by LuaFy_RunScript() or LuaFy_RunFile() and attempting to yield control to FileMaker will fail with error 3020. To use coroutine.yield/resume properly in this context you'll need to create your own coroutines in your Lua script.

LuaFy_Timeout ( {sec} ) LuaFy Plus
LuaFy_Timeout ( sec ; instructionCount ) LuaFy Plus
LuaFy_Timeout ( "tuning" ) LuaFy Plus

LuaFy will return a "Time limit exceeded" error if executing the Lua code takes too long. The default value of "too long" is 5 seconds. This prevents your Lua code from locking up FileMaker indefinitely, e.g. with an infinite loop in your Lua script.

Lua is a very fast scripting language so 5 seconds of CPU time is a very long time to get work done.

LuaFy_Timeout will return the current value of the timeout. In LuaFy it will always be "5" for 5 seconds. If you are running LuaFy Plus this can be a different number.

With LuaFy Plus if you want to run a longer calculation or be more restrictive on how long a calculation can run, you use LuaFy_Timeout() to specify a different number of seconds to use. The timing of the Lua script is only measured to the nearest second.

Specify the number of seconds you want to assign to the timeout for running Lua code. The minimum value you can set is 1 second. LuaFy_Timeout will return the number of seconds to which the timeout is currently set even if you leave out the argument.

LuaFy_Timeout() has a second optional argument that specifies how many Lua instructions are executed before the timer is checked. The default value is 100 instructions. If you have a very tight execution loop and need to optimize your code for runtime speed, make instructionCount a high number like 1000 or more to avoid the overhead of checking the elapsed time. If you have Lua instructions that can take a long time, e.g. os.execute or luafy.shellexec(), you may want to set instructionCount to a low number like 5 so that you can keep a closer eye on your timing. Set instructionCount to a negative number like -1 if you want to turn off the timeout for some reason (not recommended).

If you need to learn the current setting of instructionCount, call LuaFy_Timeout("tuning") to get a number. In LuaFy this will be 100. In LuaFy Plus this can anything from 0 to 1000000. 0 indicates that the timeout feature is shut off.

LuaFy_LastError ( {errorFormat} )

This value is zero when there is no error. If a LuaFy plug-in function generates an error, the result of LuaFy_LastError will be in the format "ERRNUM: Error message". While the number ERRNUM will indicate a general category of error, error message is quite specific. Error messages generated in the Lua scripting engine are returned so you can specifically locate the problem. For example the error message for 3010 (Lua syntax error) will provide specific details about what Lua did not understand in your Lua script.

errorFormat can be "number" or "message" if you want LuaFy_LastError() to return just the error number or the error message. If errorFormat is "full" (the default value), both number and message are returned.

0(no error, no message)Any
3002File not found or is not readable.LuaFy_RunFile()
3004Unable to resolve into relative file path.LuaFy_RunFile()
3005Unable to create relative file path using FileMaker's Get(FilePath).LuaFy_RunFile()
3010Lua syntax errorLuaFy_RunScript(), LuaFy_RunFile()
3012Lua compiler memory allocation errorLuaFy_RunScript(), LuaFy_RunFile()
3018Lua compiler unknown errorLuaFy_RunScript(), LuaFy_RunFile()
3020Lua runtime errorLuaFy_RunScript(), LuaFy_RunFile(), LuaFy_CallFunction(), LuaFy_ResumeFunction()
3022Lua runtime memory allocation errorLuaFy_RunScript(), LuaFy_RunFile(), LuaFy_CallFunction(), LuaFy_ResumeFunction()
3024Lua runtime error in error handlingLuaFy_RunScript(), LuaFy_RunFile(), LuaFy_CallFunction(), LuaFy_ResumeFunction()
3028Lua runtime unknown errorLuaFy_RunScript(), LuaFy_RunFile(), LuaFy_CallFunction(), LuaFy_ResumeFunction()
3100Function does not exist.LuaFy_CallFunction()
3110Table does not exist.LuaFy_CallFunction()
3111Table entry is not a function.LuaFy_CallFunction()
3200Coroutine yielded.LuaFy_CallFunction(), LuaFy_ResumeFunction()
3250Cannot resume. No function is active.LuaFy_ResumeFunction()
3300Not a valid number of seconds for timeout.LuaFy_Timeout()
3350Not a valid number of instructions for timeout tuning.LuaFy_Timeout()
3400Bad argument.LuaFy_Version()
3900Not enough parameters to license LuaFy Plus.LuaFy_Version()
3999Demo time expired. Restart the app to restore normal LuaFy functionality.Any

LuaFy is a product of Cosmic Consulting
Tom Hays <>