Lua Scripting

Rainmeter has the ability to load and execute scripts in Lua, a functional programming language. Rainmeter includes the Lua 5.1 standard libraries, which encompass a variety of powerful features.

A script refers to a set of Lua functions that is associated with a script measure. These functions may be executed when the skin loads, when it updates, or on command.

This page details the Rainmeter-specific modifications and new functions that have been added to Rainmeter's built-in Lua environment. More documentation for Lua itself is available at:

The rest of this page assumes a basic knowledge of the Lua language.

Script Measure

The script measure is used to load a Lua script from a file and interface with the script. The script file must be a text file, and typically has the extension .lua.

Much like plugin measures, each script measure creates a separate instance of its script. This means that a skin can have any number of scripts loaded simultaneously—even from the same script file. (The order in which scripts are executed is determined by the measure order.) "Global" variables are not shared between instances.

[MeasureName]
Measure=Script
ScriptFile=MyScript.lua

Options

In addition to general measure options and ScriptFile, scripts also allow user-defined options. These options may have any name and value, and may be changed with !SetOption. The script can read and use its own option values using the SELF object functions. This allows the same script file to be used with different parameters depending on the context.

[MeasureName]
Measure=Script
ScriptFile=MyScript.lua
MyOption=Hello, world!

Dynamic Variables

Dynamic variables are generally not needed with script measures. This is because functions are provided to get the current values of variables, measures and options within Lua. If these functions are used in the Update function, they will return the current values at the time the function is called.

!CommandMeasure

The !CommandMeasure bang can be used to execute Lua code in the context of a particular script instance:

!CommandMeasure "MyScriptMeasure" "MyFunction()"

Multiple statements may be separated by semicolons (;). All statements are global.

!CommandMeasure "MyScriptMeasure" "a = b; print(SKIN:ParseFormula('2+2'))"

All statements must be passed as a single parameter in the bang. Because single-quotes (') and double-quotes (") are both valid string containers in Lua, while only double-quotes are recognized in Rainmeter, single quotes are recommended when passing strings with !CommandMeasure.

Initialize

If the Initialize function is defined in any script, the function is called one time (without parameters) when the skin is activated or refreshed. This happens even if the script measure is disabled. If the script file is changed by a !SetOption bang, the new script's Initialize function is called as well.

function Initialize()
MyVariable = 'Hello, world!'
end

Actions that are needed to "set up" the script, such as declaring global variables, should be done in the Initialize function.

Using dofile

The dofile function can be used to include libraries or other snippets of Lua code. You must specify a full path to the dofile, using the syntax dofile('C:\PathToDoFile\SomeLua.lua'). Use the GetVariable function if you want to use the #@# variable shortcut to the @Resources folder for the current config, or MakePathAbsolute if you want to have the .lua file be relative to the current skin folder.

function Initalize()
dofile(SKIN:GetVariable('@')..'MyDoFiles\\toolkit.lua')
dofile(SKIN:MakePathAbsolute('toolkit.lua'))
end

Note: While a dofile you call can be anywhere on your system, be aware that if you do not put the dofile .lua file somewhere in the path to the current config, you won't be able to distribute it with your skin as a .rmskin package. A .rmskin package can only distribute the contents of a single root config folder.

Update

If the Update function is defined in any script, the function is called (without parameters) whenever the script measure updates. The script measure responds normally to the Disabled option, the UpdateDivider option, and all measure bangs.

function Update()
MyVariable = 'Hello, world!'
return MyVariable
end

The Update function's return value determines what values are provided by the script measure. Strings and numbers in Lua are analogous to string values and number values in Rainmeter measures. Examples:

  • return
    Provides 0 as the number value, and '' (blank) as the string value. The same is true if no return is stated.

  • return 99 and return '99'
    Provides 99 as the number value, and '99' as the string value.

  • return 'Ninety-Nine'
    Provides 0 as the number value (because the string cannot be converted to a number), and 'Ninety-Nine' as the string value.

The values provided by the script measure can be used in the same way as other measure values. (Note: the values only update when the measure itself updates. Calling Update() within Lua does not update the measure values.)

Log

Lua errors are logged in the About window. The print function may also be used to write strings to the log. This can provide helpful feedback when writing or troubleshooting a script.

print('The current value of MyVariable is: ' .. MyVariable)

Functions

Lua functions are provided to identify a meter, a measure, or the current skin as a Lua object. Additional functions are provided for manipulating each type of object in specific ways.

SKIN object

The SKIN object is created automatically.

GetMeasure Parameter: MeasureName

Creates a handle object for the named measure. Returns nil if the measure is not found.

Example: MyMeasure = SKIN:GetMeasure('MeasureName')

GetMeter Parameter: MeterName

Creates a handle object for the named meter. Returns nil if the meter is not found.

Example: MyMeter = SKIN:GetMeter('MeterName')

GetVariable Parameter: VariableName, Default

Returns the current value of the named variable as a string. If the variable does not exist, returns the given default value, or nil if no default is given.

Example: MyVariable = SKIN:GetVariable('VariableName', 'n/a')

Bang Parameters: Bang or BangName, BangArg1, BangArg2, BangArgN

Executes a bang. The bang can be constructed in one of two ways:

  1. The entire bang as a single string.

    Example: SKIN:Bang('!SetOption "MyMeter" "Text" "Hello, world!"')

    Multiple bangs are valid using this method.

    SKIN:Bang('[!UpdateMeter "MyMeter"][!Redraw]')


  2. Each bang parameter as a separate parameter in the function.

    Example: SKIN:Bang('!SetOption', 'MyMeter', 'Text', 'Hello, world!')

    Multiple bangs must be separate using this method.

    SKIN:Bang('[!UpdateMeter "MyMeter"]')
    SKIN:Bang('[!Redraw]')

    Note: In spite of the need for a separate SKIN:Bang() function for each bang you want to use, this second method is strongly recommended. You will quickly find that the first method, using a single string to define the bang(s) will quickly become very complicated to properly quote if the bangs themselves contain strings that must be quoted.

MakePathAbsolute Parameter: File/Folder

Converts a relative file path into a full file path. The path will be relative to the skin folder.

Example: MyPath = SKIN:MakePathAbsolute('MyImage.png')

ReplaceVariables Parameter: String

Returns the given string, with all valid variable values properly replaced. Section variables are valid.

Example: MyString = SKIN:ReplaceVariables('The value of MyVariable is #MyVariable#.')

ParseFormula Parameter: FormulaString

If the given string is a valid formula, evaluates the formula and returns the result as the number. Otherwise, returns nil. This can take advantage of mathematical functions in Rainmeter that may not be built into Lua. Remember that formulas in Rainmeter must be entirely enclosed in (parentheses).

numToRound = 239.78
roundedNum = SKIN:ParseFormula('(Round('..numToRound..'))')

Measure object

A Measure object is created using GetMeasure. It creates a handle to a specific measure in the skin, which can then be used with the following functions to act on the measure.

Example: MyMeasure = SKIN:GetMeasure('MeasureName')

GetValue

Returns the current number value of the measure.

Example: MyMeasureValue = MyMeasure:GetValue()

GetStringValue

Returns the current string value of the measure.

Example: MyMeasureValue = MyMeasure:GetStringValue()

GetOption Parameters: OptionName, Default

Returns the current value of the named option as a string. If the option does not exist, returns the given default value, or '' if no default is given.

Example: MyGroup = MyMeasure:GetOption('Group', 'None')

GetNumberOption Parameters: OptionName, Default

Returns the current value of the named option as a number. If the option does not exist, or is not a valid number or formula, returns the given default value, or 0 if no default is given.

Example: MyUpdateDivider = MyMeasure:GetNumberOption(UpdateDivider, 1)

GetName

Returns the measure's name as a string.

Example: MyMeasureName = MyMeasure:GetName()

GetMinValue

Returns the current minimum value of the measure as a number.

Example: MyMeasureMin = MyMeasure:GetMinValue()

GetMaxValue

Returns the current maximum value of the measure as a number.

Example: MyMeasureMax = MyMeasure:GetMaxValue()

GetRelativeValue

Returns the measure's current number percentage value as a number, scaled from 0.0 to 1.0. The result will be based on the current defined or derived MinValue and MaxValue of the measure.

Example: MyMeasureValue = MyMeasure:GetRelativeValue()

GetValueRange

Returns the current value range of the measure as a number. The result will be based on the current defined or derived MinValue and MaxValue of the measure, and will be the difference between the two.

Example: MyMeasureRange = MyMeasure:GetValueRange()

Disable

Disables the measure.

Example: MyMeasure:Disable()

Enable

Enables the measure.

Example: MyMeasure:Enable()

SELF object

The SELF object is created automatically. SELF is a measure object linked to the current script measure. All measure object functions are valid for SELF.

MyScriptMeasureName = SELF:GetName()

Meter object

A Meter object is created using GetMeter. It creates a handle to a specific meter in the skin, which can then be used with the following functions to act on the meter.

Example: MyMeter = SKIN:GetMeter('MeterName')

GetOption Parameters: OptionName, Default

Returns the current value of the named option as a string. If the option does not exist, returns the given default value, or '' if no default is given.

Example: MySolidColor = MyMeter:GetOption('SolidColor', '000000')

GetName

Returns the meter's name as a string.

Example: MyMeterName = MyMeter:GetName()

GetX Parameters: Absolute

Returns the current X position of the meter as a number. If the optional Absolute parameter is true, returns the absolute (or "real") X position, which may be different than the defined option on the meter.

Example: MyX = MyMeter:GetX()

GetY Parameters: Absolute

Returns the current Y position of the meter as a number. If the optional Absolute parameter is true, returns the absolute (or "real") Y position, which may be different than the defined option on the meter.

Example: MyY = MyMeter:GetY()

GetW

Returns the current "real" width of the meter as a number.

Example: MyW = MyMeter:GetW()

GetH

Returns the current "real" height of the meter as a number.

Example: MyH = MyMeter:GetH()

SetX

Sets the X position of the meter.

Example: MyMeter:SetX()

SetY

Sets the Y position of the meter.

Example: MyMeter:SetY()

SetW

Sets the width of the meter.

Example: MyMeter:SetW()

SetH

Sets the height of the meter.

Example: MyMeter:SetH()

Hide

Hides the meter.

Example: MyMeter:Hide()

Show

Shows the meter.

Example: MyMeter:Show()

Restrictions

The following Lua features are not available in Rainmeter at this time:

  • The coroutine and debug libraries.
  • External compiled libraries, such as LuaCURL.
  • The require, os.exit, os.setlocale, io.popen, collectgarbage, getfenv, and setfenv functions.

Deprecated Features

The following Rainmeter-specific features have been deprecated and should not be used. They are still supported, but may be removed in future versions.

  • PROPERTIES = { ... }
    This table was previously used to read options on the script measure. Instead, use:
    SELF:GetOption('MyOption') or SELF:GetNumberOption('MyOption')

  • MyMeter:SetText('...')
    This function was used to change a string meter's text. Instead, use:
    SKIN:Bang('!SetOption', 'MeterName', 'Text', '...')

  • function GetStringValue()
    This function was used to set the script measure's value. Instead, use:
    function Update() ... return ... end