Thought I would stat a thread where simple little "tips and tricks" could be added as posts, without starting a whole new thread for each one. This should be for reasonably specific snippets or ideas that you find useful in using Lua with Rainmeter, or just in using Lua. Sort of a little "knowledge base" for the clever stuff you folks come up with. If you think about it, change the "subject" of your reply / post to be something about it, to help when folks are searching the forums for a solution.
Do NOT post any "help me" messages in this thread, or they will be deleted without comment. Make a new thread in the main "Lua & Rainmeter" topic instead.
It is currently October 9th, 2024, 6:51 pm
Tips & Tricks Thread
-
- Developer
- Posts: 22847
- Joined: April 19th, 2009, 11:02 pm
- Location: Fort Hunt, Virginia, USA
-
- Developer
- Posts: 22847
- Joined: April 19th, 2009, 11:02 pm
- Location: Fort Hunt, Virginia, USA
Running Lua scripts on demand
For instance:
There is another clever way of having a Lua script run on demand, rather than using disabled/enabled or setting UpdateDivider=-1. Poiru and I were talking about this the other day, and he came up with this, which I think is worth having in your toolbelt if needed.
In the script:
In the skin:
or
or
Or any other way you want to execute the script "on demand".
This has advantages over enabled/disabled on the script measure as disabled measures return zero as a numeric value, which you may not want "between runs". It has advantages over UpdateDivider=-1, as that setting will still run the measure one time when the skin is refreshed, and this also may not be what you want. All the methods have their place however, this is just one more.
There is another clever way of having a Lua script run on demand, rather than using disabled/enabled or setting UpdateDivider=-1. Poiru and I were talking about this the other day, and he came up with this, which I think is worth having in your toolbelt if needed.
In the script:
Code: Select all
function Initialize()
RunMe = false
end -- function Initialize
function Update()
if RunMe then
-- put your actual code here
RunMe = false
end
return "I just ran!"
end -- function Update
Code: Select all
FinishAction=!CommandMeasure "LuaMeasure" "RunMe = true"
Code: Select all
OnRefreshAction=!CommandMeasure "LuaMeasure" "RunMe = true"
Code: Select all
LeftMouseUpAction=!CommandMeasure "LuaMeasure" "RunMe = true"
This has advantages over enabled/disabled on the script measure as disabled measures return zero as a numeric value, which you may not want "between runs". It has advantages over UpdateDivider=-1, as that setting will still run the measure one time when the skin is refreshed, and this also may not be what you want. All the methods have their place however, this is just one more.
-
- Developer
- Posts: 2873
- Joined: April 17th, 2009, 12:18 pm
Re: Running Lua scripts on demand
Here is yet another method:jsmorley wrote:This has advantages over enabled/disabled on the script measure as disabled measures return zero as a numeric value, which you may not want "between runs". It has advantages over UpdateDivider=-1, as that setting will still run the measure one time when the skin is refreshed, and this also may not be what you want. All the methods have their place however, this is just one more.
Script (specify Initialize() and Update() if you need them*):
Code: Select all
function SomeFunction()
-- do whatever you want here
end
Code: Select all
!CommandMeasure "LuaMeasure" "SomeFunction()"
Script (specify Initialize() and Update() if you need them):
Code: Select all
function SomeFunction(x)
-- do whatever you want here, x is a variable
end
Code: Select all
!CommandMeasure "LuaMeasure" "SomeFunction(10)"
* Initialize(), Update(), and the PROPERTIES table are all optional and don't need to be specified. Note that Update() is required for returning a value back to Rainmeter.
-
- Developer
- Posts: 22847
- Joined: April 19th, 2009, 11:02 pm
- Location: Fort Hunt, Virginia, USA
Re: Tips & Tricks Thread
Reading a .ini file in Lua:
Here is a script with a function to populate a table with the contents of any .ini file. It is a three dimensional matrix of Section / Key / Value.
This script includes the function, and a sample Update() to demonstrate how to use it to print out the [Rainmeter] keys and values in Rainmeter.ini, and how to find the "Update=" value of the current skin.
Based on code here: http://luaforge.net/projects/inilazy/
Note/Caution: If you are going to return the value of a "config" in Rainmeter.ini, you must "escape" any "\" chars.
for sKey,a in pairs(tTable['Enigma\\Clock']) do
Here is a script with a function to populate a table with the contents of any .ini file. It is a three dimensional matrix of Section / Key / Value.
This script includes the function, and a sample Update() to demonstrate how to use it to print out the [Rainmeter] keys and values in Rainmeter.ini, and how to find the "Update=" value of the current skin.
Based on code here: http://luaforge.net/projects/inilazy/
Code: Select all
function Initialize()
sIniPath = SKIN:GetVariable("SETTINGSPATH")
sCurrSkin = SKIN:GetVariable("CURRENTPATH")..SKIN:GetVariable("CURRENTFILE")
end -- function Initialize
function Update()
tTable = ReadIni(sIniPath ..'Rainmeter.ini')
for sKey,a in pairs(tTable['Rainmeter']) do
for sValue,b in pairs(tTable['Rainmeter'][sKey]) do
print(sKey.."="..sValue)
end
end
tTable = ReadIni(sCurrSkin)
for sKey,a in pairs(tTable['Rainmeter']) do
if sKey == 'Update' then
for sValue,b in pairs(tTable['Rainmeter'][sKey]) do
sSkinUpdate = sValue
print(sSkinUpdate)
end
end
end
end -- function Update
function ReadIni(filename)
local f = io.open(filename,'r')
if not f then return nil, print("ReadIni: Can't open file: "..filename) end
local line_counter=0
local tablename = {}
local section
for fline in f:lines() do
line_counter=line_counter+1
-- Ignore leading and trailing spaces
local line = fline:match("^%s*(.-)%s*$")
-- Ignore comments
if not line:match("^[%;#]") and #line > 0 then
-- Check for [Section]
local sec = line:match("^%[(.*)%]$")
if sec then
section = sec
if not tablename[section] then tablename[section]={} end
else
-- parse Key=Value
local key, value = line:match("([^=]*)%=(.*)")
-- Remove white space from Key=Value
key = key:match("^%s*(%S*)%s*$")
value = value:match("^%s*(.-)%s*$")
-- Check for error
if not (key and value) then return nil, print('Error bad key or value in file:'.. filename..': '.. line_counter.."\n line:".. fline) end
-- Set Section/Key/Value in table
if section then
if not tablename[section][key] then tablename[section][key]={} end
if not tablename[section][key][value] then tablename[section][key][value]={} end
end
end
end
end
f:close()
return tablename
end -- function ReadIni
for sKey,a in pairs(tTable['Enigma\\Clock']) do
-
- Posts: 8
- Joined: March 12th, 2011, 3:18 am
Basic and Standard Lua Functions
Stumbled across this one today and figured it would be a worthy addition to this thread. For those looking for a rather basic function (like reading or writing to a file, simple mathematical operations, working with strings or arrays, ...), I recommend checking out Rosetta Code's Lua additions. May have what you are looking for or something incredibly close to it.
-
- Moderator
- Posts: 1931
- Joined: January 29th, 2010, 1:43 am
- Location: Willmar, MN
Re: Tips & Tricks Thread
Here's a simple way to change multiple settings of a meter using !SetOption without having to type out every bang.
Code: Select all
mName='MeterName'
for k,v in pairs({
--PropertyName='Value';
Text='Some Text';
Antialias=1;
}) do SKIN:Bang('!SetOption',mName,k,v) end
GitHub | DeviantArt | Tumblr
This is the song that never ends. It just goes on and on my friends. Some people started singing it not knowing what it was, and they'll continue singing it forever just because . . .
This is the song that never ends. It just goes on and on my friends. Some people started singing it not knowing what it was, and they'll continue singing it forever just because . . .
-
- Moderator
- Posts: 1931
- Joined: January 29th, 2010, 1:43 am
- Location: Willmar, MN
Re: Tips & Tricks Thread
Here's a simple way to retrieve several variables from the skin, storing them in a table for late use.
They can be retrieved in a couple ways.
Code: Select all
Vars={}
for i,v in pairs({'Var1','Var2'}) do
Vars[v]=SKIN:GetVariable(v)
end
- Vars.Var1
- Vars['Var1']
GitHub | DeviantArt | Tumblr
This is the song that never ends. It just goes on and on my friends. Some people started singing it not knowing what it was, and they'll continue singing it forever just because . . .
This is the song that never ends. It just goes on and on my friends. Some people started singing it not knowing what it was, and they'll continue singing it forever just because . . .
-
- Developer
- Posts: 22847
- Joined: April 19th, 2009, 11:02 pm
- Location: Fort Hunt, Virginia, USA
Re: Tips & Tricks Thread
I must be missing something in this. I can't get that approach to work at all. What I find is that if you don't set some default value for a "dictionary" index of a table, then it can't be looped through with "pairs". Also I find that I can't use "value" to retrieve or set data, but have to use "index". I mean, you can't say GetVariable(value) when value doesn't exist yet can you?smurfier wrote:Here's a simple way to retrieve several variables from the skin, storing them in a table for late use.
So this construct in a script, using your approach, does not work for me:
Code: Select all
PROPERTIES =
{
}
function Initialize()
SkinVars = {
CURRENTPATH;
CURRENTFILE;
CURRENTCONFIG;
ROOTCONFIGPATH;
}
for index, value in pairs(SkinVars) do
SkinVars[value] = SKIN:GetVariable(value)
end
end -->Initialize
function Update()
return SkinVars.CURRENTCONFIG
end -->Update
Code: Select all
PROPERTIES =
{
}
function Initialize()
SkinVars = {
CURRENTPATH='';
CURRENTFILE='';
CURRENTCONFIG='';
ROOTCONFIGPATH='';
}
for index, value in pairs(SkinVars) do
SkinVars[index] = SKIN:GetVariable(index)
end
end -->Initialize
function Update()
return SkinVars.CURRENTCONFIG
end -->Update
Code: Select all
local Vars = {
--VariableName;
Var1='';
SomeVar='';
}
for index,value in pairs(Vars) do Vars[index]=SKIN:GetVariable(index) end
-
- Moderator
- Posts: 1931
- Joined: January 29th, 2010, 1:43 am
- Location: Willmar, MN
Re: Tips & Tricks Thread
It must have been because of how I altered my approach.
This is what has been working for me.
This is what has been working for me.
Code: Select all
Vars={}
for i,v in pairs({'Var1','Var2'}) do
Vars[v]=SKIN:GetVariable(v)
end
GitHub | DeviantArt | Tumblr
This is the song that never ends. It just goes on and on my friends. Some people started singing it not knowing what it was, and they'll continue singing it forever just because . . .
This is the song that never ends. It just goes on and on my friends. Some people started singing it not knowing what it was, and they'll continue singing it forever just because . . .
-
- Developer
- Posts: 22847
- Joined: April 19th, 2009, 11:02 pm
- Location: Fort Hunt, Virginia, USA
Re: Tips & Tricks Thread
Yeah, works that way, although I'm not sure I have wrapped by head around why it would be Vars[v]=SKIN:GetVariable(v) instead of Vars[i]=SKIN:GetVariable(i), but it is...smurfier wrote:It must have been because of how I altered my approach.
This is what has been working for me.Code: Select all
Vars={} for i,v in pairs({'Var1','Var2'}) do Vars[v]=SKIN:GetVariable(v) end