Lua Scripting

Rainmeter, nor anyone associated with Rainmeter, is responsible for teaching you the Lua scripting language. This guide is only meant to help with using Lua with Rainmeter. However, Lua is a relatively simple language, and there are many good sites where you can learn Lua itself:

http://www.lua.org/manual/5.1/
http://lua-users.org/wiki/LuaTutorial

Or a really good book for sale:
Programming Lua Second Edition

Overview

A Lua scripting language file (.lua) can be executed by Rainmeter, passing settings from Rainmeter to the script. The script can then be used to read Rainmeter measures and meters from the calling skin, do any kind of processing outside of Rainmeter that you like, and take various actions that impact the Rainmeter skin:

  • Return a string or number value to the Lua measure, which can be used in Rainmeter just like the value returned by any measure.
  • Directly set the value of a string meter.
  • Change the value of any #Variable# set in the [Variables] section of the skin.
  • Control many aspects of the overall skin, or a measure or meter, such as position, size, enable/disable etc.
  • Send any !Bang command to the skin.
  • Write values to the Rainmeter log file.

Rainmeter has the Lua 5.1 codebase embedded. It contains all the standard libraries and functions that come with Lua, but currently cannot be extended by using external libraries like LuaCURL in your code or "including" external script files using "dofile". This is due both to the need to protect the Rainmeter core in memory, and to limitations of Lua external libraries in a 32bit / 64bit environment. Improvements to this may come at a later date.

In the Skin

Lua is integrated with Rainmeter using the new Rainmeter Measure=Script measure type:

[MeasureLuaScript]
Measure=Script
ScriptFile=MyScript.lua
MySetting="SomeSetting"
UpdateDivider=30

ScriptFile= This is the required name of the .lua file you will be executing.
MySetting= This is just a sample to show how you can pass information to the Lua script from Rainmeter when it is run. This can be any key name and any value, and you can have none, or as many as you like.
UpdateDivider= This optionally tells Rainmeter how often to execute the script, as with any other Rainmeter measure.

Notes:
  • You can use any other standard Rainmeter settings that control measures, like Disabled=0/1
  • You can use #Variables# in any setting in a script measure, but as with plugins, you cannot use dynamic variables.
  • As of this writing, Lua can interact with the current skin, and variables, meters and measures within the skin. There is currently no capability to interact with Rainmeter in general, nor any way to interact with any skin other than the one that ran the script, except by using bangs.

In the Script

There are three functions in a .lua script file written for Rainmeter that control the overall interaction with Rainmeter:

PROPERTIES
This is actually a Lua "table", used to hold the settings (Key=Value, like MySetting="SomeSetting" in the example above) you wish to pass from Rainmeter to the Lua script. You simply tell it the name of the key from the measure in the skin, and initialize it with any value. The format is:
PROPERTIES =
{
MyTextSetting = ""; MyNumberSetting = 0; }

You can then later use these settings in your script, with PROPERTIES.MyTextSetting for example, a standard Lua way of reference a table index by value. Remember that Lua is always "case sensitive". This table is PROPERTIES, not Properties.

function Initialize()
This function is used to perform actions you wish to do "once" when the skin is loaded or refreshed. It can be used to have the script get the structures of measures and meters in the skin so you can interact with them later, initialize global variables, tables etc. you will use later, or even take actions on the skin that you only want to happen once. For instance:
function Initialize()
  Measure1 = SKIN:GetMeasure("SomeMeasure")
  Meter1 = SKIN:GetMeter("SomeMeter")
  CurrentMeter1Height = Meter1:GetH()
  Meter1:Hide()

  MyNewVar = PROPERTIES.MyTextSetting
  MyNewTable = {}
end

function Update()
The Update() function is where you will put the bulk of your code. It is executed on every update cycle of the measure and should return either a string or a number, which will be used as the value of the SCRIPT measure. For the purpose of this example, lets assume that your Script measure is called MeasureScript.
  • return 99 - MeasureScript will have a numerical value of 99 (e.g. when used in Calc measures) and a textual value of "99" (e.g. when used as the MeasureName in STRING meters)
  • return "99" - MeasureScript will have a numerical value of 99 and a textual value of "99"
  • return "Ninety Nine" - MeasureScript will have a textual value of "Ninety Nine"
Example:
function Update()
  SomeNewVar = "Hello World"
  SKIN:Bang(!SetVariable MyVar "..SomeNewVar)
  NewReturnValue = 99

  return NewReturnValue
end

Simple Example:

Skin:
[Rainmeter]
Update=1000

[MeasureLuaScript]
Measure=Script
ScriptFile="#CURRENTPATH#LuaSample.lua"
SettingInSkin=20

[MeterLua]
Meter=String
MeasureName=MeasureLuaScript
FontSize=12
FontColor=255,255,255,255

Script:
PROPERTIES =
{
  SettingInSkin = 0;
}

function Initialize()
  CurrentNumber = tonumber(PROPERTIES.SettingInSkin)
end

function Update()
  NewNumber = CurrentNumber + 50
  return NewNumber
end

The measure [MeasureLuaScript] in the skin will have a string value of "70", which can be used in any calc or meter.

Functions

There are several Rainmeter-specific functions exposed to Lua. Functions may return a string (e.g. "example"), a number (e.g. 42), a boolean value (i.e. true or false), or nothing (marked by void).

print()
Allows you to output text to the Rainmeter log. Note that if the Lua interpreter raises an error in your Lua code in general, it will automatically be written to the Rainmeter log and can be viewed using "About" from the Rainmeter context menu.
print("Script just ran!")

Skin functions

These functions can be used on used with the SKIN: prefix. For example:

meter = SKIN:GetMeter("ExampleMeter")
SKIN:Bang("!Refresh")
  • void Bang(string bang)
    Runs given string.
  • meterType GetMeter(string meter)
    Returns a handle to the meter. Read more below.
  • measureType GetMeasure(string measure)
    Returns a handle to the measure. Read more below.
  • void Bang(string bang)
    Runs given string.
  • string GetSkinName()
    Returns current skin name.
  • string GetSkinIniFile()
    Retruns full path to the current skin .ini file.
  • void MoveWindow(number x, number y)
    Moves the skin to given coordinates.
  • void FadeWindow(number from, number to)
    Fades the skin.
  • string MakePathAbsolute(string path)
    Converts relative path into an absolute path (relative to the skin folder).
  • string GetVariable(string name)
    Retrieve variable name. Retruns nil for an invalid variable.
  • string ReplaceVariables(string text)
    Replaces #variables# in given string and returns the result.

Meter functions

These functions can be used on meter objects returned by the SKIN:GetMeter() call. For example:

anyMeter = SKIN:GetMeter("ExampleMeter")
anyMeter:SetX(25)
  • void SetX(number y)
    Set the meter X position.
  • void SetY(number y)
    Set the meter Y position.
  • void SetW(number w)
    Set the meter width.
  • void SetH(number h)
    Set the meter height.
  • number GetX(bool abs = false)
    Returns the meter X position.
  • number GetY(bool abs = false)
    Returns the meter Y position.
  • number GetH()
    Returns the meter height.
  • number GetW()
    Returns the meter width.
  • void Hide()
    Hide the meter.
  • number Show()
    Show the meter.
  • string GetOption(string option)
    Returns the value of the meter option (e.g. SolidColor).
  • string GetName()
    Returns meter name.

Measure functions

These functions can be used on objects returned by the SKIN:GetMeasure() call. For example:

anyMeasure = SKIN:GetMeasure("ExampleMeasure")
anyMeasure:Disable()
  • string GetValue()
    Returns the numerical value of the measure.
  • string GetStringValue()
    Returns the string value of the measure.
  • void Disable()
    Disable the measure.
  • void Enable()
    Updates string text.
  • string GetOption(string option)
    Returns the value of the measure option (e.g. MaxValue).
  • string GetName()
    Returns measure name.
  • number GetRelativeValue()
    Returns the measure value from scaled from 0.0 to 1.0.
  • number GetValueRange()
    Returns the value range.
  • number GetMinValue()
    Returns measure minimum value.
  • number GetMaxValue()
    Returns measure maximum value.

Deprecated Functions

These are functions that should not be used. They are supported for now and may be removed in the future.

  • tolua.cast - Simply use SKIN:GetMeter() by itself
  • TO.LuaLog() - Use print() instead
  • meter:SetText() - Prefer SKIN:Bang('!SetOption "MeterName" "Text" "Value"') instead
  • function GetValue() and function GetStringValue() when used to return a value to the skin - Return number or string in Update() instead

Executing Lua code within Rainmeter

The !CommandMeasure bang can be used to execute Lua code in Rainmeter.

LeftMouseUpAction=!Execute [!CommandMeasure "ScriptMeasure" "someVar=5;someVar2=someVar*7;Update()"]
-> set variable someVar to 5, set a new variable with a formula, and immediately execute the Update function. (in the context of the ScriptFile specified by ScriptMeasure)

Example Skins

There are some simple skins using the new Lua integration on the Rainmeter forums. Tearing them apart can be the best way to learn how it all fits together: