🚨 Oracle not porting Rdb to x86 and EOL on Itanium 12/2027 🚨

The DEC TPU Editor,
Rebuilt for Modern Systems

Faithful DEC OpenVMS EDT for Linux and macOS: DECTPU/EVE behavior in one portable C++ editor: split windows, fast search, undo/redo, box select, clipboard, and first-class TPU types.
tpu β€” notes.txt
$ ./tpu notes.txt
────────────────────────────── notes.txt ──────────────────────────────
LOOP
  EXITIF CURRENT_ROW > 10;
  IF CURRENT_LINE = "" THEN ERASE_LINE; ELSE MOVE_VERTICAL(1); ENDIF;
ENDLOOP;
[EOB]
notes.txt  *  Modified  INSERT  3/27 :12
Ctrl-Z command, Ctrl-X EXIT, F2 or HELP for help
VX/TPU 1.1 β€” 84-test regression suite passing on macOS, Linux, and Windows. Full DECTPU built-in surface plus undo, box selection, incremental find, system clipboard, and ~/.tpurc startup files.
Capabilities

Everything DEC TPU, 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.

Reference

Command-line commands

Everything below is callable after pressing Ctrl-Z in the editor, or programmatically from a TPU procedure.

Files

CommandDescription
WRITE [file]Save the current buffer
SAVE FILESave the current buffer
GET fileOpen file in a new buffer
INCLUDE fileInsert file at cursor
EXIT / QUITLeave the editor
SPAWN cmdSuspend the editor and run a shell command

Movement & Buffers

CommandDescription
TOP / BOTTOM / ENDBuffer top / bottom
GO TO nJump to line n
GO TO COLUMN nJump to column n
WHAT LINE / WHAT BUFFERReport current state / list buffers
NEXT BUFFER / PREVIOUS BUFFERRotate buffers
BUFFER nameSwitch / create
RELOAD / CHECK_DISKReload from disk / check mtime

Editing

CommandDescription
SELECT / SELECT_RANGEStart / inspect a range
COPY / CUT / PASTEInternal clipboard register
READ_CLIPBOARD / WRITE_CLIPBOARDSystem clipboard (pbcopy / xclip / Win32)
DELETE / REMOVE / RESTORESelection-aware delete & paste-back
BOX SELECT / BOX CUT / BOX COPY / BOX PASTERectangular selection
UNDO / REDO200-snapshot history per buffer
FILLFill SELECT_RANGE within margins
SHIFT LEFT|RIGHT [n]Shift all lines
CHANGE CASE UPPER|LOWEROn the selection or the current word
ERASE_LINE / ERASE_CHARACTER nDelete by line or by character

Buffers & SET

CommandDescription
SET INSERT / OVERSTRIKEText-entry mode
SET MODIFIED|MODIFIABLEBuffer flags
SET NO_WRITE / PERMANENT / SYSTEMProtection flags
SET MAX_LINES nCap buffer length
SET EOB_TEXT sText past last line (default [End of file])
SET JOURNALING fileAppend 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

CommandDescription
SET LEFT MARGIN nInsert column for new lines
SET RIGHT MARGIN nWrap column
SET MARGINS lrCombined
SET TAB STOPS n…Custom tab columns
SET (WRAP, ON|OFF)Auto-wrap on type
SET LINE NUMBERToggle 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

CommandDescription
CREATE_WINDOW(top, h [, status])New viewport
MAP(win, buf) / UNMAP(win)Attach / detach a buffer
ADJUST_WINDOW(win, dtop, dbot)Resize
SPLIT_WINDOWHorizontal split (Ctrl-O)
SPLIT_WINDOW_VERTICALSide-by-side split
NEXT_WINDOWRotate focus (Ctrl-N)
DELETE_WINDOWRemove the current window

Process & Misc

CommandDescription
SPAWN cmd / DCL cmdSuspend, run shell command
CREATE_PROCESS("cmd", outbuf)Spawn child with pipes
SEND(text [, proc])Write to child stdin
SEND_EOFClose child stdin
JOURNAL_OPEN file / JOURNAL_CLOSEAppend every statement to a journal
RECOVER_BUFFER [file]Replay a journal
LEARN_BEGIN / LEARN_ENDRecord / capture replayable sequence
CALL_USER(sym, arg [, lib])dlopen / LoadLibrary callout
HELP [topic] / HELP_TEXT(topic)17 topics; both buffer + string forms
Keys

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).

Movement
KeyAction
↑↓←→MOVE_VERTICAL / MOVE_HORIZONTAL
Home / EndLine begin / line end
PgUp / PgDnScroll a screen
Backspace / DelERASE_CHARACTER (-1 / +1)
InsertToggle INSERT / OVERSTRIKE
TabInsert tab (uses TAB_STOPS)
EnterSPLIT_LINE
Control keys
KeyAction
Ctrl-ZCommand line
Ctrl-SWRITE_FILE
Ctrl-XEXIT
Ctrl-FSEARCH / live incremental find
Ctrl-VSELECT
Ctrl-WMOVE_TEXT (cut)
Ctrl-YPaste
Ctrl-OSPLIT_WINDOW
Ctrl-NNEXT_WINDOW
GOLD combinations
KeyAction
PF1 / F1GOLD prefix
GOLD+TTop of buffer
GOLD+EEnd of buffer
GOLD+FFind
GOLD+WWrite file
GOLD+QQuit
Function keys
KeyAction
F2HELP buffer
F3FIND
F4DELETE
F6–F12Available for DEFINE_KEY
PF1–PF4VT-style numeric keypad
Language

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.

example.tpu
! 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;
Build

One file. Three platforms.

VX/TPU is a single C++17 source. Pick your toolchain.

macOS / Clang

shell
brew install ncurses
clang++ -std=c++17 -O2 tpu.cpp -lncurses -o tpu
./tpu file.txt

Linux / GCC

shell
sudo apt install libncurses-dev
g++ -std=c++17 -O2 tpu.cpp -lncurses -o tpu
./tpu file.txt

Windows / MSVC + PDCurses

cmd / PowerShell
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

shell
./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.

What is VX/TPU?

VX/TPU is Sector7’s modern reimplementation of DEC’s TPU (Text Processing Utility) environment from OpenVMS: the same scripting language, built-in commands, buffers, windows, and extensibility model familiar from DECTPU and EVE, rebuilt to run on desktop systems today using ncurses on macOS and Linux and PDCurses on Windows.

Which platforms does VX/TPU support?

VX/TPU ships as a single C++17 source file. Typical builds use Clang plus Homebrew ncurses on macOS, GCC with libncurses-dev on Linux (for example Debian/Ubuntu), and MSVC plus PDCurses on Windows. The editor is exercised under bash, zsh, and PowerShell 7.

Will OpenVMS DECTPU procedures run on VX/TPU?

VX/TPU targets script-level compatibility with the classic DECTPU built-in surface: patterns, markers, buffers, key maps, SET/SHOW, HELP, processes, journaling, LEARN sequences, and the TPU programming language constructs. Anything that depended on OpenVMS-specific integration may need review after migration.

How do I enter the command line?

Press Ctrl-Z by default (it is a normal KEY_MAP entry and can be remapped). The command line accepts the same file, movement, editing, search, buffer, window, and process operations documented in VX/TPU’s reference sections on this page.

How do key maps and startup files work?

Use CREATE_KEY_MAP, ADD_KEY_MAP, DEFINE_KEY, GOLD-style prefixes, and per-buffer SET (KEY_MAP_LIST) to match site standards. On launch VX/TPU automatically COMPILEs $TPU_STARTUP or ~/.tpurc, so teams can share the same bindings and procedures across machines.

Does VX/TPU support undo, clipboard, and box selection?

Yes. Each buffer keeps a 200-snapshot undo/redo history (UNDO/REDO plus GOLD shortcuts). Clipboard integration uses READ_CLIPBOARD and WRITE_CLIPBOARD with pbcopy/pbpaste on macOS, wl-clipboard or xclip paths on Linux, and Win32 APIs on Windows. Rectangular edits use BOX SELECT, BOX CUT, BOX COPY, and BOX PASTE.

Can I run regression tests without opening the full-screen editor?

Run tpu --test yourfile.tpu to execute TPU code headlessly. Built-in ASSERT, ASSERT_EQ, and TEST sections are designed for scripted CI runs, similar in spirit to Sector7’s own multi-test regression suite.

How is VX/TPU distributed?

VX/TPU is supplied as part of Sector7’s OpenVMS migration and modernization toolchains. For evaluations, licensing arrangements, or roadmap questions, reach out through the Sector7 contact channels on this site or your existing account team.

Transform Your Legacy Software Today!

Get In Touch
Unlock the potential of your legacy software with our expert migration services.