-
-
Notifications
You must be signed in to change notification settings - Fork 624
How to Load and Use Lua Scripts
This tutorial was originally written by mrpeachy and posted on Crunchbang. It has been updated and modified over time by various contributors. While Lua syntax is backwards compatible with older Conky versions, the configuration structure evolves over time as new functionality is added and things get rewritten. Most scripts will, however, continue working across versions - the only thing that might change are require
s and some conky specific functions (in case variables are deprecated).
If you spot areas that could use clearer explanations or improved formatting, feel free to contribute and enhance this tutorial!
This guide is designed for beginners with little to no programming experience. It also serves as a good starting point for those interested in learning Lua. Lua does provide it's own manual, so if you feel like you don't understand some bits take a look at it as well.
Lua is one of the simplest scripting languages out there. It's got some minor quirks (like 1-based array indexing), but it should be really easy to understand to most digitally literate people.
To integrate Lua scripts into Conky they have to be loaded using lua_load
in the the conky.conf
file:
conky.config = {
lua_load = "path/to/script.lua"
-- other setings
}
The config file is usually placed in ~/.config/conky/conky.conf
. On a fresh install it might need to be copied over from /etc/conky/conky.conf
.
lua_load
specifies the paths to the Lua scripts that Conky will execute. These paths can be relative if the script is placed in the same directory as conky.conf
, (e.g. lua_load = "./script.lua"
). It can also be an absolute path, (e.g. lua_load = "/home/username/scripts/script.lua"
).
Multiple files may be loaded - to do so semicolon (;
) can be used as a file path separator.
If Inotify is supported by the system (it is for most Linux distributions), these files should reload automatically when they're changed. This depends on the conky build environment (of package vendor).
Lua script files should be placed in a directory where Conky can access them. Most commonly, people place Conky scripts alongside the config file because that makes them easier to edit, copy and store on git.
If Conky is unable to load the file, double-check the file path. If it's correct, use system utilities like ls
, chown
and chmod
to ensure file can be read by Conky. For details on Linux file permissions check out this useful guide by Red Hat.
While lua_load
loads Lua scripts, Conky allows executing functions from the scripts using hooks. Hooks are called as part of the update cycle of the window, as well as startup/closing and for some events.
All Lua hooks start with lua_
and can be found in the Conky documentation.
To connect a lua function to the hook, it's necessary to specify the function name as hook value. For instance:
conky.config = {
lua_load = "script.lua",
-- other settings
lua_draw_hook_post = "main",
}
IMPORTANT: Name of the function in the Lua file is prefixed with
For drawing, most important hooks are lua_draw_hook_*
, these allow a Lua script to present information in the Conky window:
-
lua_draw_hook_pre
: Runs the function before main content (specified inconky.text
block) is drawn.- intended for drawing background graphics that should be located below any other text.
-
lua_draw_hook_post
: Runs the function after the Conky window is drawn.- intended for drawing over everything else.
Note that drawing functionality can be disabled at compile time. If installed conky version doesn't have drawing capabilities, draw hooks will do nothing. Some distributions offer various flavors of conky with different settings, so make sure to pick the appropriate one. Check your Linux distribution's documentation for installation instructions.
Conky also provides some additional hooks which might be useful for specific use cases:
-
lua_startup_hook
: Runs once when Conky starts.- intended for collecting immutable system data or preconfiguring some things in Lua that might be expensive to do every update.
-
lua_shutdown_hook
: Runs once when Conky exits.- intended for cleanup of temporary files or resources that were created for conky or from the startup hook.
-
lua_mouse_hook
: Captures mouse events within the Conky window. Covered in detail in Mouse Events section.- intended for adding interactivity to Conky. As Conky runs in a separate background layer, some mouse events might not be reported the best by X11.
These are all the supported hooks at the moment, but more might be added in future. See lua_
prefixed variables in the documentation to check if anything else has been added in meantime, or create a feature request.
Let's go step by step through a simple Lua script and explain what each part does before presenting the final code.
At the top of the script, it's necessary to load external libraries:
require("cairo")
require("cairo_xlib")
In this case, cairo
loads bindings from the Cairo library which is used for rendering in Conky. cairo_xlib
is needed to create drawing surfaces on X11.
Other bindings like rsvg
add their own libraries that can be require
d from Lua. Check the appropriate wiki pages for those.
Previously set lua_draw_hook_post = "main"
will expect a conky_main
function to be defined in one of lua_load
ed files. Missing this will cause warnings/errors, so let's define that function:
function conky_main()
-- executed Lua code goes here
end
Some hooks might provide some data to the functions. If that data isn't used, the variables can be omitted because Lua doesn't care about number of provided/used arguments - if arguments aren't provided when the function is called, the value will simply be nil
.
Arguments are simply a list of names:
function my_function(first, second)
end
For more details on function signatures, refer to the Lua manual.
Conky might try updating window content before the window has been created because window management is handled by WMs. Because windows can be a bit unpredictable at times (they get recreated), it's good practice to check whether a window currently exists from window related hooks:
if conky_window == nil then
return
end
Not doing so might cause errors in some cases, depending on WMs, luck, current phase of the moon and star alignments.
All drawing in Cairo happens on a surface. Now that we're certain conky_window
exists, values from it can be used for creation of Cairo surface:
local cairo_surface = cairo_xlib_surface_create(
conky_window.display,
conky_window.drawable,
conky_window.visual,
conky_window.width,
conky_window.height
)
local c = cairo_create(cairo_surface)
cairo_surface
is just a handle to the surface and will only be needed for proper cleanup later. c
is used for all the drawing. It's common to give it a short name like c
or ctx
because writing something like cairo_drawing_context
a lot can be tedious and hard to read.
Conky provides a lot of variables in conky.text
that will likely end up being useful from Lua code too. conky_parse
is used to evaluate Conky variables. It processes any text that can go into conky.text
and returns the evaluated result as a string.
Any Conky variable can be used:
cpu_usage = conky_parse("${cpu}")
memory_used = conky_parse("${memperc}")
disk_space = conky_parse("${fs_used /home}")
It can also evaluate more complex expressions:
network_status = conky_parse("${if_up wlan0}Online${else}Offline${endif}")
For this introduction, we'll be using updates
variable which simply returns the number of times conky has updated its window (redrawn contents). How often the draw function is called, i.e. the delay between updates depends on update_interval
setting.
In order to make conky print a message to the console after 5 updates, we can use something like:
local updates = tonumber(conky_parse("${updates}"))
if updates > 5 then
print("conky_main counted >5 updates to its window")
end
Lua function tonumber
simply parses the returned string value into a number. This will be necessary to handle numeric values correctly in most cases, so keep it in mind.
Most bindings require you to clean up resources at the end. Not doing so will cause conky to consume more and more memory over time (a memory leak), but other than that isn't really that dangerous.
cairo_destroy(c)
cairo_surface_destroy(cairo_surface)
When and what you need to clean up depends on what's being used. But for Cairo, the above functions should be called (with appropriate variables) at the end of the draw hooks.
Now that each part is explained, here is the complete script:
-- ~/.config/conky/script.lua
require("cairo")
require("cairo_xlib")
function conky_main()
if conky_window == nil then
return
end
local cairo_surface = cairo_xlib_surface_create(
conky_window.display,
conky_window.drawable,
conky_window.visual,
conky_window.width,
conky_window.height
)
local c = cairo_create(cairo_surface)
local updates = tonumber(conky_parse("${updates}"))
if updates > 5 then
print("conky_main counted >5 updates to its window")
end
cairo_destroy(c)
cairo_surface_destroy(cairo_surface)
end
This script checks the update count and prints debug information to the console after 5 updated. Not the most exciting thing in the world, but you're ready to level-up to more advanced topics now.
Happy scripting!
- Home
- Installation
- Configurations
- Window Configuration
- Configs
- FAQ
- Lua
- Variables
- Compatibility
- Using Lua scripts
- How to Load and Use Lua Scripts
- Essentials of Drawing
- Drawing Lines
- Drawing Rectangles, Circles and Arcs
- Making A Bar Meter and A Circle Meter
- Borders and If Statements
- Alarm Colors and Complex If Statements
- Functions
- Function Parameters
- Table Parameters
- For Loops and CPU Chart
- Clock and Circular Things
- Useful Functions and Code
- CLI Commands Timers and Line Editing
- Mouse Events
- Rendering an SVG with librsvg and Cairo
- Contributing
- Issue Reporting