internal/skills/content/lua-guide/SKILL.md
Lua language guardrails, patterns, and best practices for AI-assisted development. Use when working with Lua files (.lua), or when the user mentions Lua/LuaJIT/Neovim/Love2D. Provides table patterns, metatable guidelines, coroutine usage, and embedding conventions specific to this project's coding standards.
npx skillsauth add ar4mirez/samuel lua-guideInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Applies to: Lua 5.4+, LuaJIT 2.1, Neovim Plugins, Love2D, Embedded Scripting
local; globals are a performance and correctness hazardpcall/xpcall for recoverable errors; error() for programmer mistakeslocal for every variable and function unless it must be globalsnake_case for variables/functions, PascalCase for class-like tables, UPPER_SNAKE_CASE for constants[[ ... ]] long strings for multi-line text and SQL/HTML templates#tbl over table.getn() for sequence lengthfor i = 1, #arr not for i = 0, #arr - 1ipairs for sequential iteration, pairs for hash-map iteration# behavior)table.insert / table.remove for array ops; avoid manual index gaps__newindex metamethod that errorspcall(fn, ...) to catch errors; xpcall(fn, handler, ...) for tracebacksnil, err_msg from functions that can fail (idiomatic two-value return)error("msg", level) for violated preconditions (programmer errors)local function read_config(path)
local f, err = io.open(path, "r")
if not f then return nil, "cannot open config: " .. err end
local content = f:read("*a")
f:close()
return content
end
local ok, result = xpcall(dangerous_operation, debug.traceback)
if not ok then log.error("failed: %s", result) end
local insert = table.inserttable.concat instead of .. concatenation in loopspairs() in hot paths (not JIT-compiled); prefer arrays with ipairsffi.new, ffi.cast) for C struct access instead of Lua tableslua_setallocf or lua_gc configurationdebug.sethook instruction-count hooks for untrusted scriptslocal M = {}
local TIMEOUT_MS = 5000
local function validate(data)
assert(type(data) == "table", "expected table, got " .. type(data))
assert(data.name, "missing required field: name")
end
function M.process(data)
validate(data)
return { status = "ok", name = data.name }
end
return M
local Animal = {}
Animal.__index = Animal
function Animal.new(name, sound)
return setmetatable({ name = name, sound = sound }, Animal)
end
function Animal:speak()
return string.format("%s says %s", self.name, self.sound)
end
-- Inheritance
local Dog = setmetatable({}, { __index = Animal })
Dog.__index = Dog
function Dog.new(name)
return setmetatable(Animal.new(name, "woof"), Dog)
end
function Dog:fetch(item)
return string.format("%s fetches the %s", self.name, item)
end
local function producer(items)
return coroutine.wrap(function()
for _, item in ipairs(items) do
coroutine.yield(item)
end
end)
end
local function filter(predicate, iter)
return coroutine.wrap(function()
for item in iter do
if predicate(item) then coroutine.yield(item) end
end
end)
end
local nums = producer({ 1, 2, 3, 4, 5, 6 })
local evens = filter(function(n) return n % 2 == 0 end, nums)
for v in evens do print(v) end --> 2, 4, 6
local function range(start, stop, step)
step = step or 1
local i = start - step
return function()
i = i + step
if i <= stop then return i end
end
end
for n in range(1, 10, 2) do print(n) end --> 1, 3, 5, 7, 9
local api, keymap = vim.api, vim.keymap
local M = {}
function M.setup(opts)
opts = vim.tbl_deep_extend("force", { enabled = true, width = 80 }, opts or {})
if not opts.enabled then return end
local group = api.nvim_create_augroup("MyPlugin", { clear = true })
api.nvim_create_autocmd("BufWritePre", {
group = group, pattern = "*.lua",
callback = function(ev)
local lines = api.nvim_buf_get_lines(ev.buf, 0, -1, false)
for i, line in ipairs(lines) do lines[i] = line:gsub("%s+$", "") end
api.nvim_buf_set_lines(ev.buf, 0, -1, false, lines)
end,
})
keymap.set("n", "<leader>mp", function()
vim.notify("MyPlugin activated", vim.log.levels.INFO)
end, { desc = "Activate MyPlugin" })
end
return M
local mymodule = require("mymodule")
describe("mymodule.process", function()
it("returns ok for valid input", function()
local result = mymodule.process({ name = "test" })
assert.are.equal("ok", result.status)
end)
it("raises on missing name", function()
assert.has_error(function() mymodule.process({}) end, "missing required field: name")
end)
end)
spec/*_spec.lua (busted) or test_*.lua (luaunit)it("returns nil when file not found")nil, empty tables, boundary values, type mismatchesbusted --verbose-- .luacheckrc
std = "lua54+busted" -- or "luajit+busted"
globals = { "vim" } -- for Neovim plugins
max_line_length = 120
max_cyclomatic_complexity = 10
# stylua.toml
column_width = 100
indent_type = "Spaces"
indent_width = 2
quote_style = "AutoPreferDouble"
call_parentheses = "Always"
lua myfile.lua # Run Lua script
luajit myfile.lua # Run with LuaJIT
busted --verbose # Run tests
luacheck . # Lint
stylua . # Format
luarocks install busted # Install test framework
luarocks install luacheck # Install linter
For detailed patterns and examples, see:
development
Zig language guardrails, patterns, and best practices for AI-assisted development. Use when working with Zig files (.zig), build.zig, or when the user mentions Zig. Provides comptime patterns, allocator conventions, C interop guidelines, and testing standards specific to this project's coding standards.
tools
WordPress framework guardrails, patterns, and best practices for AI-assisted development. Use when working with WordPress projects, or when the user mentions WordPress. Provides theme development, plugin architecture, REST API, blocks, and security guidelines.
tools
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs. Use when testing web apps, automating browser interactions, or debugging frontend issues.
tools
Suite of tools for creating elaborate, multi-component web applications using modern frontend technologies (React, Tailwind CSS, shadcn/ui). Use for complex projects requiring state management, routing, or shadcn/ui components - not for simple single-file HTML/JSX pages.