This is an old revision of the document!
Table of Contents
Lua scripting
Lantern Terminal includes Lua 5.4.9 on Linux and Windows. Select Script → Run, choose a .lua file and supply any arguments. Logon scripts, saved script commands and –script also accept Lua. No separate Lua or Python installation is required.
local app = require("lantern").app local tab = app:GetScriptTab() tab.Screen:Send("printf '%s%s\\n' 'terminal-' 'ready'\r") assert(tab.Screen:WaitForString("terminal-ready", 5), "Endpoint did not respond") print(tab.Caption, tab.Screen.Rows, tab.Screen.Columns)
Use colon syntax for methods and dot syntax for properties. Split a test response across command arguments so the wait cannot match the echoed command itself. Each script stays attached to its originating tab when focus changes. A tab runs one script at a time. Script → Cancel terminates the worker and leaves the connection open. Output and tracebacks appear in Activity; errors open that pane automatically.
Application, arguments and tabs
app.Version,app.Arguments.Count,app.Arguments:GetArg(0); argument indexes are zero-based. Luaarg[0]is the script filename andarg[1]is the first argument;…contains the arguments too.app:GetScriptTab(),app:GetActiveTab(),app:GetTabCount(),app:GetTab(1)(one-based),app:GetProfiles(),app:Sleep(milliseconds),app:Quit().- Tab properties:
id,Caption(writable),Index(one-based),Screen,Session. - Tab methods:
Activate(),Clone(),Close(),ConnectSftp(),ResetCaption(). Clone and SFTP return a new tab.
Prefer GetScriptTab() for automation. GetActiveTab() deliberately targets the tab currently in focus.
Screen and prompt capture
Rows,Columns,CurrentRow,CurrentColumn,Selection,MatchIndexare read-only. Screen coordinates are one-based.Send(text)sends UTF-8 text through the session’s configured encoding.SendBytes(bytes)transmits the exact bytes, including NUL. Lua strings can hold binary data:screen:SendBytes(string.char(0, 255)).WaitForString(text, timeout, ignoreCase, milliseconds)returns a boolean.WaitForStrings({“ready”, “error”}, timeout, ignoreCase, milliseconds)returns a one-based match index or zero on timeout. The earliest incoming match wins; table order resolves ties.ReadString({“prompt> ”}, timeout, ignoreCase)returns text before the delimiter, excluding the delimiter, or an empty string on timeout.MatchIndexidentifies the delimiter.- Wait timeouts use seconds unless the optional
millisecondsflag is true. Zero or omitted timeout waits until a match, disconnection or cancellation.app:Sleepalways uses milliseconds. IgnoreCaseenables Unicode case-insensitive matching.IgnoreEscapestrips terminal escape sequences from captured text.Synchronousis always true; setting it false raises an error.Get2(top,left,bottom,right)preserves line separators;Get(…)concatenates the lines. Invalid coordinates raise an error.Clear(),WaitForCursor(timeout),SendKeys(text)andSendSpecial(action)provide terminal controls. SendKeys expands{ENTER},{TAB},{ESC},{UP},{DOWN},{LEFT}and{RIGHT}; other text remains literal. SendSpecial uses application action identifiers.
Sending marks the incoming stream before transmission, retaining immediate replies. Successful waits consume through the matched delimiter. Matching uses the incoming text stream, rather than repeatedly searching old screen contents. Disconnection, locked sessions and capture-buffer overflow raise errors. Use pcall or xpcall when a script needs to recover.
Sessions, configuration and logging
tab.Session exposes Connected, Status, Path (saved profile ID), Logging, LogFileName (writable) and Config.
session:Connect(profile)andConnectInTab(profile)open and return a new tab. Supply a saved profile ID string or a profile table.session:Disconnect()closes the connection.session:Log(true, append, raw)starts logging;Log(false)stops it. SetLogFileNamefirst.raw=truerecords received bytes.config:GetOption(key),SetOption(key,value)andSave()access typed profile settings. Examples includefontSize,logPath,host,port,keyFile.Save()persists a saved profile.config:ConnectInTab()clones the configured tab.
Clipboard and dialogs
app.Clipboard.Text reads/writes text. app.Dialog:MessageBox(text,title) shows a message; Prompt(text,title,default,password) returns text and a cancellation boolean. FileOpenDialog(title) returns the selected path or an empty string on cancellation. Dialogs run in the desktop application.
Files and Lua libraries
Standard Lua libraries are available. The entry script directory is added to package.path for local Lua modules. UTF-8 BOMs and an initial shebang are accepted. Use UTF-8 source and text strings.
For portable Unicode filenames, use the Qt-backed helpers:
local lantern = require("lantern") lantern.write_file("capture-café.txt", "saved bytes\0") local bytes = lantern.read_file("capture-café.txt")
These helpers preserve bytes, accept UTF-8 paths, cap each file at 16 MiB and raise errors on failure. Writes replace the file atomically. Ordinary Lua io functions follow the operating system’s filename conventions. Third-party binary Lua modules are not bundled.
Scripts execute with your user privileges, including standard Lua filesystem/process access. Run trusted code and review recordings for secrets. Do not embed passwords or key passphrases. The worker is a separate cancellable process, not a security sandbox.
Scripts written for SyncTERM-Lua
Scripts written for the SyncTERM 1.9 Lua scripting fork run unchanged. The first time a script uses one of its global names (send, expect, screen, regex, bbs and so on), Lantern loads a compatibility layer that provides them on top of the API above. Ordinary Lantern scripts are not affected, and the same file still runs in SyncTERM.
Supported: expect, expect_pattern, expect_regex (PCRE2), must_expect, waitfor, readline, quiet, sleep, idle, set_timeout, on/off triggers, send, sendln, screen, screen_size, cursor, buffer, clear, raw, connected, disconnect, quit, now, message, input, confirm, log/print, regex.find/regex.match, the before/matched globals, script_path and the bbs table. They behave as in SyncTERM: received text has ANSI codes and stray control characters removed before matching, expect uses up text up to its match, quiet(s) waits at least s seconds of silence counted from the call, and the script stops when the connection closes.
bbs.user,bbs.name,bbs.address,bbs.portandbbs.conn_typecome from the session (Username, name, Hostname, Port, Protocol).bbs.passwordis alwaysnil.- Set the session's Terminal → Appearance → Character encoding to CP437 for BBSes. The script then receives the BBS's original CP437 bytes, exactly as in SyncTERM.
- A script run as the session's logon script, or with
–scriptwhen opening a session, sees everything received since the connection started, like a SyncTERM dialing-directory script. A script started with Script → Run mid-session starts with an empty buffer, like SyncTERM's script hotkey. logandprintwrite to the Activity pane.message,inputandconfirmshow dialogs. For unattended runs, setsyncterm_answers = {confirm = {…}, input = {…}, message = {…}}before the first SyncTERM call; each question takes the next answer.
Recording and diagnostics
Script → Record captures outgoing sends. Save as .lua to generate a Lua replay or .py for Python. Recordings distinguish text from raw byte sends and omit recognised secret-prompt input. They do not infer expected prompts or detect every secret; add waits and review before saving/sharing.
The bundled lantern-lua –version reports the runtime. The application supplies its private local API connection to workers; launching an automation script directly without those details produces an explicit connection error. Low-level lantern.rpc(operation, tabId, values) is available for application API operations; prefer the documented facade for normal scripts. The broader SCRIPTING-API.md describes a larger feature contract, not a promise that all its members are implemented.
