;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; TinyFugue - programmable mud client ;;;; Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2004, 2005, 2006-2007 Ken Keys ;;;; ;;;; TinyFugue (aka "tf") is protected under the terms of the GNU ;;;; General Public License. See the file "COPYING" for details. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; /set tf_stdlib_id=$Id: stdlib.tf,v 35000.92 2007/01/13 23:12:39 kkeys Exp $ ;;; TF macro library ;;; DO NOT EDIT THIS FILE. ;;; ;;; Personal commands should be performed in %HOME/.tfrc; public commands ;;; for all users should be performed in %TFLIBDIR/local.tf. This file will ;;; be replaced when tf is upgraded; %HOME/.tfrc and %TFLIBDIR/local.tf will ;;; not, so changes you make to them will not be lost. ;;; This library is essential to the correct operation of TF. It is as ;;; much a part of TF as the executable file. It is designed so that ;;; it can be used by one or many users. ;;; Many internal macros here are named starting with "~" to minimize ;;; conflicts with the user's namespace; you should not give your own ;;; macros names beginning with "~". Also, you probably don't want to ;;; use the -i flag in defining your personal macros, although you can. ;;; library loading ; Note: users should not rely on %_loaded_libs or any other undocumented ; feature of /loaded and /require. /set _loaded_libs= /def -i loaded = \ /if /@test _loaded_libs !/ "*{%{1}}*"%; /then \ /set _loaded_libs=%{_loaded_libs} %{1}%;\ ; in case the file this tries to /load another file that uses /loaded /let _required=0%; \ /elseif (_required) \ /exit%; \ /endif /def -i require = \ /let _required=1%; \ /load %{-L} %{L} ;;; visual status bar /eval /load -q %TFLIBDIR/tfstatus.tf ;;; file compression /if ( systype() =~ "unix" ) \ /def -i COMPRESS_SUFFIX = .Z%;\ /def -i COMPRESS_READ = zcat%;\ /elseif ( systype() =~ "os/2" ) \ /def -i COMPRESS_SUFFIX = .zip%;\ /def -i COMPRESS_READ = unzip -p%;\ /endif ;;; High priority for library hooks/triggers. This is a hack. /set maxpri=2147483647 ;;; Commands ;; Some of these use helper macros starting with ~ to reduce conflicts with ;; the user's namespace. Users should not rely on them or any other ;; undocumented implementation details. ;;; /echo [-a<attr>] [-p] [-oeAr] [-w[<world>]] <text> /def -i echo = \ /let opt_a=%; \ /let opt_w=()%; \ /let opt_p=0%; /let opt_o=0%; /let opt_e=0%; /let opt_r=0%; /let opt_A=0%; \ /if (!getopts("a:poerAw:")) /return 0%; /endif%; \ /return echo({*}, opt_a, !!opt_p, \ (opt_w !~ "()") ? strcat("w",opt_w) : opt_e ? "e" : opt_A ? "a" : opt_r ? "r" : "o") /def -i _echo = /test echo({*}) ;;; /prompt [-a<attr>] [-p] <text> /def -i prompt = \ /let opt_a=%; \ /let opt_p=0%; \ /if (!getopts("a:p")) /return 0%; /endif%; \ /return prompt(decode_attr({*}, opt_a, !!opt_p)) ;;; /substitute [-a<attr>] [-p] <text> /def -i substitute = \ /if (!getopts("a:p", "")) /return 0%; /endif%; \ /return substitute({*}, opt_a, !!opt_p) ;;; /sys <command> ; Executes an "inline" shell command. ; Only works for commands that do not require input or redraw the screen. /def -i sys = /quote -S -decho \\!!%{*-:} ;;; /send [-nW] [-T<type>] [-w<world>] text /def -i send = \ /if (!getopts("hnWT:w:", "")) /return 0%; /endif%; \ /let _text=%{*}%; \ /let _flags=$[opt_h ? "h" : ""]$[opt_n ? "u" : ""]%; \ /if (opt_W) \ /~send $(/@listsockets -s)%; \ /elseif (opt_T !~ "") \ /~send $(/@listsockets -s -T%{opt_T})%; \ /else \ /test send(_text, {opt_w}, _flags)%; \ /endif /def -i ~send = \ /while ({#}) \ /@test send(_text, {1}, _flags)%; \ /shift%; \ /done ;; null commands /def -i : = /@test 1 /def -i true = /@test 1 /def -i false = /@test 0 ;; /def -i bg = /fg -n ;; /ADDWORLD [-pxe] [-T<type>] [-s<srchost>] <name> [[<char> <pass>] <host> <port> [<file>]] ;; /ADDWORLD [-T<type>] DEFAULT <char> <pass> [<file>] /def -i addworld = \ /if (!getopts("pxeT:s:", "")) /return 0%; /endif%; \ /let flags=$[opt_p ?"p":""]$[opt_x?"x":""]$[opt_e?"e":""]%; \ /if ({1} =/ "default") \ /test addworld({1}, opt_T, "", "", {2}, {3}, {4}, flags, opt_s)%;\ /elseif ({#} <= 4) \ /test addworld({1}, opt_T, {2}, {3}, "", "", {4}, flags, opt_s)%;\ /else \ /test addworld({1}, opt_T, {4}, {5}, {2}, {3}, {6}, flags, opt_s)%;\ /endif ;; /world [-nlqxfb] [<name>] ;; /world [-nlqxfb] <host> <port> /def -i world = \ /if (!getopts("nlqxfb", 0)) /return 0%; \ /endif%; \ /let _args=%*%; \ /if (_args =~ "") \ /let _args=$(/nth 1 $(/@listworlds -s))%; \ /if (_args =/ "default") \ /let _args=$(/nth 2 $(/@listworlds -s))%; \ /endif%; \ /endif%; \ /let _opts=%; \ /if (is_open(_args)) \ /if (opt_n) /let _opts=%_opts -n%; /endif%; \ /if (opt_q) /let _opts=%_opts -q%; /endif%; \ /@fg %_opts %_args%; \ /else \ /if (opt_l) /let _opts=%_opts -l%; /endif%; \ /if (opt_q) /let _opts=%_opts -q%; /endif%; \ /if (opt_x) /let _opts=%_opts -x%; /endif%; \ /if (opt_f) /let _opts=%_opts -f%; /endif%; \ /if (opt_b) /let _opts=%_opts -b%; /endif%; \ /@connect %_opts %_args%; \ /endif ;; /purgeworld <name>... /def -i purgeworld = /unworld $(/@listworlds -s %*) ;; for loop. ; syntax: /for <var> <min> <max> <command> /def -i for = \ /@eval \ /let %1=%2%%; \ /while ( %1 <= %3 ) \ %-3%%; \ /@test ++%1%%; \ /done ;; flag toggler. /def -i toggle = /@test %1 := !%1 ;; result negation. /def -i not = /@eval %*%; /@test !%? ;; expression evaluator. /def -i expr = /result %* ;; replace text in input buffer. /def -i grab = /@test kblen() & dokey("dline")%; /@test input({*}) ;; partial hilites. /def -i partial = /def -F -p%{hpri-0} -Ph -t"$(/escape " %*)" ;; triggers. /def -i trig = /trigpc 0 100 %* /def -i trigc = /trigpc 0 %{1-x} %-1 /def -i trigp = /trigpc %{1-x} 100 %-1 /def -i undeft = /untrig -anGgurfdhbBC0 - %* /def -i nogag = \ /if ({#}) \ /untrig -ag - %*%;\ /else \ /echo %% Gags disabled.%;\ /set gag=0%;\ /endif /def -i nohilite = \ /if ({#}) \ /untrig -aurfdhbBC0 - %*%;\ /else \ /echo %% Hilites disabled.%;\ /set hilite=0%;\ /endif ;; macro existance test. /def -i ismacro = /test tfclose("o")%; /@list -s -i %{*-@} ;; variable existance test. /def -i isvar = /test tfclose("o")%; /listvar -msimple -- %* ;; cut-and-paste tool ; paste [-w<world>] [-spxtqnh] [-e<end>] [-a<abort>] [prefix] /def -i paste = \ /if (!getopts("spnxtqhw:e:a:", "")) /return 0%; /endif%; \ /if (opt_p & opt_t) \ /echo -e %% %0: Options -p and -t are mutually exclusive.%; \ /return 0%; \ /endif%; \ /if (opt_x & opt_w !~ "") \ /echo -e %% %0: Options -x and -w are mutually exclusive.%; \ /return 0%; \ /endif%; \ /let _prefix=$[opt_n ? "" : {*-%{paste_prefix-:|}}]%; \ /if (!opt_n) /shift%; /endif%; \ /let _end=%{opt_e-/endpaste}%; \ /let _abort=%{opt_a-/abort}%; \ /let _line=%; \ /let _text=%; \ /let _world=%{opt_w-${world_name}}%; \ /let _oldlen=0%; \ /let _lead=0%; \ /let _read=0%; \ /if (!opt_q) \ /echo -ep %% Entering paste mode. Type "@{B}%{_end}@{n}" or "@{B}.@{n}" to end, or "@{B}%{_abort}@{n}" to abort.%; \ /endif%; \ /while (1) \ /if ((_read := tfread(_line)) < 0 | _line =/ _abort) \ /return 0%; \ /endif%; \ /if (_line =/ _end | _line =/ ".") \ /break%; \ /endif%; \ /if (_line =/ "/quit" | _line =/ "/help*") \ /echo -ep %% Type "@{B}%{_end}@{n}" or "@{B}.@{n}" to end /paste, or @{B}%{_abort}@{n} to abort.%; \ /endif%; \ /if (opt_t) \ /test regmatch("^ +", _line), _lead := strlen({P0})%; \ /if (!_oldlen) \ /test _text := _line%; \ /elseif (_oldlen <= _lead) \ /test _text := strcat(_text, substr(_line, _oldlen))%; \ /else \ /_paste %{_prefix} %{_text}%; \ /test _text := _line%; \ /endif%; \ /test _oldlen := strlen(_text)%; \ /elseif (!opt_p) \ /if (!opt_s) \ /test regmatch(" *$$", _line)%; \ /let _line=%PL%; \ /endif%; \ /test _paste(_prefix=~"" ? _line : strcat(_prefix, " ", _line))%; \ /elseif (regmatch("^ *$", _line)) \ /if (_text !~ "") \ /_paste %{_prefix}%{_text}%; \ /_paste %{_prefix}%; \ /let _text=%; \ /endif%; \ /else \ /let _text=%{_text} $(/echo - %{_line})%; \ /endif%; \ /done%; \ /if ((opt_p | opt_t) & _text !~ "") \ /_paste %{_prefix}%{_text}%; \ /endif%; \ /return 1 /def -i _paste = \ /if (opt_x) \ ; execute /test eval({*}, 0)%; \ /else \ ; send (preserving leading spaces, and invoking send hooks) /test send({*}, _world, opt_h ? "h" : "")%; \ /endif ; /recordline -i - %* ; A /recordline here would allow history browsing during the paste, but do we ; really want pasted lines being stored permanently in history? Anyway, ; there's currently no way to preserve leading spaces in /recordline. ;; other useful stuff. /def -i first = /result {1} /def -i rest = /result {-1} /def -i last = /result {L} /def -i nth = /result {1} > 0 ? shift({1}), {1} : "" /def -i cd = /lcd %{*-%HOME} /def -i pwd = /last $(/@lcd) /def -i man = /help %* /def -i signal = /quote -S -decho !kill -%{1-l} $[{1}!~"" ? getpid() : ""] /def -i split = /@test regmatch("^([^=]*[^ =])? *=? *(.*)", {*}) /def -i ver = \ /result regmatch('version (.*). %% Copyright', $$(/version)), {P1} /def -i vercmp = \ /let pat=^([0-9]+)\\.([0-9]+) (alpha|beta|gamma|stable) ([0-9]*)$$%; \ /if (!regmatch(pat, {1})) \ /echo -e %% %0: Bad version format "%1"%; \ /return -2%; \ /endif%; \ /let maj1=%P1%; \ /let min1=%P2%; \ /let lev1=%P3%; \ /let rev1=%P4%; \ /if (!regmatch(pat, {2})) \ /echo -e %% %0: Bad version format "%2"%; \ /return -2%; \ /endif%; \ /let maj2=%P1%; \ /let min2=%P2%; \ /let lev2=%P3%; \ /let rev2=%P4%; \ ; lev comparison works because (alpha, beta, gamma, stable) happen to be ; alphabetically sorted. /return (maj1-maj2 ?: min1-min2 ?: strcmp(lev1,lev2) ?: rev1-rev2) /def -i runtime = \ /let real=%; \ /let cpu=%; \ ; "/let cpu=$[cputime()]" would lose precision in int->str->int conversion, ; but assignment operator avoids conversion. /test real:=time(), cpu:=cputime()%; \ /eval -s0 %{*}%; \ /let result=%?%; \ /_echo real=$[time() - real] cpu=$[cputime() - cpu]%; \ /return result ;;; Extended world definition macros /def -i addtiny = /addworld -T"tiny" %* /def -i addlp = /addworld -T"lp" %* /def -i addlpp = /addworld -T"lpp" %* /def -i adddiku = /addworld -T"diku" %* /def -i addtelnet = /addworld -T"telnet" %* ;; Proxy server connect hook /def -iFp'maxpri' -agG -hPROXY proxy_hook = /proxy_command /def -i proxy_command = \ /proxy_connect%; \ ; Many proxy servers turn localecho off. We don't want that. /localecho on%; \ /trigger -hCONNECT ${world_name}%; \ /if (login & ${world_character} !~ "" & ${world_login}) \ /trigger -hLOGIN ${world_name}%; \ /endif /def -i proxy_connect = telnet ${world_host} ${world_port} ;; Heuristics to detect worlds that use prompts, but have not been classified ;; as such by the user's /addworld definition. /def -iFp1 -mglob -T'{}' -hCONNECT ~detect_worldtype_hook = \ ; telnet prompt /def -ip1 -n1 -w -mregexp -h'PROMPT login: *$$' \ ~detect_worldtype_telnet_${world_name} = \ /echo -e %%% This looks like a telnet world, \ so I'm redefining it as one. You should explicitly set the type \ with the -T"telnet" option of /addworld.%%;\ /addworld -Ttelnet ${world_name}%%;\ /set lp=1%%;\ /localecho on%%; \ /@test prompt(strcat({PL}, {P0}))%%;\ /purge -i ~detect_worldtype_*_${world_name}%; \ /let cleanup=/purge -i #%?%; \ ; generic prompt /def -ip0 -n1 -w -mregexp -h'PROMPT ...[?:] *$$' \ ~detect_worldtype_prompt_${world_name} = \ /echo -e %%% This looks like an unterminated-prompt world, \ so I'm redefining it as one. You should explicitly set the type \ with the -T"prompt" option of /addworld.%%;\ /addworld -Tprompt ${world_name}%%; \ /set lp=1%%; \ /@test prompt(strcat({PL}, {P0}))%%; \ /purge -i ~detect_worldtype_*_${world_name}%; \ /let cleanup=%cleanup%%; /purge -i #%?%; \ ; If there's no prompt in the first 5s, assume this is not a prompting world, ; and undefine the hooks to avoid false positives later. We must also create ; a disconnect hook to undefine the prompt hooks if we disconnect before the ; timeout, and have the timeout process undefine the disconnect hook. /def -iFp'maxpri' -n1 -w -hDISCONNECT = %cleanup%; \ /let cleanup=%cleanup%%; /purge -i #%?%; \ /repeat -5 1 %cleanup ;; Default worldtype hook: tiny login format (for backward compatibility), ;; but do not change any flags. /def -mglob -T{} -hLOGIN -iFp'maxpri' ~default_login_hook = \ /~login_hook_tiny ;; Tiny hooks: login format, lp=off. /def -mglob -T{tiny|tiny.*} -hWORLD -iFp'maxpri' ~world_hook_tiny = \ /set lp=0 /def -mglob -T{tiny|tiny.*} -hLOGIN -iFp'maxpri' ~login_hook_tiny = \ /let _char=${world_character}%;\ /if (strchr(_char, ' ') >= 0) /let _char="%_char"%; /endif%; \ /let _pass=${world_password}%;\ /if (strchr(_pass, ' ') >= 0) /let _pass="%_pass"%; /endif%; \ /send connect %_char %_pass ;; Generic prompt-world hooks: lp=on. /def -mglob -Tprompt -hWORLD -iFp'maxpri' ~world_hook_prompt = \ /set lp=1 ;; LP/Diku/Aber/etc. hooks: login format, lp=on. /def -mglob -T{lp|lp.*|diku|diku.*|aber|aber.*} -hWORLD -iFp'maxpri' \ ~world_hook_lp = \ /set lp=1 /def -mglob -T{lp|lp.*|diku|diku.*|aber|aber.*} -hLOGIN -iFp'maxpri' \ ~login_hook_lp = \ /send -- ${world_character}%; \ /send -- ${world_password} ;; Hooks for LP-worlds with telnet end-of-prompt markers: ;; login format, lp=off. /def -mglob -T{lpp|lpp.*} -hWORLD -iFp'maxpri' ~world_hook_lpp = \ /set lp=0 /def -mglob -T{lpp|lpp.*} -hLOGIN -iFp'maxpri' ~login_hook_lpp = \ /send -- ${world_character}%; \ /send -- ${world_password} ;; Telnet hooks: login format, lp=on, and localecho=on (except at ;; password prompt). /def -mglob -T{telnet|telnet.*} -hCONNECT -iFp'maxpri' ~con_hook_telnet =\ /def -w -qhPROMPT -n1 -iFp'maxpri-1' = /localecho on /def -mglob -T{telnet|telnet.*} -hWORLD -iFp'maxpri' ~world_hook_telnet =\ /set lp=1 /def -mglob -T{telnet|telnet.*} -hLOGIN -iFp'maxpri' ~login_hook_telnet =\ /def -n1 -ip'maxpri' -mregexp -w -h'PROMPT login: *$$' \ ~telnet_login_${world_name} = \ /send -- $${world_character}%; \ /def -n1 -ip'maxpri' -mregexp -w -h'PROMPT password: *$$' \ ~telnet_pass_${world_name} = \ /send -- $${world_password} /def -mregexp -T'^telnet(\\..*)?$' -h'PROMPT password: *$' -iFp'maxpri-1' \ ~telnet_passwd = \ /@test prompt(strcat({PL}, {P0}))%;\ /def -w -q -hSEND -i -n1 -Fp'maxpri' ~echo_${world_name} =\ /localecho on%;\ /localecho off ;; /telnet <host> [<port>] ;; Defines a telnet-world and connects to it. /def -i telnet = \ /addtelnet %{1},%{2-23} %1 %{2-23}%; \ /connect %{1},%{2-23} ;;; default filenames ; This is ugly, mainly to keep backward compatibility with the lame old ; "~/tiny.*" filenames and *FILE macros. The new style, "~/*.tf", has ; a sensible suffix, and works on 8.3 FAT filesystems. (A subdirectory ; would be nice, but then /save* would fail if the user hasn't created ; the subdirectory). /if ( TINYPREFIX =~ "" & TINYSUFFIX =~ "" ) \ ; New-style names make more sense. /set TINYPREFIX=~/%; \ /set TINYSUFFIX=.tf%; \ ; Old-style names on unix systems, for backward compatibility. /if ( systype() =~ "unix" ) \ /set TINYPREFIX=~/tiny.%; \ /set TINYSUFFIX=%; \ /endif%; \ /endif /eval /def -i MACROFILE = %{TINYPREFIX}macros%{TINYSUFFIX} /eval /def -i HILITEFILE = %{TINYPREFIX}hilite%{TINYSUFFIX} /eval /def -i GAGFILE = %{TINYPREFIX}gag%{TINYSUFFIX} /eval /def -i TRIGFILE = %{TINYPREFIX}trig%{TINYSUFFIX} /eval /def -i BINDFILE = %{TINYPREFIX}bind%{TINYSUFFIX} /eval /def -i HOOKFILE = %{TINYPREFIX}hook%{TINYSUFFIX} /eval /def -i WORLDFILE = %{TINYPREFIX}world%{TINYSUFFIX} /eval /def -i LOGFILE = tiny.log ;;; define load* and save* macros with default filenames. /def -i ~def_file_command = \ /def -i %1%2 = \ /%1 %%{1-$${%{3}FILE}} %{-3} /~def_file_command load def MACRO /~def_file_command load hilite HILITE /~def_file_command load gag GAG /~def_file_command load trig TRIG /~def_file_command load bind BIND /~def_file_command load hook HOOK /~def_file_command load world WORLD /~def_file_command save def MACRO -mglob -h0 -b{} -t{} ?* /~def_file_command save gag GAG -mglob -h0 -b{} -t -ag /~def_file_command save trig TRIG -mglob -h0 -b{} -t -an /~def_file_command save bind BIND -mglob -h0 -b /~def_file_command save hook HOOK -mglob -h /def -i savehilite = \ /save %{1-${HILITEFILE}} -mglob -h0 -b{} -t -aurfdhbBC0%;\ /save -a %{1-${HILITEFILE}} -mglob -h0 -t -P ;;; list macros /def -i listdef = /list %* /def -i listfullhilite = /list -mglob -h0 -b{} -t'$(/escape ' %*)' -aurfdhbBC0 /def -i listpartial = /list -mglob -h0 -t'$(/escape ' %*)' -P /def -i listhilite = /listfullhilite%; /listpartial /def -i listgag = /list -mglob -h0 -b{} -t'$(/escape ' %*)' -ag /def -i listtrig = /list -mglob -h0 -b{} -t'$(/escape ' %*)' -an /def -i listbind = /list -mglob -h0 -b'$(/escape ' %*)' /def -i listhook = /list -mglob -h'$(/escape ' %*)' ;;; purge macros /def -i purgedef = /purge -mglob -h0 -b{} - %{1-?*} /def -i purgehilite = /purge -mglob -h0 -b{} -t'$(/escape ' %*)' -aurfdhbBC0 /def -i purgegag = /purge -mglob -h0 -b{} -t'$(/escape ' %*)' -ag /def -i purgetrig = /purge -mglob -h0 -b{} -t'$(/escape ' %*)' -an /def -i purgedeft = /purge -mglob -h0 -b{} -t'$(/escape ' %*)' ?* /def -i purgebind = /purge -mglob -h0 -b'$(/escape ' %*)' /def -i purgehook = /purge -mglob -h'$(/escape ' %*)' /def -i untrig = \ /if (!getopts("a:", "")) /return 0%; /endif%; \ /if /!purge -i -msimple -a%opt_a -t"$(/escape " %*)"%; /then \ /echo -e %% No trigger on %*.%; \ /return 0%; \ /endif /def -i unhook = \ /if /!purge -i -msimple -h"$(/escape " %*)"%; /then \ /echo -e %% No hook on %*.%; \ /return 0%; \ /endif ;; meta-character quoter ;; /escape <metachars> <string> /def -i escape = \ /let _meta=%; /let _dest=%; /let _tail=%; /let _i=%;\ /test _meta:=strcat({1}, "\\\\")%;\ /test _tail:={-1}%;\ /while ((_i := strchr(_tail, _meta)) >= 0) \ /test _dest:=strcat(_dest, substr(_tail,0,_i), "\\\\", substr(_tail,_i,1)), \ _tail:=substr(_tail, _i+1)%;\ /done%;\ /result strcat(_dest, _tail) ;;;; Replace ;;; syntax: /replace <old> <new> <string> /def -i replace = /result replace({1}, {2}, {-2}) ;;; /loadhist [-lig] [-w<world>] file /def -i loadhist = \ /let _file=%L%; \ /quote -S /recordline %-L '%%{_file-${LOGFILE}} ;;; Retry connections ;; /retry <world> [<delay>] ;; Try to connect to <world>. Repeat every <delay> seconds (default 60) ;; until successful. ; The -w on the /repeat lets /connect choose fg or bg correctly /def -i retry = \ /def -mglob -p'maxpri' -F -h'CONFAIL $(/escape ' %1) *' ~retry_fail_%1 =\ /repeat -w -%{2-60} 1 /connect %1%;\ /def -mglob -n1 -p'maxpri' -F -h'CONNECT $(/escape ' %1)' ~retry_succ_%1=\ /undef ~retry_fail_%1%;\ /connect %1 ;; /retry_off [<world>] ;; Cancels "/retry <world>" (default: all worlds) /def -i retry_off = /purge -mglob {~retry_fail_%{1-*}|~retry_succ_%{1-*}} ;;; Hilites for pages and whispers ;; Simulates "/hilite page" and "/hilite whisper" in old versions. /def -i hilite_whisper = \ /def -ip2 -ah -mregexp -t'^[^ ]* whispers,? ".*" (to [^ ]*)?$$' ~hilite_whisper1 /def -i hilite_page = \ /def -ip2 -ah -mglob -t'{*} pages from *[,:] *' ~hilite_page1%;\ /def -ip2 -ah -mglob -t'You sense that {*} is looking for you in *' ~hilite_page2%;\ /def -ip2 -ah -mglob -t'The message was: *' ~hilite_page3%;\ /def -ip2 -ah -mglob -t'{*} pages[,:] *' ~hilite_page4%;\ /def -ip2 -ah -mglob -t'In a page-pose*' ~hilite_page5 /def -i nohilite_whisper = /purge -mglob -I ~hilite_whisper[1-9] /def -i nohilite_page = /purge -mglob -I ~hilite_page[1-9] ;;; backward compatible commands /def -i cat = \ /echo -e %% Entering cat mode. Type "." to end.%; \ /let _line=%; \ /let _all=%; \ /while ((tfread(_line) >= 0) & (_line !~ ".")) \ /if (_line =/ "/quit") \ /echo -e %% Type "." to end /cat.%; \ /endif%; \ /@test _all := \ strcat(_all, (({1} =~ "%%" & _all !~ "") ? "%%;" : ""), _line)%; \ /done%; \ /recordline -i %_all%; \ /@test eval(_all) /def -i time = /@test echo(ftime({*-%%{time_format}})), time() /def -i rand = \ /if ( {#} == 0 ) /echo $[rand()]%;\ /elseif ( {#} == 1 ) /echo $[rand({1})]%;\ /elseif ( {#} == 2 ) /echo $[rand({1}, {2})]%;\ /else /echo -e %% %0: too many arguments%;\ /endif ; Since the default page key (TAB) is not obvious to a new user, we display ; instructions when he executes "/more on" if he hasn't re-bound the key. /def -i more = \ /if ( {*} =/ "{on|1}" & ismacro("-ib'^I' = /key_tab") & \ ismacro("-i key_tab = /dokey page") ) \ /echo -e %% "More" paging enabled. Use TAB to scroll.%;\ /endif%; \ /set more %* /def -i nolog = /log off /def -i nowrap = /set wrap off /def -i nologin = /set login off /def -i noquiet = /set quiet off /def -i act = /trig %* /def -i reply = /set borg %* /def -i background = /set background %* /def -i bamf = /set bamf %* /def -i borg = /set borg %* /def -i clearfull = /set clearfull %* /def -i cleardone = /set cleardone %* /def -i insert = /set insert %* /def -i login = /set login %* /def -i lp = /set lp %* /def -i lpquote = /set lpquote %* /def -i quiet = /set quiet %* /def -i quitdone = /set quitdone %* /def -i redef = /set redef %* /def -i shpause = /set shpause %* /def -i sockmload = /set sockmload %* /def -i sub = /set sub %* /def -i visual = /set visual %* /def -i gpri = /set gpri %* /def -i hpri = /set hpri %* /def -i isize = /set isize %* /def -i ptime = /set ptime %* /def -i wrapspace = /set wrapspace %* /def -i wrap = \ /if ({*} =/ '[0-9]*') \ /set wrapsize=%*%; \ /set wrap=1%; \ /else \ /set wrap %*%;\ /endif /def -i ~do_prefix = \ /if ( {-1} =/ "{|off|0|on|1}" ) \ /set %{1}echo %{-1}%; \ /elseif ( {-1} =/ "{all|2}" & {1} =~ "m" ) \ /set %{1}echo %{-1}%; \ /else \ /set %{1}prefix=%{-1}%; \ /set %{1}prefix%; \ /set %{1}echo=1%; \ /endif /def -i kecho = /~do_prefix k %* /def -i mecho = /~do_prefix m %* /def -i qecho = /~do_prefix q %* ;;; Other standard libraries /eval /load -q %TFLIBDIR/kbbind.tf /eval /if (systype() =~ "os/2") /load -q %TFLIBDIR/kb-os2.tf%; /endif /eval /load -q %TFLIBDIR/world-q.tf /eval /load -q %TFLIBDIR/color.tf /eval /load -q %TFLIBDIR/changes.tf /eval /load -q %TFLIBDIR/at.tf ;;; constants /set pi= /test pi:=2 * acos(0) /set e= /test e:=exp(1) ;;; Copy shell's MAILPATH to tf's TFMAILPATH ; MAILPATH is a colon-separated list of fields; each field is a filename and ; an optional '?' or '%' followed by a message. /eval /if (MAILPATH !~ "") \ /let _head=%; \ /let _tail=%{MAILPATH}%; \ /while (regmatch("^([^?%%:]+)([?%%][^:]+)?:?", {_tail})) \ /test _head := strcat(_head, " ", escape(" ", {P1}))%; \ /let _tail=%{PR}%; \ /done%; \ /set TFMAILPATH=%{_head}%; \ /endif ;;; Help for newbies /def -i -h'SEND help' -Fq send_help = \ /if (${world_name} =~ "") \ /echo -e %% You are not connected to a world.%; \ /echo -e %% Use "/help" to get help on TinyFugue.%; \ /endif ;;; Load local public config file /def -hloadfail -ag ~gagloadfail /eval /load %{TFLIBDIR}/local.tf /undef ~gagloadfail