Skip to content

Lua Scripting

VisiGrid includes a sandboxed Lua console for automating tasks and manipulating data programmatically. All operations are transactional and fully undoable.

Press Ctrl+Shift+L to toggle the Lua console panel. On first open, the input is pre-filled with examples — press Enter to see available scripts.

┌─────────────────────────────────────────┐
│ > sheet:get("A1") │
│ 42 │
│ > for r = 1, 10 do │
│ ... sheet:set("A" .. r, r * 2) │
│ ... end │
│ nil │
│ ops: 10 | cells: 10 | time: 1.2ms │
│ > │
│ Ctrl+Enter to run · Undo reverses the entire script │
└─────────────────────────────────────────┘

Type these directly in the input:

CommandDescription
helpShow all commands and shortcuts
examplesList available example scripts
example NLoad example N into input
clearClear output history
#NameDescription
1Fill SeriesFill A1:A10 with powers of 2
2Trim WhitespaceRemove leading/trailing spaces from column A
3Find DuplicatesFind and report duplicate values in column A
4Normalize DatesConvert date formats to YYYY-MM-DD
5Compare ColumnsFind mismatches between columns A and B
6Generate Multiplication TableCreate 10x10 table starting at A1
7Sum ColumnCalculate sum and average of numbers in column A

Load any example: example 1 or example "Fill Series"

All coordinates are 1-indexed to match spreadsheet conventions.

MethodDescription
sheet:get("A1")Get value using A1 notation (shorthand)
sheet:set("A1", val)Set value using A1 notation (shorthand)
sheet:get_value(row, col)Get typed value by row/col
sheet:set_value(row, col, val)Set cell value
sheet:get_formula(row, col)Get formula string or nil
sheet:set_formula(row, col, f)Set formula
MethodDescription
sheet:rows()Number of rows with data
sheet:cols()Number of columns with data
sheet:selection()Current selection (see below)
local sel = sheet:selection()
print(sel.range) -- "A1:C5"
print(sel.start_row) -- 1
print(sel.start_col) -- 1
print(sel.end_row) -- 5
print(sel.end_col) -- 3
local r = sheet:range("A1:C5")
-- Read all values as 2D table
local data = r:values()
print(data[1][1]) -- value at A1
print(data[2][3]) -- value at C2
-- Write 2D table to range
r:set_values({
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
})
-- Range info
r:rows() -- → 5
r:cols() -- → 3
r:address() -- → "A1:C5"
MethodDescription
sheet:begin()Start transaction (noop, for clarity)
sheet:rollback()Discard pending changes, returns count
sheet:commit()Commit changes (noop, auto-commits at end)
-- Fill column with sequence
for i = 1, 100 do
sheet:set("A" .. i, i * 2)
end
print("Filled 100 cells")
-- Process current selection
local sel = sheet:selection()
for row = sel.start_row, sel.end_row do
for col = sel.start_col, sel.end_col do
local val = sheet:get_value(row, col)
if type(val) == "number" then
sheet:set_value(row, col, val * 1.1) -- +10%
end
end
end
-- Bulk transform with Range
local r = sheet:range("A1:C10")
local data = r:values()
for i, row in ipairs(data) do
for j, val in ipairs(row) do
if type(val) == "number" then
data[i][j] = val * 2
end
end
end
r:set_values(data)
-- Conditional rollback
sheet:begin()
for i = 1, 100 do
sheet:set("A" .. i, math.random(1, 100))
end
local sum = 0
for i = 1, 100 do
sum = sum + (sheet:get("A" .. i) or 0)
end
if sum > 5000 then
local discarded = sheet:rollback()
print("Rolled back " .. discarded .. " ops (sum too high)")
else
print("Sum: " .. sum)
end
ActionShortcut
Toggle consoleCtrl+Shift+L
Execute scriptEnter or Ctrl+Enter
Newline (multiline)Shift+Enter
Previous commandUp Arrow
Next commandDown Arrow
Scroll output upPage Up
Scroll output downPage Down
Scroll to topCtrl+Home
Scroll to bottomCtrl+End
Clear outputCtrl+L
Close consoleEscape

After each script runs, the console shows:

ops: 100 | cells: 50 | time: 12.5ms
  • ops: Total operations queued
  • cells: Unique cells modified (deduplicated)
  • time: Wall-clock execution time

Enabled Libraries: table, string, math, utf8

Disabled (for security): os, io, debug, package, require, load, loadfile, dofile

LimitValue
Operations1,000,000
Output lines5,000
Instructions100,000,000
Wall-clock30 seconds
  • No filesystem or network access
  • Single undo entry per script (Ctrl+Z reverses entire script)
  • Deterministic execution (same input = same output)