Lua Scripting
VisiGrid includes a sandboxed Lua console for automating tasks and manipulating data programmatically. All operations are transactional and fully undoable.
Opening the Console
Section titled “Opening the Console”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 │└─────────────────────────────────────────┘Console Commands
Section titled “Console Commands”Type these directly in the input:
| Command | Description |
|---|---|
help | Show all commands and shortcuts |
examples | List available example scripts |
example N | Load example N into input |
clear | Clear output history |
Built-in Examples
Section titled “Built-in Examples”| # | Name | Description |
|---|---|---|
| 1 | Fill Series | Fill A1:A10 with powers of 2 |
| 2 | Trim Whitespace | Remove leading/trailing spaces from column A |
| 3 | Find Duplicates | Find and report duplicate values in column A |
| 4 | Normalize Dates | Convert date formats to YYYY-MM-DD |
| 5 | Compare Columns | Find mismatches between columns A and B |
| 6 | Generate Multiplication Table | Create 10x10 table starting at A1 |
| 7 | Sum Column | Calculate sum and average of numbers in column A |
Load any example: example 1 or example "Fill Series"
Sheet API
Section titled “Sheet API”All coordinates are 1-indexed to match spreadsheet conventions.
Cell Access
Section titled “Cell Access”| Method | Description |
|---|---|
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 |
Sheet Info
Section titled “Sheet Info”| Method | Description |
|---|---|
sheet:rows() | Number of rows with data |
sheet:cols() | Number of columns with data |
sheet:selection() | Current selection (see below) |
Selection API
Section titled “Selection API”local sel = sheet:selection()print(sel.range) -- "A1:C5"print(sel.start_row) -- 1print(sel.start_col) -- 1print(sel.end_row) -- 5print(sel.end_col) -- 3Range API (Bulk Read/Write)
Section titled “Range API (Bulk Read/Write)”local r = sheet:range("A1:C5")
-- Read all values as 2D tablelocal data = r:values()print(data[1][1]) -- value at A1print(data[2][3]) -- value at C2
-- Write 2D table to ranger:set_values({ {1, 2, 3}, {4, 5, 6}, {7, 8, 9}})
-- Range infor:rows() -- → 5r:cols() -- → 3r:address() -- → "A1:C5"Transaction Control
Section titled “Transaction Control”| Method | Description |
|---|---|
sheet:begin() | Start transaction (noop, for clarity) |
sheet:rollback() | Discard pending changes, returns count |
sheet:commit() | Commit changes (noop, auto-commits at end) |
Example Scripts
Section titled “Example Scripts”-- Fill column with sequencefor i = 1, 100 do sheet:set("A" .. i, i * 2)endprint("Filled 100 cells")-- Process current selectionlocal 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 endend-- Bulk transform with Rangelocal 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 endend
r:set_values(data)-- Conditional rollbacksheet:begin()for i = 1, 100 do sheet:set("A" .. i, math.random(1, 100))end
local sum = 0for 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)endKeyboard Shortcuts
Section titled “Keyboard Shortcuts”| Action | Shortcut |
|---|---|
| Toggle console | Ctrl+Shift+L |
| Execute script | Enter or Ctrl+Enter |
| Newline (multiline) | Shift+Enter |
| Previous command | Up Arrow |
| Next command | Down Arrow |
| Scroll output up | Page Up |
| Scroll output down | Page Down |
| Scroll to top | Ctrl+Home |
| Scroll to bottom | Ctrl+End |
| Clear output | Ctrl+L |
| Close console | Escape |
Execution Stats
Section titled “Execution Stats”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
Sandboxing and Safety
Section titled “Sandboxing and Safety”Enabled Libraries: table, string, math, utf8
Disabled (for security): os, io, debug, package, require, load, loadfile, dofile
Resource Limits
Section titled “Resource Limits”| Limit | Value |
|---|---|
| Operations | 1,000,000 |
| Output lines | 5,000 |
| Instructions | 100,000,000 |
| Wall-clock | 30 seconds |
Safety Guarantees
Section titled “Safety Guarantees”- No filesystem or network access
- Single undo entry per script (Ctrl+Z reverses entire script)
- Deterministic execution (same input = same output)