'set novalue on' /* force KEXX and its way of SIGNAL ON NOVALUE */ /* Usage: MACRO KHELP [arg] */ /* Options: SET SYNONYM KHELP MACRO KHELP */ /* DEFINE F1 'SYNEX KHELP' FOCUSWORD.1() */ /* Examples: MACRO KHELP BOXFILL (header of BOXFILL.KEX) */ /* MACRO KHELP (command KHELP) */ /* MACRO KHELP UNKNOWN (command KHELP UNKNOWN) */ /* MACRO KHELP UNKNOWN.KEX (header of UNKNOWN.KEX) */ /* Special: For type 5 KHELP shows the macro definition in */ /* INITIAL.KML with comments above its definition, */ /* not shown by QUERY MACRO, MACROS, or DEFINE. */ /* Requires: Kedit 5.0 or KeditW 1.0 (Frank Ellermann, 1999) */ /* Purpose: Add context help for following macros to KHELP: */ /* ANSIFY translate ISO Latin 1 to Codepage 437 (or 850) */ /* BASE Insert in local XHTML copy */ /* BOX draw BOXes (9 styles, use keypad or box block) */ /* BOXFILL fill marked box (sample macro) */ /* BROWSE document browser (temporary wrap long lines) */ /* CA accelerate KHELP CAppend (like CI, COV, and CR) */ /* CDD CHD + CHDR like 4DOS CDD supporting *.DIR items */ /* CDEFG show biggest files (top 1000) in DIR.DIR file */ /* CHANGES CHANGE all occurences on line, not only first */ /* CHCP Optionally set and get process codepage (OS/2) */ /* CLIPBRD OS/2 WPS clipbrd.exe interface using GET & PUT */ /* COLOR * INITIAL.KEX calls COLOR by 'macro' monitor.1() */ /* COLOR2 Old (1995-2005) colour scheme for younger eyes */ /* COLORS translate color setting to corresponding number */ /* CONFIG edit miscellaneous CONFIG.SYS and AUTOEXEC.BAT */ /* COUNTS COUNT string in BLOCK / ALL lines ignoring CASE */ /* DAY display date + weekday, any arg.: input as line */ /* DOSX edit redirected standard output of OS command */ /* EIS edit OEIS sequence in local EIS??.TXT copies */ /* ENV like DOS SET, but modifying Kedit's environment */ /* EURO check char.s not contained in ASCII 32..126 & 9 */ /* EXTRACT * EXTRTEST clone, supports = and abbreviations */ /* EXTrac operand accelerate KHELP EXTRACT operand: QUERY/EXTRACT */ /* FEATURES Kedit 5.00 (D3/P3) bug list and workarounds */ /* FILES Kedit FIDO FILES.BBS (add orphans to FILES.BBS) */ /* GERMAN defines GERMAN.KML after INITIAL.KML (KEYB GR) */ /* HEXA hex. editor (like HEXE but using current MODE) */ /* HEXE hex. editor (show and maybe even patch binary) */ /* HREF convert URL (focus word) to dummy XHTML link */ /* HTM edit *.htm or *.html in homepage directory */ /* INITIAL * PROFILE.KEX calls 'macro initial' if INITIAL() */ /* KC KCOMPARE clone (resetting special keys at exit) */ /* KCOMPARE compare files with Kedit (samples macro) */ /* KEX Kedit macro using MACROPATH (or its definition) */ /* KEYCODES Kedit key decoder (showing name and definition) */ /* KEYDIFF determine all reDEFINEd (non-default) keys */ /* KHELP * KHELP.KEX allows normal 'command khelp khelp' */ /* KTAGS XTAGS clone (supporting TABs and Unix tags) */ /* LASTMSG * like QUERY LASTMSG, but in DIALOG (word wrap) */ /* LESSMORE used as synonym for LESS TAG and MORE TAG error */ /* LOCUS locate target in any currently edited file */ /* LONGEST locate and tag longest line(s) in edited file */ /* MBOXREF replace In-Reply-To: by References: in mbox */ /* MEMORY * show current MEMORY usage (samples macro) */ /* MODE OS/2: 'DOSQ MODE x,y' plus 'PSCREEN y x PRESET' */ /* MONO INITIAL.KEX calls MONO by 'macro' monitor.1() */ /* MUSTARD RFC 2119 keywords (MAY, MUST, SHOULD, etc.) */ /* NAME change filename and rename a corresponding file */ /* NBSP convert blanks in marked block to XHTML   */ /* NEMO start an OS/2 Norton clone in directory of file */ /* NETSCAPE view focus URL with NETSCAPE or NETSCDDE.exe */ /* NMK edit redirected output of NMAKE /f xyz.NMK xyz */ /* PROFILE * KHELP.KEX allows normal 'command khelp profile' */ /* Query operand accelerate KHELP QUERY operand: QUERY/EXTRACT */ /* QX simplified XQ.KEX integrating RELOAD.KEX */ /* REXX edit OS/2 script or copy REXXTRAP.CMD stuff */ /* REXXTRAP update REXXTRAP.CMD functions in *.CMD scripts */ /* RING * DIR currently edited files TAGging modified */ /* RW force write access on edited read-only file */ /* RXHELP REXX context help (OS/2, MDOS, PC DOS 7, PREXX) */ /* RXLYNX view focus URL or current file with RXLYNX.cmd */ /* SAY * display persistent result of REXX expression */ /* S-STAR test macro for [Ctrl]+[PrtSc] in patched Kedit */ /* SEQBOX put numbers in marked box (samples macro) */ /* Set operand accelerate KHELP SET operand */ /* SETLINES switch PSCREEN rows and columns */ /* STATUS * mini status: only relevant non-default settings */ /* SUBJECT encode CP 850 Subject: header as base-64 UTF-8 */ /* TIME * show elapsed time for specified command */ /* TRACE * DEBUG manager (keys, debugging, RXTRACE, etc.) */ /* TRASH Netscape mailbox directory TREE (excl. *.snm) */ /* TREE corrected sample supporting long and HPFS id.s */ /* TV remove base64 TV (= MZ) binaries from mbox file */ /* UNBLANK get rid of blank lines with even line numbers */ /* UNESCAPE experimental: JavaScript decryption */ /* UNIX raw text mode based on EOLIN LF etc. settings */ /* UTF hex. UTF-32 or UTF-16 to hex. UTF-8 and UTF-16 */ /* WINDOWS KeditW: could be called by 'macro' monitor.1() */ /* WO locate word in any edited file (uses LOCUS.kex) */ /* XC edit file executing specified initial command */ /* XDIR MANYFILE clone (corrected) */ /* XFN xedit "=:=\fn.=" in the path of the actual file */ /* XFT xedit "=:=\=.ft" in the path of the actual file */ /* XHTML Convert plain text (code page 850) to XHTML 1.0 */ /* XID xedit "=:=\id" in the path of the actual file */ /* XTREE DIR all subdirecories TAGging empty directories */ /* X-WIKI Profile for text/x-wiki translates UTF-8 to NCR */ /* XX XEDIT file with name completion (DIR ambiguous) */ /* ZIP edit preselected files (e.g. here: ZIP manuals) */ /* :: INITIAL.KML header */ /* : accelerate KHELP TARGET */ /* & accelerate KHELP "&" (for OS/2) */ /* 0 shorthand for "error messages and return codes" */ /* ~ DIR *.KEX *.KML in "home" directory of profile */ /* * show this comment list (= header of KHELP.KEX) */ X = translate( space( arg( 1 ))) /* end of header */ /* macro header types terminated by first non-empty instruction: */ /* . none, for help use MACRO name ? (e.g. MACRO SETLINES ?) */ /* 0 none, for help use MACRO name (e.g. MACRO KTAGS) */ /* 1 KEXX 'set novalue on' followed by REXX-style /* comments */ */ /* or any REXX-comment header excluding the first line */ /* 2 REXX comment header including the first line (no example) */ /* 3 SAMPLES macro: KEXX-style *-comment lines */ /* 4 none, show complete macro */ /* 5 :name defined in INITIAL.KML with preceding (!) *-comments */ if X = '*' then X = 'KHELP.KEX' /* * = own header */ if X = '::' then exit HEADER( X, 5 ) /* defined in KML */ if X = 'ANSIFY' then exit HEADER( X, 1 ) if X = 'BASE' then exit HEADER( X, 1 ) if X = 'BOX' then exit HEADER( X, 1 ) if X = 'BOXFILL' then exit HEADER( X, 3 ) /* samples header */ if X = 'BROWSE' then exit HEADER( X, 1 ) if X = 'CDD' then exit HEADER( X, 1 ) if X = 'CDEFG' then exit HEADER( X, 1 ) if X = 'CHANGES' then exit HEADER( X, 1 ) if X = 'CHCP' then exit HEADER( X, 1 ) if X = 'CLIPBRD' then exit HEADER( X, 1 ) if X = 'COLOR' then call ASKFOR X, 4 /* ambiguous item */ if X = 'COLOR2' then call ASKFOR( X, 4 ) if X = 'COLORS' then exit HEADER( X, 5 ) /* defined in KML */ if X = 'CONFIG' then exit HEADER( X, 1 ) if X = 'COUNTS' then exit HEADER( X, 1 ) if X = 'DAY' then exit HEADER( X, 5 ) /* defined in KML */ if X = 'DOSX' then exit HEADER( X, 5 ) /* defined in KML */ if X = 'EIS' then exit HEADER( X, 1 ) if X = 'ENV' then exit HEADER( X, 1 ) if X = 'EURO' then exit HEADER( X, 1 ) if X = 'EXTRACT' then call ASKFOR X, 1 /* ambiguous item */ if X = 'FEATURES' then exit HEADER( X, 4 ) /* show all lines */ if X = 'FILES' then exit HEADER( X, 3 ) /* samples header */ if X = 'GERMAN' then exit HEADER( X, 1 ) if X = 'HEXA' then exit HEADER( X, 1 ) if X = 'HEXE' then exit HEADER( X, 1 ) if X = 'HTM' then exit HEADER( X, 1 ) if X = 'INITIAL' then call ASKFOR X, 1 /* ambiguous item */ if X = 'KC' then exit HEADER( X, 1 ) if X = 'KCOMPARE' then exit HEADER( X, 3 ) /* samples header */ if X = 'KEX' then exit HEADER( X, 1 ) if X = 'KEYCODES' then exit HEADER( X, 1 ) if X = 'KEYDIFF' then exit HEADER( X, 1 ) if X = 'KHELP' then call ASKFOR X, 1 /* ambiguous item */ if X = 'KTAGS' then exit HEADER( X, 0 ) /* usage: no arg. */ if X = 'LASTMSG' then call ASKFOR X, 5 /* ambiguous item */ if X = 'LESSMORE' then exit HEADER( X, 1 ) if X = 'LOCUS' then exit HEADER( X, 1 ) if X = 'LONGEST' then exit HEADER( X, 1 ) if X = 'MBOXREF' then exit HEADER( X, 1 ) if X = 'MEMORY' then call ASKFOR X, 3 /* ambiguous item */ if X = 'MODE' then exit HEADER( X, 1 ) if X = 'MONO' then exit HEADER( X, 4 ) /* show all lines */ if X = 'MUSTARD' then exit HEADER( X, 1 ) if X = 'NAME' then exit HEADER( X, 5 ) /* defined in KML */ if X = 'NBSP' then exit HEADER( X, 1 ) if X = 'NEMO' then exit HEADER( X, 5 ) /* defined in KML */ if X = 'NETSCAPE' then exit HEADER( X, 1 ) if X = 'NMK' then exit HEADER( X, 1 ) if X = 'PROFILE' then call ASKFOR X, 3 /* ambiguous item */ if X = 'QX' then exit HEADER( X, 1 ) if X = 'REXX' then exit HEADER( X, 1 ) if X = 'REXXTRAP' then exit HEADER( X, 1 ) if X = 'RING' then call ASKFOR X, 1 /* ambiguous item */ if X = 'RW' then exit HEADER( X, 1 ) if X = 'RXHELP' then exit HEADER( X, 1 ) if X = 'RXLYNX' then exit HEADER( X, 1 ) if X = 'SAY' then call ASKFOR X, 5 /* ambiguous item */ if X = 'S-STAR' then exit HEADER( X, 4 ) /* show all lines */ if X = 'SEQBOX' then exit HEADER( X, 3 ) /* samples header */ if X = 'SETLINES' then exit HEADER( X, . ) /* usage: arg. ? */ if X = 'STATUS' then call ASKFOR X, 1 /* ambiguous item */ if X = 'SUBJECT' then exit HEADER( X, 1 ) if X = 'TIME' then call ASKFOR X, 1 /* ambiguous item */ if X = 'TRACE' then call ASKFOR X, 1 /* ambiguous item */ if X = 'TRASH' then exit HEADER( X, 1 ) if X = 'TREE' then exit HEADER( X, 1 ) /* corrected TREE */ if X = 'TV' then exit HEADER( X, 1 ) if X = 'UNBLANK' then exit HEADER( X, 1 ) if X = 'UNESCAPE' then exit HEADER( X, 1 ) if X = 'UNIX' then exit HEADER( X, 1 ) if X = 'UTF' then exit HEADER( X, 1 ) if X = 'WINDOWS' then exit HEADER( X, 1 ) if X = 'WO' then exit HEADER( X, 5 ) /* defined in KML */ if X = 'XC' then exit HEADER( X, 1 ) if X = 'XDIR' then exit HEADER( X, 1 ) if X = 'XFN' then exit HEADER( X, 5 ) /* defined in KML */ if X = 'XFT' then exit HEADER( X, 5 ) /* defined in KML */ if X = 'XHTML' then exit HEADER( X, 1 ) if X = 'XID' then exit HEADER( X, 5 ) /* defined in KML */ if X = 'XTREE' then exit HEADER( X, 1 ) if X = 'X-WIKI' then exit HEADER( X, 1 ) if X = 'XX' then exit HEADER( X, 1 ) if X = 'ZIP' then exit HEADER( X, 1 ) if TRYKEX( X ) then exit 0 /* explicit *.KEX */ if EXTRAS( arg( 1 )) then exit 0 /* mixed case abbreviation */ 'command khelp' arg( 1 ) /* else try command KHELP */ exit rc /* (no error if not found) */ EXTRAS: procedure /* --- KHELP EXT xyz, Q xyz, S xyz, etc. */ parse arg W XYZ ; X = '' ; W = translate( W ) if abbrev( 'EXTRAC ' , W, 3 ) then X = 'EXTract' MODIFY( XYZ ) if abbrev( 'QUER ' , W, 1 ) then X = 'Query' MODIFY( XYZ ) if abbrev( 'SE ' , W, 1 ) then X = 'Set' MODIFY( XYZ ) if W = 'CA' & XYZ = '' then X = 'CAppend' if arg( 1 ) = '0' then X = 'Error Messages and Return Codes' if arg( 1 ) = '&' then X = '"&"' if arg( 1 ) = ':' then X = 'TARGET' if arg( 1 ) = '~' then do /* PROFILE home directory: */ X = SEARCH( defprof.1()) ; X = left( X, lastpos( '\', X )) if X <> '' then 'dir "' || X || '*.k??"' ; return 1 end if X <> '' then 'command khelp' X ; X = (X <> '') ; return X MODIFY: procedure /* --- expand an abbreviated SET argument */ OLD = cmdline.3() ; SET = arg( 1 ) ; 'nomsg modify' SET if rc = 0 then do SET = translate( SET ) SET = SET || substr( word( cmdline.3(), 2 ), 1+ length( SET )) end 'cmsg' OLD ; return SET TRYKEX: procedure /* --- determine HEADER type of given KEX */ parse arg FILE ; if right( FILE, 4 ) <> '.KEX' then return 0 FILE = SEARCH( FILE ) ; if FILE = '' then return 1 PATH = fileid.1() 'kedit "' || FILE || '" (noprof' ; if rc <> 0 then return 1 'nomsg locate :1' ; TYPE = translate( curline.3()) if ring.0() > 1 then 'nomsg quit' /* silent QUIT found macro */ 'kedit "' || PATH || '" (nodefext' if abbrev( TYPE, "'S" ) then exit HEADER( FILE, 1 ) /* 'SET... */ if abbrev( TYPE, "'N" ) then exit HEADER( FILE, 1 ) /* 'NOV... */ if abbrev( TYPE, "/*" ) then exit HEADER( FILE, 2 ) /* REXXify */ if abbrev( TYPE, "* " ) then exit HEADER( FILE, 3 ) /* samples */ return ASKFOR( FILE, 4 ) /* KEX HEADER unidentified */ ASKFOR: procedure /* --- ask user for ambiguous KHELP topic */ parse arg FILE, TYPE ; parse source . . DIALOG.0 DIALOG.0 = delimit( 'macro' DIALOG.0 FILE ) DIALOG.1 = 'No: show header of' FILE || '.KEX' if TYPE = 5 then DIALOG.1 = 'No: display macro' FILE if TYPE = 4 then DIALOG.1 = 'No: display macro' FILE || '.KEX' if TYPE = 0 then DIALOG.1 = 'No: command macro' FILE if TYPE = . then DIALOG.1 = 'No: command macro' FILE '?' DIALOG.1 = 'Yes: command khelp' FILE || d2c(10) || DIALOG.1 DIALOG.2 = 'CANCEL' /* DIALOG error => CANCEL */ 'dialog' delimit( DIALOG.1 ) 'TITLE' DIALOG.0 'YESNOCANCEL' if DIALOG.2 = 'NO' then exit HEADER( FILE, TYPE ) if DIALOG.2 = 'YES' then return 0 /* YES => command khelp */ exit rc /* CANCEL=> emergency exit */ HEADER: procedure /* --- display help HEADER of given macro */ parse arg FILE, TYPE if TYPE = 0 then 'macro' FILE ; if TYPE = 0 then return rc if TYPE = . then 'macro' FILE '?' ; if TYPE = . then return rc PATH = fileid.1() ; I = 2 if TYPE = 5 then do /* get INITIAL.KML definition and comment */ TYPE = SEARCH( 'INITIAL.KML' ) ; if TYPE = '' then return 1 'kedit "' || TYPE || '" (noprof' ; if rc <> 0 then return rc ':0 tfind' delimit( ':' || FILE || ' ' ) if rc = 0 then do TYPE = curline.3() 'nomsg tfind -~/:/ & ~/*/' ; if rc <> 0 then 'top' do I = 0 until FILE.I = TYPE /* get comment above macro */ 'next' ; FILE.I = curline.3() end do I = I +1 until abbrev( FILE.I, ':' ) 'next' ; FILE.I = curline.3() end end else FILE.1 = 'macro' FILE 'not found in' TYPE end else do /* get macro header depending on its type */ FILE = SEARCH( FILE ) ; if FILE = '' then return 1 'kedit "' || FILE || '" (noprof' ; if rc <> 0 then return rc 'locate :' || ( TYPE = 1 ) ; I = 1 do until focuseof() 'next' ; FILE.I = curline.3() if FILE.I > '' then do if TYPE = 1 > abbrev( FILE.I, '/*' ) then leave if TYPE = 2 > abbrev( FILE.I, '/*' ) then leave if TYPE = 3 > abbrev( FILE.I, '*' ) then leave X = lastpos( '*/' , FILE.I ) if TYPE = 1 then parse var FILE.I '/*' FILE.I =(X) . if TYPE = 2 then parse var FILE.I '/*' FILE.I =(X) . if TYPE = 3 then parse var FILE.I '*' FILE.I end if opmode.1() = 'REAL' & memory.3() < 2 then leave if FILE.1 > '' then I = I + 1 end end if ring.0() > 1 then 'nomsg quit' 'kedit "' || PATH || '" (nodefext' ; if rc <> 0 then return rc 'refresh' ; I = I - 1 ; if FILE.I = '' then I = I -1 do I = 1 to I ; say FILE.I ; end ; return 0 SEARCH: procedure /* --- search macro in whatever MACROPATH */ arg FILE if right( FILE, 4 ) <> '.KEX' & right( FILE, 4 ) <> '.KML' then FILE = FILE || '.KEX' if pos( '\', FILE ) > 0 | pos( ':', FILE ) = 2 then do LAST = lastpos( '\', FILE ) + 1 ; if LAST = 1 then LAST = 3 parse var FILE PATH =(LAST) FILE /* split PATH from id. */ LAST = GETDIR( FILE, PATH ) /* test macro existence */ if LAST > '' then LAST = LAST || FILE if LAST = '' then 'emsg' PATH || FILE 'not found' return LAST end PATH = dosenv( 'PATH' ) /* prepare macro search */ if PATH > '' & right( PATH, 1 ) <> ';' then PATH = PATH || ';' if version.1() == 'KEDIT' then do /* Kedit 5.0 MACROPATH: */ LAST = GETDIR( 'kedit.exe', PATH ) /* Kedit's LAST resort */ if macropath.1() = 'ON' then nop /* LAST is part of PATH */ if macropath.1() = 'OFF' then PATH = LAST /* OFF -> LAST */ end else do /* KEDITW not tested... */ LAST = GETDIR( 'keditw.exe', PATH ) /* Keditw's LAST resort */ if LAST > '' then do /* add \USER & \SAMPLES */ LAST = LAST || ';' || LAST || 'USER;' || LAST || 'SAMPLES' end if macropath.1() = 'ON' then PATH = PATH || LAST if macropath.1() = 'OFF' then PATH = '' /* OFF -> void */ end if wordpos( macropath.1(), 'OFF ON' ) = 0 then do PATH = dosenv( macropath.1()) /* use common MACROPATH */ if PATH > '' & right( PATH, 1 ) <> ';' then PATH = PATH || ';' PATH = PATH || LAST /* LAST is Kedit's home */ end if PATH = '' then do /* sorry: MACROPATH OFF */ 'emsg' FILE 'not found: unknown KEDIT directory' ; return '' end PATH = GETDIR( FILE, PATH ) /* search FILE in PATH */ if PATH = '' then do 'emsg' FILE 'not found in MACROPATH' ; return '' end return PATH || FILE GETDIR: procedure /* --- find FILE in PATH with DIR command */ parse arg FILE, PATH /* search FILE in PATH */ if sign( pos( '*', FILE )) then return '' /* don't find *.* or */ if sign( pos( '?', FILE )) then return '' /* similar file id.s */ 'extract /DIRFORMAT/' /* adapted DIRFORMAT */ 'nomsg dirformat' max( 8, length( FILE )) max( 3, length( FILE )) do while PATH <> '' parse var PATH NAME ';' PATH /* NAME= next directory */ if right( NAME, 1 ) <> '\' then NAME = NAME || '\' 'nomsg dir "' || NAME || FILE || '" (noprof' if rc <> 0 then iterate /* ignore bad path NAME */ do until focuseof() /* match dot file NAMEs */ 'next' ; ID = dirfileid.4() if dirfileid.5() > '' then ID = ID || '.' || dirfileid.5() if translate( ID ) == translate( FILE ) then do if ring.0() > 1 then 'quit' /* found, exit DIR.DIR */ 'dirformat' DIRFORMAT.1 DIRFORMAT.2 return NAME /* return found path */ end end if ring.0() > 1 then 'quit' /* go on, exit DIR.DIR */ end 'dirformat' DIRFORMAT.1 DIRFORMAT.2 /* reset user's DIRFORM */ return '' /* not found: ''-string */