The TPU Editor, Rebuilt for Modern Systems


~/.tpurc startup files.
Everything DECTPU, with the modern parts you actually wanted.
Built-ins behave like the manual says. Where DECTPU was missing pieces, VX/TPU adds them — without losing the script-level compatibility you have under EVE.
Multi-window layout
Horizontal and vertical splits, per-window status lines, CREATE_WINDOW,
MAP/UNMAP, ADJUST_WINDOW, plus Ctrl-O
and Ctrl-N shortcuts.
Pattern engine
ANCHOR, ANY, NOTANY, ARB,
SCAN/SCANL, SPAN/SPANL,
LINE_BEGIN, LINE_END, PAGE_BREAK,
REMAIN, UNANCHOR. Composed with + and &.
Real key maps
CREATE_KEY_MAP, CREATE_KEY_MAP_LIST,
ADD_KEY_MAP, per-buffer
SET (KEY_MAP_LIST), GOLD prefix, custom shift key,
PRE/POST_KEY_PROCEDURE.
First-class types
PATTERN, RANGE, MARKER,
BUFFER, ARRAY, PROGRAM,
LEARN, PROCESS. Assign them, return them,
pass them to procedures.
Real language
IF/THEN/ELSE/ENDIF, LOOP/EXITIF/ENDLOOP,
PROCEDURE with parameters, LOCAL declarations,
ON_ERROR handlers, ! comments, -
line continuation.
FAO that works
Strings !AS, signed !SL, unsigned !UL,
hex !XL, octal !OL, binary !BL,
padded !nZL, plural !%S, date !%D,
time !%T.
Margins & wrap
SET (LEFT_MARGIN), SET (RIGHT_MARGIN),
SET (MARGINS), SET (TAB_STOPS),
SET (WRAP) with auto-wrap on type, tab-stop expansion
on Tab.
Mouse, timers, hooks
SET (MOUSE), LOCATE_MOUSE,
SET (TIMER, ms, "stmt"),
UNDEFINED_KEY, SHIFT_KEY.
External processes
CREATE_PROCESS("sort", out), SEND,
SEND_EOF, ATTACH. Output streams
non-blockingly into a buffer.
Journals & learn
JOURNAL_OPEN, JOURNAL_CLOSE,
RECOVER_BUFFER, LEARN_BEGIN,
LEARN_END returns a replayable LEARN value.
Headless test mode
tpu --test file.tpu runs your TPU code without the screen,
with built-in ASSERT, ASSERT_EQ, and
TEST sections. CI-friendly.
Linux · macOS · Windows
One C++17 file. ncurses on POSIX, PDCurses on Windows.
Tested under bash, zsh, and
PowerShell 7.
Undo / redo
Per-buffer 200-snapshot undo stack. UNDO,
REDO, plus GOLD-U / GOLD-R.
Read-only commands never invalidate the redo history.
Box selection
Rectangular selection: BOX SELECT,
BOX CUT, BOX COPY,
BOX PASTE. Renders as a real rectangle with the
same selection machinery.
Live incremental find
Ctrl-F jumps to the first hit as you type. Ctrl-F again advances; Esc restores the original cursor. No popup; the message line is the prompt.
System clipboard
WRITE_CLIPBOARD, READ_CLIPBOARD wrap
pbcopy/pbpaste,
wl-copy/wl-paste,
xclip/xsel, and the Win32 clipboard.
CALL_USER → dlopen
CALL_USER(symbol, arg [, library]) loads a shared
object (dlopen/LoadLibrary) and calls
const char* fn(const char*), returning the
result as a string.
Reload & backups
Captures file mtime on load. RELOAD /
CHECK_DISK detect on-disk changes. WRITE_FILE
renames the existing file to .bak first
(toggle with SET (BACKUP, OFF)).
Video regions
SET (VIDEO, range, BOLD|REVERSE|UNDERLINE|...)
paints ncurses attributes over a Range — the foundation for
syntax highlighting hooks driven from TPU code.
Persistent startup file
$TPU_STARTUP or ~/.tpurc is auto-COMPILEd
at boot. Bind keys, define procedures, set margins — all your
customisations load automatically.
Custom status lines
SET (STATUS_LINE, win, "TEXT", " %n %m %l/%t :%c %d ")
— %n name, %f file, %l/%t
line/total, %c column, %m modified,
%i insert mode, %d direction.
Numeric base literals
Real DECTPU numeric literals: %X1A,
%XFF, %O17, %B1010,
%D42. Mix with the standard decimal literals.
Help in many shapes
Inside the editor, HELP opens a system buffer.
From a script, HELP_TEXT(topic) returns the body
as a string. 17 topic sections.
MESSAGE_BUFFER scrollback
Every MESSAGE appends to
$MESSAGE_BUFFER, capped at 1000 lines. Visit it
with BUFFER $MESSAGE_BUFFER to see history.
Compile-time errors
Each Stmt carries its source line. Unknown commands report
"Unknown command: foo (line 27)"; missing
ENDPROCEDURE is recorded in
parser.compile_diagnostics.
SHOW everything
SHOW BUFFERS, KEYMAPS,
KEY_MAP_LISTS, PROCEDURES,
VARIABLES, DEFAULTS,
SUMMARY, SYSTEM,
KEY [name].
"Drop-in DECTPU built-ins, real first-class values, and a multi-window ncurses screen — in a single C++ file."
A faithful TPU you can hack on.
Command-line commands
Everything below is callable after pressing Ctrl-Z in the editor, or programmatically from a TPU procedure.
In this section
Files
| Command | Description |
|---|---|
| WRITE [file] | Save the current buffer |
| SAVE FILE | Save the current buffer |
| GET file | Open file in a new buffer |
| INCLUDE file | Insert file at cursor |
| EXIT / QUIT | Leave the editor |
| SPAWN cmd | Suspend the editor and run a shell command |
Movement & Buffers
| Command | Description |
|---|---|
| TOP / BOTTOM / END | Buffer top / bottom |
| GO TO n | Jump to line n |
| GO TO COLUMN n | Jump to column n |
| WHAT LINE / WHAT BUFFER | Report current state / list buffers |
| NEXT BUFFER / PREVIOUS BUFFER | Rotate buffers |
| BUFFER name | Switch / create |
| RELOAD / CHECK_DISK | Reload from disk / check mtime |
Editing
| Command | Description |
|---|---|
| SELECT / SELECT_RANGE | Start / inspect a range |
| COPY / CUT / PASTE | Internal clipboard register |
| READ_CLIPBOARD / WRITE_CLIPBOARD | System clipboard (pbcopy / xclip / Win32) |
| DELETE / REMOVE / RESTORE | Selection-aware delete & paste-back |
| BOX SELECT / BOX CUT / BOX COPY / BOX PASTE | Rectangular selection |
| UNDO / REDO | 200-snapshot history per buffer |
| FILL | Fill SELECT_RANGE within margins |
| SHIFT LEFT|RIGHT [n] | Shift all lines |
| CHANGE CASE UPPER|LOWER | On the selection or the current word |
| ERASE_LINE / ERASE_CHARACTER n | Delete by line or by character |
Search
| Command | Description |
|---|---|
| FIND text | Forward literal search |
Ctrl-F | Live incremental find (jumps as you type) |
| SEARCH pat | Pattern search; matches across newlines |
| SEARCH(pat, REVERSE) | Force reverse direction |
| SEARCH_QUIETLY pat | Search without status message |
| REPLACE | Prompt for old & new text |
| SET (FORWARD) / SET (REVERSE) | Default search direction |
Buffers & SET
| Command | Description |
|---|---|
| SET INSERT / OVERSTRIKE | Text-entry mode |
| SET MODIFIED|MODIFIABLE | Buffer flags |
| SET NO_WRITE / PERMANENT / SYSTEM | Protection flags |
| SET MAX_LINES n | Cap buffer length |
| SET EOB_TEXT s | Text past last line (default [End of file]) |
| SET JOURNALING file | Append commands to a journal |
| SET (BACKUP, ON|OFF) | Rename existing file to .bak on save |
| SET (KEY_MAP_LIST, name [, buf]) | Per-buffer key-map list |
| SET (VIDEO, range, BOLD|REVERSE|...) | Paint ncurses attributes over a range |
| SET (STATUS_LINE, win, "TEXT", fmt) | Custom per-window status format |
| SHOW BUFFERS|KEYMAPS|PROCEDURES|VARIABLES|DEFAULTS|SUMMARY|SYSTEM|KEY [name] | Open a system buffer with a tabular report |
Margins, Tabs & Events
| Command | Description |
|---|---|
| SET LEFT MARGIN n | Insert column for new lines |
| SET RIGHT MARGIN n | Wrap column |
| SET MARGINS lr | Combined |
| SET TAB STOPS n… | Custom tab columns |
| SET (WRAP, ON|OFF) | Auto-wrap on type |
| SET LINE NUMBER | Toggle the gutter |
| SET (MOUSE, ON|OFF) | Enable mouse events |
| SET (TIMER, ms, "stmt") | Run TPU statement on a timer |
| SET (PRE_KEY_PROCEDURE, "stmt") | Run before each key |
| SET (POST_KEY_PROCEDURE, "stmt") | Run after each key |
| SET (UNDEFINED_KEY, "stmt") | Hook for unbound keys |
| SET (SHIFT_KEY, key) | Secondary GOLD-style prefix |
Windows
| Command | Description |
|---|---|
| CREATE_WINDOW(top, h [, status]) | New viewport |
| MAP(win, buf) / UNMAP(win) | Attach / detach a buffer |
| ADJUST_WINDOW(win, dtop, dbot) | Resize |
| SPLIT_WINDOW | Horizontal split (Ctrl-O) |
| SPLIT_WINDOW_VERTICAL | Side-by-side split |
| NEXT_WINDOW | Rotate focus (Ctrl-N) |
| DELETE_WINDOW | Remove the current window |
Process & Misc
| Command | Description |
|---|---|
| SPAWN cmd / DCL cmd | Suspend, run shell command |
| CREATE_PROCESS("cmd", outbuf) | Spawn child with pipes |
| SEND(text [, proc]) | Write to child stdin |
| SEND_EOF | Close child stdin |
| JOURNAL_OPEN file / JOURNAL_CLOSE | Append every statement to a journal |
| RECOVER_BUFFER [file] | Replay a journal |
| LEARN_BEGIN / LEARN_END | Record / capture replayable sequence |
| CALL_USER(sym, arg [, lib]) | dlopen / LoadLibrary callout |
| HELP [topic] / HELP_TEXT(topic) | 17 topics; both buffer + string forms |
Default key bindings
Every binding is a KEY_MAP entry — they're shown here in the default TPU$KEY_MAP_LIST. Override with DEFINE_KEY or per-buffer SET (KEY_MAP_LIST).
| Key | Action |
|---|---|
| ↑↓←→ | MOVE_VERTICAL / MOVE_HORIZONTAL |
| Home / End | Line begin / line end |
| PgUp / PgDn | Scroll a screen |
| Backspace / Del | ERASE_CHARACTER (-1 / +1) |
| Insert | Toggle INSERT / OVERSTRIKE |
| Tab | Insert tab (uses TAB_STOPS) |
| Enter | SPLIT_LINE |
| Key | Action |
|---|---|
| Ctrl-Z | Command line |
| Ctrl-S | WRITE_FILE |
| Ctrl-X | EXIT |
| Ctrl-F | SEARCH / live incremental find |
| Ctrl-V | SELECT |
| Ctrl-W | MOVE_TEXT (cut) |
| Ctrl-Y | Paste |
| Ctrl-O | SPLIT_WINDOW |
| Ctrl-N | NEXT_WINDOW |
| Key | Action |
|---|---|
| PF1 / F1 | GOLD prefix |
| GOLD+T | Top of buffer |
| GOLD+E | End of buffer |
| GOLD+F | Find |
| GOLD+W | Write file |
| GOLD+Q | Quit |
| Key | Action |
|---|---|
| F2 | HELP buffer |
| F3 | FIND |
| F4 | DELETE |
| F6–F12 | Available for DEFINE_KEY |
| PF1–PF4 | VT-style numeric keypad |
The TPU language, made real
Variables, expressions, control flow, error handling, procedures with parameters, and the full DECTPU object model — including arrays and compiled programs as values.
! Search backwards from the cursor for a comment, capitalize it, ! and bail out gracefully if there is no match. PROCEDURE upcase_prev_comment LOCAL pat := LINE_BEGIN + "!" + REMAIN; ON_ERROR MESSAGE("no comment found above"); RETURN; ENDON_ERROR; SET (REVERSE, CURRENT_BUFFER); LOCAL r := SEARCH(pat); IF NOT r THEN ABORT; ENDIF; CHANGE_CASE(r, UPPER); POSITION(r); MESSAGE("done"); ENDPROCEDURE; ! And as a compiled program value: prog := COMPILE("MESSAGE(\"hello, \" + CURRENT_BUFFER);"); EXECUTE(prog); ! Arrays: counts := CREATE_ARRAY; counts{"hits"} := counts{"hits"} + 1;
One file. Three platforms.
VX/TPU is a single C++17 source. Pick your toolchain.
macOS / Clang
brew install ncurses clang++ -std=c++17 -O2 tpu.cpp -lncurses -o tpu ./tpu file.txt
Linux / GCC
sudo apt install libncurses-dev g++ -std=c++17 -O2 tpu.cpp -lncurses -o tpu ./tpu file.txt
Windows / MSVC + PDCurses
cl /std:c++17 /EHsc tpu.cpp ^ /I C:\pdcurses ^ C:\pdcurses\wincon\pdcurses.lib # In PowerShell: ./tpu.exe file.txt ./tpu.exe --test tests\tpu_tests.tpu
Run the regression suite
./run_tests.sh ==> Building tpu ==> Running tpu_tests.tpu PASS 1+2 PASS string concat PASS FAO !4ZL pad ... ---------------------------------------- 61 passed, 0 failed
Frequently Asked Questions
Curious about how Sector7 can facilitate your application migration? Explore our FAQs for expert insights.
Transform Your Legacy Software Today!
