I was having a hard time understanding the structure of the Lua environment, so I built a tool to help me easily explore Global variables and functions in Codea. It lets you easily navigate through the Global Environment _ENV
using the parameters panel. It also lets you see the current value of global variables you have set.
It really helped me understand Codea and Lua, and also helped with debugging some of my apps as well. So, I thought I should share.
I feel like I am grossly abusing the parameters and output panel, but it was easier than creating an overlay and buttons. If you are using parameters in your app then it will overwrite them. I found it useful to start a new project and just explore. Setup is simple; just paste the code in a blank file and run your project. If you feel your global variable is missing from the list, press “Refresh List”.
I hope this is of some use to someone.
Edit: Added support for non-key tables.
Edit 2: After playing around with this to make sure the code was ok and fixing some small mistakes. I noticed an added bonus of using the parameter’s area for debug; it still works when the app is paused using Codea’s pause button! Also, added cleaner menu and hiding of CONSTANTS.
Edit 3: Made current path to variable more clear and visible
Edit 4: I added Live Viewing/Watching of the currently selected variable. Test it out by choosing ElapsedTime.
--[[
Debug Tool for viewing and exploring all Global Variables
## Usage:
- Load this project as a dependency or copy this code to a blank lua file in your project.
- This is a tool I made to help me learn Lua better and explore the environment.
- If a variable is a table then ">>" will be by its name. Click the button to go deeper.
- If a variable is a function then "-> f()" will be by its name. Click for function debug info.
- Clicking any variable will give more information in the output area.
- The output is copied to the clipboard as well.
- Choose a variable to Live View it and/or press again to get a current snapshot in output.
- The app can be paused and still allow viewing
- Turn on Copy Output to Clipboard, the next variable pressed will have its value copied to clipboard.
## Warnings:
- All parameters you have set or are using will be erased.
- Local variables are not visible
- Table _G is just repeating into itself.
--]]
function viewEnv(pathKeys, showConstants, varKey)
local pathKeys = pathKeys or {_ENV}
parameter.clear()
-- Button to Select between hiding or showing constants
local c = "Hiding"
if showConstants then c = "Showing" end
parameter.boolean("Copy_Output_to_Clipboard", false)
parameter.action(string.format("[ %s Constants ]", c),
function ()
viewEnv(pathKeys, not showConstants)
end
)
-- Button to Refresh Variable or Check for new ones
parameter.action("[ Refresh Variables ]",
function ()
viewEnv(pathKeys, showConstants)
end
)
-- Button to move out of the current table
if #pathKeys > 1 then
parameter.action("[ << BACK ]",
function ()
table.remove(pathKeys, #pathKeys)
viewEnv(pathKeys, showConstants)
end
)
end
-- Get Current Path to Variable List
local path = "_ENV"
local spacer = " > "
for i = 2, #pathKeys do
path = path .. spacer .. tostring(pathKeys[i])
end
parameter.watch("_Path_"); _Path_ = path
local _liveVariable = "_ENV"
local function setLiveVariable(l, v)
if type(l) ~= "function" then
if #l > 0 then
_liveVariable = string.format("%s[%s]", _liveVariable, v)
else
_liveVariable = string.format('%s["%s"]', _liveVariable, v)
end
end
end
-- Find current table from pathKey list
local loc = pathKeys[1]
for i = 2, #pathKeys do
setLiveVariable(loc, pathKeys[i])
loc = loc[pathKeys[i]]
end
if type(loc) ~= "function" and varKey then
setLiveVariable(loc, varKey)
parameter.action(string.format("Live Viewing: [%s]", varKey))
parameter.watch(_liveVariable)
end
-- Allow exploring functions
if type(loc) == "function" then
loc = debug.getinfo(loc)
loc.func = nil
end
local keys = {}
local tableType = "Key: "
-- Check if array or key table
if #loc > 0 then
tableType = "Index: "
for i = 1, #loc do
table.insert(keys, i)
end
else
-- Convert keys to strings to sort alphabetically
for k, _ in pairs(loc) do
k = tostring(k)
if (not showConstants and k ~= string.upper(k)) or showConstants then
table.insert(keys, k)
end
end
table.sort(keys, function (a, b) return string.lower(a) < string.lower(b) end)
end
-- Create the buttons for the variable
for _, k in ipairs(keys) do
local title = k
-- Check if it is a table or function and allow going deeper
if type(loc[k]) == "table" then
title = k .. " >>"
elseif type(loc[k]) == "function" then
title = k .. " -> f()"
end
parameter.action(title,
function()
output.clear()
local t = type(loc[k])
local v = tostring(loc[k])
print(tableType .. k)
print("Value: " .. v)
-- Copy Value to clipboard
if Copy_Output_to_Clipboard then
pasteboard.copy(v)
print("Output value has been copied to the clipboard.")
end
if t == "table" or t == "function" then
table.insert(pathKeys, k)
viewEnv(pathKeys, showConstants)
else
viewEnv(pathKeys, showConstants, k)
end
end
)
end
end
-- Auto Run the Environment Viewer
viewEnv()