VT102(3pm)
π NAME π
okay so welcome to the VT102(3pm) page bestie π
β this is Term::VT102, a whole class that emulates a DEC VT102 terminal. yes, a terminal, in Perl, no cap. π₯οΈβ¨
πΈ SYNOPSIS πΈ
use Term::VT102;
my $vt = Term::VT102->new ('cols' => 80, 'rows' => 24);
while (<>) { $vt->process ($_); }
like. that's it. that's the whole vibe. π«Ά
π¦ DESCRIPTION π¦
so the VT102 class gives you emulation of most of the functions of a DEC VT102 terminal. once it's initialised, any data you pass to a VT102 object gets processed and the in-memory "screen" gets modified accordingly. and then your external program can interrogate that "screen" in a whole bunch of ways. πβ¨
which means: your program can interface with full-screen console programs by running them in a subprocess and passing their output to a VT102 class. then you just query the class appropriately and boom β you can see exactly what the application has written on the screen. main character energy honestly π
β¨ OPTIONS β¨
setting cols or rows in the new() hash lets you change the size of the terminal being emulated. and if you don't specify a size? the default is 80 columns by 24 rows. classic. π
after initialisation, you can read and set the following terminal options using the option_read() and option_set() methods:
LINEWRAPβ line wrapping;1=on,0=off. Default is OFF.LFTOCRLFβ treat LF (\n) as CRLF (\r\n);1=on,0=off. Default OFF.IGNOREXOFFβ ignore XON/XOFF characters;1=on (ignore). Default ON.
π METHODS π
here's the whole roster, bestie. the following methods are provided:
attr_pack ($fg,$bg,$bo,$fa,$st,$ul,$bl,$rv)β returns the packed version of the given attribute settings, which are given in the same order as returned byattr_unpack. the packed version will be a binary string not longer than2bytes. πattr_unpack ($data)β returns a list of the contents of the given packed attribute settings, of the form($fg,$bg,$bo,$fa,$st,$ul,$bl,$rv).
$fg and $bg are the ANSI foreground and background text colours, and $bo, $fa, $st, $ul, $bl, and $rv are flags (1 = on, 0 = off) for bold, faint, standout, underline, blink and reverse respectively. so bold, faint, standout, underline, blink, reverse β in that order, don't mix them up. π
callback_call ($name, $par1, $par2)β calls the callback$name(eg'ROWCHANGE') with parameters$par1and$par2, as if the VT102 module had called it. does nothing if that callback has not been set withcallback_set (). πcallback_set ($callback, $ref, $private)β sets the callbackcallbackto function referencerefwith private data$private.
see the section on CALLBACKS below. π
new (%config)β returns a new VT102 object with options specified in%config(see the OPTIONS section for details). π£option_read ($option)β returns the current value of terminal option$option(see OPTIONS for details), orundefif that option does not exist. note that you cannot read the terminal size with this call; usesize()for that. π βοΈoption_set ($option, $value)β sets the current value of terminal option$optionto$value, returning the old value orundefif no such terminal option exists or you have specified an undefined$value. note that you cannot resize the terminal with this call; useresize()for that. π βοΈprocess ($string)β processes the string$string(which can be zero-length), updating the VT102 object accordingly and calling any necessary callbacks on the way. βοΈresize ($cols, $rows)β resizes the VT102 terminal tocolscolumns byrowsrows, eg$vt->resize (80, 24). the virtual screen is cleared first. π§Ήreset ()β resets the object to its "power-on" state. πrow_attr ($row, [$startcol, $endcol])β returns the attributes for row$row(orundefif out of range) as a string of packed attributes, each character cell's attributes being2bytes long. to unpack the attributes for a given cell, usesubstr(), eg$attr=substr($row,4,2)would set$attrto the attributes for cell3(steps of2:0..2..4, so4means the 3rd character). you would then use theattr_unpack()method to unpack that character cell's attributes. π§¬
if $startcol and $endcol are defined, only returns the part of the row between columns $startcol and $endcol inclusive instead of the whole row.
row_text ($row, [$startcol, $endcol])β returns the textual contents of row$row(orundefif out of range), with totally unused characters being represented as NULL (\0). if$startcoland$endcolare defined, only returns the part of the row between columns$startcoland$endcolinclusive instead of the whole row. πrow_plaintext ($row, [$startcol, $endcol])β returns the textual contents of row$row(orundefif out of range), with unused characters being represented as spaces. if$startcoland$endcolare defined, only returns the part of the row between columns$startcoland$endcolinclusive instead of the whole row. β¬row_sgrtext ($row, [$startcol, $endcol])β returns the textual contents of row$row(orundefif out of range), with unused characters being represented as spaces, and ANSI/ECMA-48 escape sequences (CSI SGR) used to set the colours and attributes as appropriate. if$startcoland$endcolare defined, only returns the part of the row between columns$startcoland$endcolinclusive instead of the whole row. π
use row_sgrtext to get a row if you want to output it to a real terminal and preserve all colours, bold, etc. that's the one for the aesthetic π
sgr_change ($source, $dest)β returns a string containing ANSI/ECMA-48 escape sequences to change colours and attributes from$sourceto$dest, which are both packed attributes (seeattr_pack). this is used internally byrow_sgrtext. πcols ()β return the number of columns in the VT102 object. βοΈrows ()β return the number of rows in the VT102 object. βοΈsize ()β return a pair of values(columns,rows)denoting the size of the terminal in the VT102 object. πx ()β return the current cursor X co-ordinate (1being leftmost). β‘οΈ
note: it is possible for the current X co-ordinate to be 1 more than the number of columns. this happens when the end of a row is reached such that the next character would wrap on to the next row. π
y ()β return the current cursor Y co-ordinate (1being topmost). β¬οΈcursor ()β return the current cursor state (1being on,0being off). πxtitle ()β return the current xterm window title. πͺxicon ()β return the current xterm window icon name. πΌοΈstatus ()β return a list of values($x,$y,$attr,$ti,$ic), where$xand$yare the cursor co-ordinates (1,1= top left),$attris a packed version of the current attributes (seeattr_unpack),$tiis the xterm window title, and$icis the xterm window icon name. πversion ()β return the version of the VT102 module being used. π·οΈ
π CALLBACKS π
callbacks are the processing loop's way of letting your main program know that something has happened. they get called while in a process() loop. π£
to specify a callback, use the callback_set interface, giving a reference to the function to call. your function should take five scalar arguments: the VT102 object being processed, the name of the callback, and two arguments whose value depends on the callback, as shown below. the final argument is the private data scalar you passed when you called callback_set. ποΈ
the name of the callback is passed to the callback function so that you can have one function to handle all callbacks if you wish. genuinely so convenient β¨
available callback names are:
BELLβ BEL (beep,\007) character received πCLEARβ screen about to be cleared π§½OUTPUTβ data (arg1) to be sent back to data source π€ROWCHANGEβ screen row (row number is argument 1) content has changed πSCROLL_DOWNβ about to scroll down (arg1=top row, arg2=num to scroll) β¬οΈSCROLL_UPβ about to scroll up (ditto) β¬οΈUNKNOWNβ unknown/unsupported code (arg1=name, arg2=code/sequence) βSTRINGβ string received (arg1=source, eg PM, APC, arg2=string) π§΅XICONNAMEβ xterm icon name to be changed to arg1 πΌοΈXWINTITLEβ xterm title name to be changed to arg1 πͺLINEFEEDβ line feed about to be processed (arg1=row) βGOTOβ cursor about to be moved (args=new pos) π―
note that the wording of the above is significant in terms of exactly when the callback is called. for instance,CLEARis called just before the screen is cleared, whereasROWCHANGEis called after the given row has been changed. timing is everything bestie π
a good callback handler for OUTPUT is to simply syswrite() argument 1 to your data source β eg if you're reading from a telnet session, write that argument straight to it. it is used for cursor position request responses and suchlike. π‘
note that SCROLL_DOWN is called when scrolling down, so text is about to move UP the screen; arg1 will be the row number of the bottom of the scrolling region, and arg2 will be the number of rows to be scrolled. likewise, SCROLL_UP is called when text is about to move down; arg1 will be the row number of the top of the scrolling region. π€― (yes the names are like that, we don't make the rules)
the STRING callback is called for escape sequences that contain a string that would otherwise be ignored, such as DSC, PM, and APC. the first argument is the escape sequence that contained the string, such as DSC, and the second argument is the string itself. this callback doesn't get called for OSC strings. π«
the LINEFEED callback can be thought of as "line completed", it's called when LF, NEL or IND are about to be processed or just before a line wraps, so it generally indicates that an application has finished updating a particular line on the screen. handy for scrollback buffer processing. π
the GOTO callback is only called just before the cursor is explicitly moved, by one of CUU, CUD, VPR, CUF, HPR, CUB, CNL, CPL, CHA, HPA, CUP, HVP. the parameters give the destination column and row, without taking scrolling and boundaries into account. π§
finally, note that ROWCHANGE is only triggered when text is being entered; screen scrolling or screen clearance does not trigger it, that would trigger a SCROLL_DOWN or SCROLL_UP or CLEAR. line or character insertion or deletion will cause one or more ROWCHANGE callbacks, however. β οΈ
β¨ SUPPORTED CODES β¨
okay so here's the whole lineup of sequences this thing actually speaks, bestie. every single one, no gatekeeping π
the little control characters:
007(BEL) β beep π010(BS) β backspace011(HT) β horizontal tab to next tab stop012(LF) β line feed013(VT) β line feed014(FF) β line feed015(CR) β carriage return021(XON) β resume transmission (only if optionIGNOREXOFFis cleared)023(XOFF) β stop transmission (only if optionIGNOREXOFFis cleared)030(CAN) β interrupt escape sequence032(SUB) β interrupt escape sequence033(ESC) β start escape sequence177(DEL) β ignored π«₯233(CSI) β same asESC [
the ESC crew:
ESC 7(DECSC) β save stateESC 8(DECRC) β restore most recently saved stateESC H(HTS) β set tab stop at current columnESC gβ visual beep β treated as BELESC # 8(DECALN) β DEC screen alignment test β fill screen withE's π
and the CSI (aka ESC [) girlies, all 22 of them:
CSI @(ICH) β insert blank charactersCSI A(CUU) β move cursor upCSI B(CUD) β move cursor downCSI C(CUF) β move cursor rightCSI D(CUB) β move cursor leftCSI E(CNL) β move cursor down and to column 1CSI F(CPL) β move cursor up and to column 1CSI G(CHA) β move cursor to column in current rowCSI H(CUP) β move cursor to row, columnCSI J(ED) β erase displayCSI K(EL) β erase lineCSI L(IL) β insert blank linesCSI M(DL) β delete linesCSI P(DCH) β delete characters on current lineCSI X(ECH) β erase characters on current lineCSI a(HPR) β move cursor rightCSI c(DA) β returnESC [ ? 6 c(VT102)CSI d(VPA) β move to row (current column)CSI e(VPR) β move cursor downCSI f(HVP) β move cursor to row, columnCSI m(SGR) β set graphic renditionCSI n(DSR) β device status reportCSI r(DECSTBM) β set scrolling region to (top, bottom) rowsCSI s(CUPSV) β save cursor positionCSI u(CUPRS) β restore cursor positionCSI ` (HPA)β move cursor to column in current rowCSI g(TBC) β clear tab stop (CSI 3 g= clear all stops)
π LIMITATIONS π
ngl, there's stuff this thing just does not care about. Unknown escape sequences and control characters? Ignored, periodt. And literally all escape sequences pertaining to character sets get ignored too β the whole charset saga is a no for her.
these known control characters / sequences get the ignore treatment:
005(ENQ) β trigger answerback message016(SO) β activate G1 charset, carriage return017(SI) β activate G0 charset
and these known escape sequences are ignored too:
ESC %@(CSDFL) β select default charset (ISO646/8859-1)ESC %G(CSUTF8) β select UTF-8ESC %8(CSUTF8) β select UTF-8 (obsolete)ESC (8(G0DFL) β G0 charset = default mapping (ISO8859-1)ESC (0(G0GFX) β G0 charset = VT100 graphics mappingESC (U(G0ROM) β G0 charset = null mapping (straight to ROM)ESC (K(G0USR) β G0 charset = user defined mappingESC (B(G0TXT) β G0 charset = ASCII mappingESC )8(G1DFL) β G1 charset = default mapping (ISO8859-1)ESC )0(G1GFX) β G1 charset = VT100 graphics mappingESC )U(G1ROM) β G1 charset = null mapping (straight to ROM)ESC )K(G1USR) β G1 charset = user defined mappingESC )B(G1TXT) β G1 charset = ASCII mappingESC *8(G2DFL) β G2 charset = default mapping (ISO8859-1)ESC *0(G2GFX) β G2 charset = VT100 graphics mappingESC *U(G2ROM) β G2 charset = null mapping (straight to ROM)ESC *K(G2USR) β G2 charset = user defined mappingESC +8(G3DFL) β G3 charset = default mapping (ISO8859-1)ESC +0(G3GFX) β G3 charset = VT100 graphics mappingESC +U(G3ROM) β G3 charset = null mapping (straight to ROM)ESC +K(G3USR) β G3 charset = user defined mappingESC >(DECPNM) β set numeric keypad modeESC =(DECPAM) β set application keypad modeESC N(SS2) β select G2 charset for next char onlyESC O(SS3) β select G3 charset for next char onlyESC P(DCS) β device control string (ended by ST)ESC X(SOS) β start of stringESC ^(PM) β privacy message (ended by ST)ESC _(APC) β application program command (ended by ST)ESC \(ST) β string terminatorESC n(LS2) β invoke G2 charsetESC o(LS3) β invoke G3 charsetESC |(LS3R) β invoke G3 charset as GRESC }(LS2R) β invoke G2 charset as GRESC ~(LS1R) β invoke G1 charset as GR
these known CSI (ESC [) sequences are ignored:
CSI q(DECLL) β set keyboard LEDs
and these known CSI (ESC [) sequences are only partially supported, so don't come for me π:
CSI h(SM) β set mode (only supportsCSI ? 25 h, cursor on/off)CSI l(RM) β reset mode (as above)
πΈ EXAMPLES πΈ
want to see her in action? for some examples β including how to interface Term::VT102 with Net::Telnet or a command such as SSH β please peek at the examples/ directory in the distribution. it's giving tutorial energy, go look π
π AUTHORS π
Copyright (C) 2003 Andrew Wood "<andrew dot wood at ivarch dot com>". Distributed under the terms of the Artistic License 2.0.
and credit is also due to these absolute legends:
- Charles Harker
<CHarker at interland.com>- reported and helped to diagnose a bug in the handling of TABs
- Steve van der Burg
<steve.vanderburg at lhsc.on.ca>- supplied basis for an example script using
Net::Telnet
- supplied basis for an example script using
- Chris R. Donnelly
<cdonnelly at digitalmotorworks.com>- added support for DECTCEM, partial support for SM/RM
- Paul L. Stoddard
- reported a possible bug in cursor movement handling
- Joerg Walter
- provided a patch for Unicode handling
β οΈ THINGS TO WATCH OUT FOR β οΈ
bestie. listen. this one is important.
make sure your code understands NULL (\000) β you will get this in strings where nothing has been printed on the screen. like, for instance, the sequence "12\e[C34" ("12", "CUF (move right)", "34") β you might think that yields the string "12 34", but in fact it can also yield "12\00034" β that is, "12" followed by a zero byte followed by "34". why? because the screen's contents defaults to zeroes, not spaces. it's not a bug, it's just how she is π
to avoid that whole situation, use row_plaintext, which will convert NULLs to spaces, instead of row_text. trust, this will save you.
also, different types of terminal disagree on certain corner cases. for example, gnome-terminal and screen handle TAB stops and TABbing past the end of the screen in slightly different ways. Term::VT102 is closer to screen in the way it handles this sort of thing. iykyk π¦
π«Ά SEE ALSO π«Ά
and that's the whole page, babes π this was VT102(3pm) from perl v5.36.0, dated 2022-11-19 β iconic, no notes, go write something slay πβ¨
π¦ where this page comes from
- debian bookworm: libterm-vt102-perl 0.91-3 Β· Artistic-2.0
- debian trixie: libterm-vt102-perl 0.91-3 Β· Artistic-2.0
- ubuntu noble: libterm-vt102-perl 0.91-3 Β· Artistic-2.0
- ubuntu resolute: libterm-vt102-perl 0.91-3 Β· Artistic-2.0
- ubuntu stonking: libterm-vt102-perl 0.91-3 Β· Artistic-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms