====== 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. Lua ''arg[0]'' is the script filename and ''arg[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. * Zmodem: ''tab:ZmodemUpload({path, ...})'' queues files that are sent when the host starts its Zmodem receiver (returns the number queued), ''tab:ZmodemCancel()'' stops a transfer, ''tab:ZmodemActive()'' is true while one runs. Downloads start by themselves. Prefer ''GetScriptTab()'' for automation. ''GetActiveTab()'' deliberately targets the tab currently in focus. ===== Screen and prompt capture ===== * ''Rows'', ''Columns'', ''CurrentRow'', ''CurrentColumn'', ''Selection'', ''MatchIndex'' are 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. ''MatchIndex'' identifies the delimiter. * Wait timeouts use seconds unless the optional ''milliseconds'' flag is true. Zero or omitted timeout waits until a match, disconnection or cancellation. ''app:Sleep'' always uses milliseconds. * ''IgnoreCase'' enables Unicode case-insensitive matching. ''IgnoreEscape'' strips terminal escape sequences from captured text. ''Synchronous'' is 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)'' and ''SendSpecial(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)'' and ''ConnectInTab(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. Set ''LogFileName'' first. ''raw=true'' records received bytes. * ''config:GetOption(key)'', ''SetOption(key,value)'' and ''Save()'' access typed profile settings. Examples include ''fontSize'', ''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.port'' and ''bbs.conn_type'' come from the session (Username, name, Hostname, Port, Protocol: ''Telnet'', ''RLogin'', ''SSH2'', ''Raw TCP''). ''bbs.password'' is always ''nil''. * 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 ''--script'' when 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. * ''log'' and ''print'' write to the Activity pane. ''message'', ''input'' and ''confirm'' show dialogs. For unattended runs, set ''syncterm_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. [[lanternterminal:start|Back to Lantern Terminal]]