This is an old revision of the document!
Table of Contents
Saltbush Terminal: scripting
Saltbush Terminal runs Python and Lua scripts. A script is attached to the tab it starts from and drives that session: it sends text, waits for prompts, reads the screen, changes settings, opens tabs, transfers files and shows dialogs.
- Script → Run… chooses a
.pyor.luafile and optional arguments. - Script → Cancel stops the current tab's script and leaves the connection open.
- Script → Start/Stop Recording records what you type and saves it as a Lua or Python script.
- Script → Activity shows script output and errors. Errors open it automatically. Select text with the mouse and press Ctrl+C to copy it (also while a script is writing), or right-click for Copy and Copy All; the Copy All button copies everything. Click the terminal again to type there.
- Session Options → Logon → Logon script runs a script whenever the session connects. A logon script sees everything received since the connection started; a script started with Script → Run starts with what arrives after it starts.
Python scripts run with the system python3; the saltbush module uses only the standard library and is supplied automatically. Lua 5.4 is built in, so no Lua installation is needed.
The interface is the same as Lantern Terminal's. Scripts written for Lantern (from lantern import app, require(“lantern”)) and scripts written for the SyncTERM-Lua fork run unchanged.
Python
from saltbush import app tab = app.GetScriptTab() tab.Screen.Send("printf '%s%s\\n' 'terminal-' 'ready'\r") if not tab.Screen.WaitForString("terminal-ready", 5): raise TimeoutError("Endpoint did not respond") print(tab.Caption, tab.Screen.Rows, tab.Screen.Columns)
Lua
local app = require("saltbush").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)
Lua uses colon syntax for methods and dot syntax for properties. arg[0] is the script file and arg[1] the first argument; … holds the arguments too. Lua's standard libraries are available, and the script's folder is on package.path.
Build test prompts from pieces, as above, so a wait does not match its own echoed command line.
Interface
Application
app.Version,app.Arguments.Count,app.Arguments.GetArg(0)(zero-based).app.GetScriptTab()(the tab the script started from),app.GetActiveTab(),app.GetTabCount(),app.GetTab(1)(one-based),app.GetProfiles()(Lua),app.Sleep(milliseconds),app.Quit().app.Clipboard.Text(read and write).app.Dialog.MessageBox(text, title),app.Dialog.Prompt(text, title, default, password)(Lua also returns a cancelled flag),app.Dialog.FileOpenDialog(title).
Tabs
- Properties:
id,Caption(writable),Index,Screen,Session. - Methods:
Activate(),Clone(),Close(),ConnectSftp(),ResetCaption(). - Zmodem:
ZmodemUpload(files)queues files that are sent when the host starts its Zmodem receiver (returns the number queued),ZmodemCancel(),ZmodemActive(). Downloads start by themselves.
Screen
Rows,Columns,CurrentRow,CurrentColumn(one-based),Selection,MatchIndex.Send(text)sends text in the session's character set.SendBytes(data)sends exact bytes.WaitForString(text, timeout, ignoreCase, milliseconds)returns true or false.WaitForStrings(list, …)returns the one-based index of the first match, or 0 on timeout.ReadString(list, timeout, ignoreCase)returns the text before the match.- Timeouts are in seconds unless
millisecondsis true; 0 waits until a match, a disconnect or cancellation. A disconnect while waiting raises an error. IgnoreCase,IgnoreEscape(strip escape sequences from captured text),Synchronous(always true).Get(top, left, bottom, right)andGet2(…)read part of the screen (Get2keeps line breaks).Clear(),WaitForCursor(timeout),SendKeys(“text{ENTER}”)({ENTER} {TAB} {ESC} {UP} {DOWN} {LEFT} {RIGHT}),SendSpecial(action)(actions as in Key Mappings: disconnect, reconnect, copy, paste, clear, log, break, find, next-tab, previous-tab).
Sending marks the received stream first, so a reply that arrives at once is still there for the next wait. A successful wait uses up the text up to its match.
Session and configuration
Connected(true once logged in),Status(Lua),Path(saved session id),Logging,LogFileName(writable),Config.Disconnect(),Connect(profile)andConnectInTab(profile)open a new tab from a saved session id or a table/dict of options,Log(enabled, append, raw).Config.GetOption(name),Config.SetOption(name, value),Config.Save()(saves a saved session),Config.ConnectInTab(). Option names are the setting names in the settings file (font_size,log_path,hostname…); Lantern's names (fontSize,logPath,host,keyFile…) also work.
SyncTERM-Lua scripts
The first time a Lua script uses one of the SyncTERM-Lua globals (send, sendln, expect, expect_pattern, expect_regex, must_expect, waitfor, readline, quiet, sleep, idle, set_timeout, on, off, screen, screen_size, cursor, buffer, clear, raw, connected, disconnect, quit, now, message, input, confirm, log, regex, bbs, before, matched, script_path), the compatibility layer is loaded. Received text has escape sequences removed (unless raw(true)), expect uses up text up to its match, the default timeout is 30 seconds and the script stops when the connection closes. On a CP437 session the script sees the BBS's original CP437 bytes. bbs.password is always nil. log and print write to the Activity pane.
Safety
Scripts run with your user's permissions. Each run of the program has a private connection (a socket in a folder only you can open, plus a random token passed to the scripts it starts); other users cannot drive your sessions. Do not put passwords in scripts, and review recordings before sharing them. Input typed at password prompts is not recorded.
