CmdShl is a command interpreter front-end. It mimics the CMD.EXE command line behavior. It adds the following features:
Installing CmdShl is very simple: just copy CMDSHL.CMD somewhere along your PATH, REXXVIO.DLL somewhere along your LIBPATH and, if you want to use a profile file, customize PROFILE.SHL and move it somewhere along your DPATH.
If REXXVIO.DLL is currently in use, close ALL your OS/2 windowed or fullscreen sessions, and open a bare OS/2 windowed session (that is, one not starting CmdShl of Fl). You can then replace REXXVIO.DLL from this session.
If you were using a previous version of MLRXSHL, execute the following code from an OS/2 command prompt, to allow the new functions defined in REXXVIO to be registered:
rexxtry call VioDropFuncs
If you want to use CmdShl whenever you open an OS/2 session, you can add the following statement in the Parameter field of your OS/2 Windowed (or fullscreen) session object:
/k "cmdshl"If you use an old OS/2 release that has no support for long files (i.e., files that are bigger than 2GB), overwrite REXXVIO.DLL with REXXVIO.OLD beforehand.
cmdshl [/?] [/I|/O] [/P profile] [/C command|/K command]
/? - Display a short explanation for CmdShl; /I - Use Insert mode by default (default); /O - Use Overstrike mode by default; /P profile - Use profile instead of "PROFILE.SHL"; /C cmd - Just like the CMD.EXE /C switch; /K cmd - Just like the CMD.EXE /K switch.
CMDSHL CMDSHL /C DIR CMDSHL /K ALIAS @myalias
CmdShl recognizes the following environment variables:
CDPATH CMDSHL.PROMPT CMDSHL.PROMPT.environment PROMPT HELP.COMMAND HELP.SWITCHES HOME
If one or more of those environment variables are not defined, the missing ones are silently ignored.
The HELP.* environment variables are used to define an optional external help subsystem.
This environment variable specifies the path along which the CD command should search for directories.
This environment variable specifies the prompt to be used if no specific prompt is defined for the current environment. It takes precedence over PROMPT.
See the PROMPT section for details on the possible values of CMDSHL.PROMPT.
This environment variable specifies the prompt to be used in the given environment. It takes precedence over CMDSHL.PROMPT and PROMPT.
For example, you can define two different prompts for two different (possible) environments:
SET CMDSHL.PROMPT.CMD=$i[$p]$s SET CMDSHL.PROMPT.EDIT=EDIT:[$p]$s
See the PROMPT section for details on the possible values of CMDSHL.PROMPT.environment.
This environment variable specifies the prompt to be used if no more specific prompt is defined. If PROMPT is not defined, "[$p]" is assumed.
The following symbols can be used to define a new prompt. Each symbol must be preceded by a dollar symbol ($):
All other symbols are emitted without changes.
If this environment variable is defined, CmdShl will not use its build-in help messages for internal commands. Instead, it will call the script/application defined by this variable.
For example, if HELP.COMMAND is defined as:
SET HELP.COMMAND=ECHO Help for
Issuing "ALIAS /?" will give:
Help for ALIAS /?
(In other words, the command is displayed back to the user.)
The syntax of the call is the following:
call %HELP.COMMAND% <command> <args>
where <command> is the upper-cased full command name (namely, one of ALIAS, CD, CMDSHL, DEFINE, QUIT or RULE) and <args> the argument(s) given to the command by the user.
If this environment variable is defined, it is used as the default value for the helpSwitches environment variable. If HELP.SWITCHES is not defined, the default value for helpSwitches is "/?".
See the helpSwitches definition in CmdShl internal variables for more details.
If this environment variable is defined, and if pathExt is set to 1, leading occurrences of the "~" symbol in paths will be replaced by its value.
Its value is assumed to be a valid and fully qualified path, but this is not enforced.
If it is not defined, it defaults to the root of the boot drive.
For example, if HOME is defined as:
Issuing "CD ~\tools" will change the current directory to be:
if pathExt has been set to 1. Otherwise, the current directory would be:
(Assuming we were at the root of the "C" drive before calling CD.)
CmdShl can recognize a couple of extended path notations in path specifications if the pathExt internal variable is set to 1.
Those extended notations are handled during completion, allowing for concise entries.
The first recognized notation is a leading "~" symbol, which represents the value of the HOME environment variable (or the root of the boot drive, if HOME is not defined).
The other recognized notation is three (or more) dots as a path segment, which represents backward navigation in the same vein as "." and "..". For example, "..." is equivalent to "..\.." and "...." is equivalent to "..\..\..".
Additionaly, CmdShl can automatically expand those notations for internal commands and convert slashes to backslashes, if the autoPathExt internal variable is set to 1. (The substitution only occurs for paths that do not start with a forward slash, in order not to clash with command options).
If autoPathExt is set to 1 but pathExt remains unset, then the only changes that will occur will be the slash to backslach ones.
Neither pathExt nor autoPathExt are enabled by default.
By default, CmdShl uses CMD.EXE editing commands, as well as some EPM keys, that is:
But you can redefine almost all keys to suit your needs. As an example, the default PROFILE.SHL file provides the following additional editing keys:
( -- insert () and move cursor inside F3 -- close the current session F8 -- insert current date Shift+F7 -- show all matching file names F2, F5, F7 -- save, load and rename -- history list Ctrl+R -- search command in history Ctrl+F -- search next match in history Ctrl+Down arrow -- save current screen Ctrl+Up arrow -- restore last screen
The expand internal action is used to expand the element preceding the cursor. That is:
In the following examples, the cursor is supposed to be the underscore sign.
keyb_fr --> c:\OS2\keyb.com_fr keyb fr_ --> keyb fr_ alias xrn=_ --> alias xrn=e:\local\yarn ^& yarn.exe ^& cd - rule RD=_ --> rule RD=%d %d*^|/? set etc=_ --> set etc=d:\tcpip\etc type %etc%\connect.log_ --> type d:\tcpip\etc\connect.log_
The tab and backtab internal actions are used to complete the element preceding the cursor. That is:
When more than one matching item is found, the tab and backtab internal actions are used to enumerate the possibilities.
The type of the element at cursor position is determined by user-defined rules. When no such rule exists, a file or directory whose name begins with the element preceding the cursor is searched for. The following rules are predefined (they can be redefined at will):
CD %d|%f %f|/?| CHDIR %d|/?| DETACH %x FOR %%%l IN (%*) DO %x RD %d %d*|/? RMDIR %d %d*|/? SET %e=%*|/?| START "%*" %o %x|"%*" %o|%o %x|%o
See the RULE command for details on rules.
The space internal action is used to insert (or overstrike) a space and to check the validity of the command preceding it. That is to say, the command preceding the cursor is checked if it is in a command (findcontexttype() returns "c") or invalid (findcontexttype() returns "0") context, as defined by rules.
If it is a command context, nothing happens if the command found is valid. Otherwise, invalidCmd is evaluated. If it is an invalid context, invalidCmd is evaluated too.
invalidCmd by default flags the offending command in red, but it can be redefined by the user. See its definition in the Internal Variables section for details.
CmdShl adds the following internal commands:
ALIAS [LIST|@file|alias=[cmd]] DEFine key [value] QUIT RULE [LIST|@file|rule=[def]] RX cmd
And it enhances the following underlying shell commands:
CD [directory|string1 string2]
The ALIAS command is used to view/define/remove aliases. Alias
names ARE case-sensitive. Recursive aliases are not allowed (but an
alias can use another alias). And an alias can use all CmdShl's
ALIAS dir=dir %* ^| less ALIAS prj=cd \user\alpha\smith\MyProject\Current ALIAS makeprj=prj ^& nmake ALIAS calc=rx say %*; RC=0 ALIAS in=cd %1 ^& %2* ^& cd -
When defining aliases from the command line, you may have to quote special symbols (such as "&" and "|") with a "^" in order to prevent unexpected results. For example, the first (dir), third (makeprj) and last (in) aliases require an "^" in front of their "&"s when entered from the command line.
When the execution of an alias is interrupted by the user (by the mean of Ctrl+C or Ctrl+Break), the execution of the alias is interrupted, as is the execution of the possibly following commands in the current command line.
The DEFine command is used to [re]define a key. You can either
assign to a key an internal action, an immediate command or a static
text. You can also remove a key definition (the key will then returns
its default value).
[In this section, if a command name is shown in mixed case, as "DEFine" above, it means it can be abbreviated. That is, you can use either "DEF", "DEFI", "DEFIN" or "DEFINE" -- upper-cased letters are required, others are optional.]
By default, the following keys-name are defined:
A-C, A-D, A-M, A-U, A-W, A-Z, A-F10, BKSP, CURD, CURL, CURR, CURU, C-CURL, C-CURR, C-E, C-END, C-HOME, C-PGDN, C-PGUP, C-X, DEL, END, ENTER, ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, HOME, INS, PGDN, PGUP, SPACE, S-TAB, TAB
[Shifted keys have a "S-" prefix, control keys have a "C-" prefix and Alt keys have a "A-" prefix.] If you want to define another key, you have to define a synonym, as in:
RX S_F7='005A'x; C_A='01'x
The variable name is the key name, with an "_" instead of a "-", as you cannot use "-" in a REXX variable name, and the key name value is the hexadecimal value returned by the getKey function. You can use the following CmdShl command to find this value for a key:
RX call getkey; say "'"substr(ckey,2)"'x"
The following internal actions are available:
backmatch, backsp, backtab, cdown, cleft, cright, ctrlend, ctrlhome, ctrlleft, ctrlright, cup, del, dup, end, enter, esc, expand, home, ins, mark (char|clear|copy|word|delete|move), match, space, tab
If you assign an internal action to a key, this key will act just as if the internal action was used. If you want to assign more than one internal action to a key, you can use the MC command.
For example, if you want the C_A key to act as the Home key (if you are used to EMACS), use:
DEFINE C-A home
And, if you do not like the command validity check, use:
[That is, restore default behavior -- you can use "DEFINE SPACE space" to undo your change.]
If you want to assign a static text to a key, use the TEXT command:
DEFINE A_F10 TEXT Hello World!
If you want to assign an immediate command, use the OSNowait statement (or its SHELL synonym). It can be followed by any CmdShl valid command(s):
DEFINE F3 OSNowait EXIT
Now, if you hit F3, your session will be closed.
If you want to assign more than one command to a key, use the MC command:
DEFINE " MC /TEXT ""/cleft
The first non-blank character following MC is the separator. It does not have to be a "/".
[See PROFILE1.SHL for more complex keys definitions.]
The QUIT command is used to exit from CmdShl. It does not close
the underlying CMD.EXE session.
The RULE command is used to view/define/remove rules. Rules names ARE case-sensitive but a case-insensitive rule is assumed if rule name is in UPPERCASE.
Rules are used to help providing smart completion and command
RULE WHENCE=%f %e RULE CD=%d^|%f %f^|/?|
A rule contains one or more clauses, separated by "|". Each clause describes a possible parameter list for the command.
In a clause, you can use any literal symbol, or one of the following values:
For example, the rule for the FOR command would be:
RULE FOR=%%%l IN (%*) DO %x
It means that the FOR command requires a "%" sign immediately followed by a letter, then one (or more) space, an "IN" keyword (case insensitive), one (or more) space again, an open parent, one or more symbols, a close parent, one (or more) space, a "DO" keyword (case insensitive), one (or more) space and finally an expression.
Another example is the rule for the START command, which contains four clauses:
RULE START="%*" %o %x|"%*" %o|%o %x|%o
An example using the "%(list)" specification follows:
RULE EDITINI=%(*.INI *.FOO)
It means that the (hypothetical) EDITINI command requires a file whose extension is either ".INI" or ".FOO" (case insensitive).
If the last element of a clause is one of the special symbols listed above followed by a "*", it means this element can be repeated zero or more time.
For example, the RD (aka RMDIR) command is described with the following rule by default:
RULE RD=%d %d*|/?
The first clause specifies that RD can take one or more directory name on its command line.
The left hand side of a rule respects the following:
For example, assuming the following:
RULE FOO=BAR|BAZ RULE foo=FOOBAR RULE Foo=FOOBARBAZ
If you enter "foo", rule 2 applies. If you enter "Foo", rule 3 applies. If you enter anything else (such as "FOO" or "foO"), rule 1 applies. It means that, if you want to define a specific rule for an all-upper-cased command, you have to define the default rule for all other cases.
RULE IN=<a special rule> RULE In=<the default rule> RULE in=<the default rule> RULE iN=<the default rule>
The right hand side respects:
For example, assuming the default rule for FOR, the following entries are all valid:
for %a in (a b) do echo %a for %a In (a b) Do echo %a for %a IN (a b) DO echo %a
The following rules are defined by default (they describe the various CMD.EXE internal commands):
CD %d|%f %f|/?| CHDIR %d|/?| DETACH %x FOR %%%l IN (%*) DO %x RD %d %d*|/? RMDIR %d %d*|/? SET %e=%*|/?| START "%*" %o %x|"%*" %o|%o %x|%o
You can redefine or remove them if needed, by using the RULE command (either in a PROFILE file or directly from the command line).
If no rules is defined for a command, "%*" is assumed.
RX is CmdShl's backdoor. You can use any valid REXX statement as a
parameter, and you can check/set CmdShl internal variables, or call
CmdShl internal functions. It is useful, but mostly for "power
[See PROFILE1.SHL for some RX usage samples.]
The CD command now accepts a new parameter, "-", and uses the
CDPATH environment variable. Additionally, both "\" and "/" can be
used in directories specifications and the drive is changed. Partial
path substitution is also allowed.
+----- - -----+
The CDPATH environment variable contains a list of paths. You do not have to include the current (".") directory in it. It is always looked up first.
For example, if CDPATH is defined as:
Issuing the "CD APPS" command will bring you to "C:\OS2\APPS" (if there was no APPS entry in the then-current directory).
If the directory specification starts with one of "/", "\", "./", "../", and so on, CDPATH is not used.
A trailing "/" or "\" is allowed in directories specification.
You can perform path substitution. For example, if you are currently in C:\project\beta\source and want to switch to C:\project\gamma\source, you can use "CD BETA GAMMA".
If path extensions are enabled, they are recognized and handled correctly. Hence you can use shortcuts like "CD ~/Mail" or "CD ..." If you want to switch to a directory named "-", you will have to enclose it with double quotes, follow it with "\" or precede it with ".\" as in:
CD "-" CD -\ CD .\-
You may prefer to use the CHDIR command, which does not provide the enhanced features of CD:
CD "-" CD .\- CD -\ CHDIR -
foo bar foo.exe
[This behavior is the default, but you can choose to give precedence to an executable name with no arguments by setting impCD to 2. See the impCD definition in CmdShl internal variables.]
for %i in (foo bar) do alias do_%i=baz %ior
(foo prj & bar prj) >foobar.log
CmdShl's ALIAS command is not called in the first statement, and foo and bar cannot be aliases.
RX say foo & bar
can be interpreted either as "RX say foo" followed by a "bar" command, or as "RX say foo & bar", displaying 1 if foo and bar are both equal to 1 and 0 otherwise. As there is no way to choose between those two valid interpretations, the first one is retained.
'a very long line...'
can be entered as:
'a very', 'long line...'
(Note the ending comma at the end of the first line.)
df.cmd [drive ...]
This is a UNIX "df" clone. It displays all available (or specified) drives, with their total, used and free capacity.
pushd.cmd [new dir]
This command pushes the current directory in a directory stack, and (optionally) changes to the given disk/directory.
This command pops the head of the directory stack, and go to this new directory.
whence.cmd file [path]
This command tries to find a file along a path (PATH by default). If the file is found, its complete path is displayed.
There are just six language-dependent messages which are not automatically adjusted: it is the alias command help string (aliasHelp), the CmdShl help string (cmdHelp), the define command help string (defHelp), the quit command help string (quitHelp), the rule command help string (ruleHelp) and the additional CD help string (cdHelp). They are at the beginning of the file, and you can translate them. Or, even better, you can define them in your PROFILE.SHL (see below).
All other language-dependent messages are automatically adjusted by CmdShl (secondary prompt, top of screen help string, ...).
CmdShl supports profile files. By default, PROFILE.SHL is used, but you can override it via the /P switch.
If present, the profile file should be somewhere along the DPATH, or you can alternatively specify its complete path.
A profile file is a plain REXX file. It is called after command line arguments, but before any user interaction. It's usually used to redefine keys assignments, displaying or setting some session-dependent data, and so on...
Please refer to PROFILE1.SHL for more explanations.
This is my current profile file, which you can use as a sample profile file for CmdShl. [Hint: for better startup performances, you can remove all comments -- that is, all except the first.]
For a detailed explanation of the features added by this profile file, read the end of this section.
/* profile.shl - sample bindings 990601 */ /* This profile file demonstrates typical profile usage: */ /* */ /* - Improving/tailoring existing commands, adding shortcuts */ /* [The auto-close '(', the insert-date key (F8), and S-F7, */ /* which displays all possible filenames.] */ /* */ /* - Adding new functions */ /* [The persistent command history, F2 (save), F5 (load) and */ /* F7 (name), tools to search items through command history */ /* as well as screen management system with C-UP, C-DOWN and */ /* C-PADPLUS.] */ /* */ /* - National Language Support */ /* [on-line messages in French.] */ /* */ /* - Useful global aliases and rules */ /* In a profile file, you can use any REXX instruction, but, due to */ /* the current implementation, it must fit in one line. */ /* */ /* That is, you can use: */ /* */ /* if foo = 'XYZZY' then say 'Nothing happens'; else x = x + 1 */ /* */ /* But you cannot use: */ /* */ /* if foo = 'XYZZY' then */ /* say 'Twice as much happens' */ /* else */ /* x = x + 1 */ /* */ /* Alternatively, you can use the comma as a line continuation marker */ /* */ /* foo = 'Hello', */ /* 'world' */ /* */ /* Another important difference with standard REXX scripts is that */ /* you cannot call CmdShl commands in a REXX structure using the */ /* standard way. You have to use the eval function. That is, */ /* */ /* if answer = 'YES' then */ /* 'DEFINE F12 OSNOWAIT shutdown' */ /* else */ /* 'DEFINE F12 TEXT shutdown' */ /* */ /* does not work. You have to use: */ /* */ /* if answer = 'YES' then */ /* call eval 'DEFINE F12 OSNOWAIT shutdown' */ /* else */ /* call eval 'DEFINE F12 TEXT shutdown' */ /* */ /* [But it works just fine outside of a structure.] */ /* Note: when a command name is in mixed case, like DEFine below, it */ /* means that you can use DEF, DEFI, DEFIN or DEFINE. */ /* */ /* There is currently only one pseudo command, DEFine, which is most */ /* useful in profile file. Its syntax is as follows: */ /* */ /* DEFine key value */ /* */ /* Key is a user-defined key or a predefined one: */ /* */ /* A-F10, BKSP, CURD, CURL, CURR, CURU, C-CURL, C-CURR, C-END, */ /* C-HOME, C-PGDN, C-PGUP, DEL, END, ENTER, ESC, F1, F2, F3, F4, */ /* F5, F6, F7, F8, F9, F10, F11, F12, HOME, INS, PGDN, PGUP, */ /* SPACE, S-TAB, TAB */ /* */ /* [Shifted keys have a "S-" prefix, control keys have a "C-" */ /* prefix and Alt keys have a "A-" prefix.] */ /* */ /* and value is an internal action or MC nnn, OSNowait nnn or */ /* TEXT nnn: */ /* */ /* backmatch, backsp, cdown, cleft, cright, ctrlend, ctrlhome, */ /* ctrlleft, ctrlright, cup, del, end, enter, esc, match, home, */ /* ins, tab, space, expand */ /* */ /* TEXT nnn simulates the keyboard entry of nnn */ /* */ /* OSNowait cmd executes cmd (via the CmdShl interpreter) */ /* */ /* MC separator cmd1 separator cmd2... allows the usage of more */ /* than one command for a key */ /* */ /* All other pseudo commands are executed via CmdShl's interpreter. */ /* [In fact, the DEFine command could have been implemented as an */ /* alias: */ /* */ /* ALIAS DEFINE=RX _args="%*"; */ /* parse value _args with key rest; */ /* if length(key) > 1 then */ /* key = value(translate(key,"_","-")); */ /* if rest \= "" then */ /* call value "key._"c2x(key), rest; */ /* else interpret "drop key._"c2x(key) */ /* */ /* It is functionally equivalent.] */ /* user-defined key name - note the usage of "_" in place of "-" in */ /* the key name (you can't use "-" in a REXX */ /* variable name). */ /* */ /* The value of a key name is the hexadecimal */ /* value returned by the getKey function when */ /* pressing it (you can use the following */ /* CmdShl command to find it) : */ /* */ /* RX call getkey; say "'"substr(ckey,2)"'x" */ /* Note: by default, variables are hidden when inside a getLine call. */ /* If you want to expose some of them, add them to the global */ /* variable -- global = global "newname1 newname2" */ /* */ /* So, each time you use one of your variable in the right hand */ /* side of a DEFine command, you have to expose it. */ S_F7 = '005A'x; C_CURU = '008D'x; C_CURD = '0091'x; C_PADPLUS = '0090'x /* defining key value - a shifted key can use "-" or "_" in its name */ 'DEFINE F3 OSNOWAIT EXIT' /* you can even do complex things: */ 'DEFINE ( MC /TEXT ()/cleft' 'DEFINE F8 OSNOWAIT RX line = insert(date(),line,currOfs); currOfs = currOfs+length(date())' 'DEFINE S-F7 osn rx if currTab = 0 then currTab = findcontextcompletion(); if currTab \= 0 then do; say; do i = 1 to tree.0; say tree.i; end; call charout, print(); oline=""; parse value SysCurPos() with origRow origCol .; key="tab"; end' /* we can even add a new feature: loading/saving commands history */ /* first, we define a file name (and make it public, F7 requires it): */ history = expand('%tmp%\history.shl'); global = global 'history' /* then, an alias, LOADHIST, which loads the commands history */ 'ALIAS LOADHIST=RX drop prevLine.; i = 0; call stream history, "c", openread; do while lines(history); i = i+1; prevLine.i = linein(history); end; prevLine.0 = i; call stream history, "c", "close"' /* now, we define three function keys, F2 (save), F5 (load/refresh) */ /* and F7 (name) */ 'DEFINE F2 OSNOWAIT RX "@del /f" history; do i = 1 to prevLine.0; call lineout history, prevLine.i; end; call stream history, "c", "close"' 'DEFINE F5 OSNOWAIT LOADHIST' 'DEFINE F7 OSNOWAIT RX call charout ,"1b"x"[s"||"1b"x"[0;0H"||"1b"x"[1;37;42m"||"1b"x"[KNew history name: "; history=getLine(history); call charout ,"1b"x"[0;0H"||"1b"x"[0;34;47m"||"1b"x"[K"helpstring"1b"x"[0m"||"1b"x"[u"' /* finally, we load the default history */ 'LOADHIST' /* We can even define a screen management system. */ scr.0 = 0; global = global 'scr.' 'ALIAS PUSHSCR=RX i = scr.0 + 1; scr.i._C = SysCurPos(); scr.i._P = currOfs origRow origCol; scr.i._L = line; scr.i._S = VioReadCellStr(0,0); scr.i._O = oldDir; scr.i._D = directory(); scr.0 = i' 'ALIAS POPSCR=RX i = scr.0; if i > 0 then do; call VioWrtCellStr 0,0,scr.i._S; line = scr.i._L; call SysCurPos word(scr.i._c,1), word(scr.i._c,2); parse var scr.i._P currOfs origRow origCol; oldDir = scr.i._O; call directory scr.i._D; scr.0 = i-1; end' 'ALIAS SWAPTMPSCR=RX i = scr.0 + 1; scr.i._C = scr._C; scr.i._P = scr._P; scr.i._L = scr._L; scr.i._S = scr._S; scr.i._O = scr._O; scr.i._D = scr._D; scr.0 = i' 'ALIAS SWAPSCR=RX if scr.0 > 0 then do; scr._C = SysCurPos(); scr._P = currOfs origRow origCol; scr._L = line; scr._S = VioReadCellStr(0,0); scr._O = oldDir; scr._D = directory(); call eval "POPSCR & SWAPTMPSCR"; end' 'DEFINE C-CURD OSNOWAIT PUSHSCR' 'DEFINE C-CURU OSNOWAIT POPSCR' 'DEFINE C-PADPLUS OSNOWAIT SWAPSCR' /* We redefine C-K to a smarter duplication function. */ 'DEFINE C-K MC /dup/tab' /* We define tools to search through command history. */ C_F = '06'x; C_R = '12'x; global = global 'item'; item = '' 'DEFINE C-R OSN RX oldLine=currLine;call charout ,"1b"x"[s"||"1b"x"[0;0H"||"1b"x"[1;37;42m"||"1b"x"[KSearch for: "; item=getLine(item); call charout ,"1b"x"[0;0H"||"1b"x"[0;34;47m"||"1b"x"[K"helpstring"1b"x"[0m"||"1b"x"[u";', 'if item \= "" then do;prevLine.0=prevLine.0-1;currLine=oldLine-1;if currLine=0 then currLine=prevLine.0;do prevLine.0 while pos(item,prevLine.currLine) = 0;currLine = currLine-1;', 'if currLine=0 then currLine=prevLine.0;end;if pos(item,prevLine.currLine) \= 0 then line=prevLine.currLine;currOfs=length(line);xOfs=0;end' 'DEFINE C-F OSN RX if item\="" then do; oldCur=currLine;currLine = currLine-1;if currLine = 0 then currLine=prevLine.0;', 'do prevLine.0 while pos(item,prevLine.currLine) = 0;currLine = currLine-1;if currLine=0 then currLine=prevLine.0;end;if pos(item,prevLine.currLine) \= 0 then line=prevLine.currLine;currOfs=length(line);xOfs=0; end' /* Here, we redefine help messages in French... */ defHelp = "Utilisez la command DEFINE pour (re)définir le rôle des touches"nl||, "du clavier."nl||nl||, "SYNTAXE: DEF touche [valeur]"nl||, " DEFINE touche [valeur]"nl||nl||, " touche Spécifie le nom de la touche à définir."nl||, " valeur Valeur affectée à la touche. Ce peut être une"nl||, " commande interne, MC xxx, OSNowait yyy ou TEXT zzz."nl||nl||, "Exemples:"nl||, " DEF F12 TEXT dir /w"nl||, " DEFINE F3 OSNOWAIT exit"nl||, " DEF F12" aliasHelp = "Utilisez la commande ALIAS pour afficher, définir ou"nl||, "supprimer un alias."nl||nl||, "SYNTAXE: ALIAS [LIST|alias=[chaîne]|@fichier]"nl||nl||, " LIST Affiche la liste des alias en cours."nl||, " alias Spécifie le nom de l'alias."nl||, " chaîne Valeur alphanumérique affectée à l'alias."nl||, " fichier Nom d'un fichier contenant un ensemble de"nl||, " définitions d'alias."nl||nl||, "Dans la définition d'un alias, %* correspond aux paramètres"nl||, "passés sur la ligne de commande." ruleHelp = "Utilisez la commande RULE pour afficher, définir ou"nl||, "supprimer une règle."nl||nl||, "SYNTAXE: RULE [LIST|règle=[chaîne]|@fichier]"nl||nl||, " LIST Affiche la liste des règles en cours."nl||, " règle Spécifie le nom de la règle."nl||, " chaîne Valeur alphanumérique affectée à la règle."nl||, " fichier Nom d'un fichier contenant un ensemble de"nl||, " définitions de règles."nl||nl||, "Dans la définition d'une règle, %*, %c, %d, %e, %f, %l, %o et"nl|| "%x dénotent le type des paramètres." cmdHelp = "Utilisez la commande CMDSHL pour augmenter les capacités de"nl||, "votre interpréteur de commande."nl||nl||, "SYNTAXE: CMDSHL [/I|/O] [/P profile] [/C cmd|/K cmd]"nl||nl||, " /I Sélecte le mode Insertion par défaut."nl||, " /O Sélecte le mode surfrappe par défaut."nl||, " /P Utilise le fichier profile spécifié."nl||, " /C Exécute la commande cmd et met fin à l'exécution"nl||, " de CMDSHL."nl||, " /K Exécute la commande cmd sans mettre fin à l'exécution"nl||, " de CMDSHL."nl||nl||, "Par défaut, le mode Insertion est actif et le fichier PROFILE.SHL"nl||, "est utilisé comme profile s'il existe sur le chemin spécifié par"nl||, "la variable d'environnement DPATH." cdHelp = "Tapez CD - Pour retourner au répertoire précédent."nl||, "Tapez CD s1 s2 Pour remplacer s1 par s2 dans le répertoire en cours." quitHelp = "Utilisez la commande QUIT pour quitter CMDSHL."nl||nl||, "SYNTAXE: QUIT" /* useful aliases... from my point of view :-) */ 'ALIAS rlogin=cls ^& ckermit ^& UTIL\telnet %1.unice.fr ^& cd -' 'ALIAS xrn=e:\local\yarn ^& yarn.exe ^& cd -' 'ALIAS open=rx xline = "%*"; if xline = "" then xline = directory(); else xline = findcommand(); call SysOpenObject xline,"DEFAULT",1; call SysOpenObject xline,"DEFAULT",1' 'ALIAS tc=java TCTypeCheck %*' 'ALIAS dir='SysSearchPath('PATH', 'sdir.cmd')' %*' 'ALIAS netscape=rx url=stream("%1", "c", "query exists"); if url="" then call eval("start netscape.exe %1"); else call eval("start netscape.exe" url)' 'ALIAS loop=rx do %*' 'ALIAS qd=query date' 'ALIAS qt=query time' 'ALIAS recurse=rx orgdir=directory(); call SysFileTree "*","dirs.","DSO"; do i=1 to dirs.0; call directory dirs.i; call eval "%1*^&rx needCR=0"; end; call directory orgdir' 'ALIAS revmap=rx call SysFileTree "*","dirs.","DSO"; do i=dirs.0 to 1 by -1; call eval "%1*" dirs.i "^&rx needCR=0"; end' 'ALIAS map=rx call SysFileTree "*","dirs.","DSO"; do i=1 to dirs.0; call eval "%1*" dirs.i "^&rx needCR=0"; end' 'ALIAS except=rx parse value "%1*" with "(" liste ")" cmde; line=""; currOfs=0; call findmulticompletion liste; do _i = 1 to tree.0; "attrib +H" tree._i; end; call eval cmde, "except"; do _i = 1 to tree.0; "attrib -H" tree._i; end' /* useful rule... from my point of view :-) */ 'RULE WHENCE=%f %e' 'RULE UNZIP=%u %(*.zip *.exe *.jar) %*' 'RULE VIEW=%(*.inf *.hlp) %*' 'RULE recurse=%x' 'RULE except=(%*) %x'
This profile file does the following:
The command history is read from/stored in the file whose name is contained in the history variable (by default %tmp%\history.shl).
F2 is used to store the current command history list to this file.
F5 is used to replace the current history list by the one defined in the file.
F7 is used to interactively give a new name for the file (to be used by subsequent F2 or F5 actions).
The default history file is loaded at startup (the "LOADHIST" invocation);
You can save the current "screen" by pressing Ctrl+Down arrow.
You can restore a previously saved "screen" by pressing Ctrl+Up arrow.
You can toggle between the current "screen" and the last previously saved one by pressing Ctrl+Numpad +. It allows you to easily switch between two different "screens".
When more than one "screen" are saved, they are stored in a stack (that is, the last stored "screen" is the first restored one.)
The "screen" above means the current state (screen layout, currently edited command, current directory and such). This feature has been added to circumvent the 16 OS/2 sessions limit and also because it is much simpler to press Ctrl+Up/Down arrow than to start or switch to another session. On the down side, it does not work from other VIO applications;
Ctrl+R asks (on the top screen line) an item to search, and find (if any) the first occurrence of it in the command history (starting from current line, and going backward).
Ctrl+F finds (if any) the next occurrence (going backward, too).
Those two definitions show another way to add functionality without using aliases. It is a bit faster that way but it is also less user-friendly (no way to easily edit such definitions, ...). Reserve it for editing features;
rlogin is probably useless for you :-)
xrn is used to launch my newsreader (Yarn/2). You probably will not use it, but it shows you how to launch an application that does not reside in the PATH.
open is used to open the current directory (or the specified argument, either a directory or file) in a window. The default view is used (as defined by your current Workplace Shell settings).
tc is again probably of no use :-)
dir overrides the default CMD.EXE's DIR command with the enhanced SDIR.CMD one. (SDir is part of MLRXSHL.) The SysSearchPath function is called so that an absolute path is used by the alias. It means the alias will always call the same script, irrespective of the current directory content.
netscape is used so that you can simply enter "netscape index.html" instead of "netscape file:index.html" which is required by Netscape if you do not want to receive an error message. If you specify an URL instead of a file name, it still works, too.
loop allows you to do a command more than once. Please note that it requires a REXX syntax. For example "loop 10; 'mp123 Lillith.mp3'; end" will play the Lillith song ten times.
[Lillith is a track from Plaid's album "Not For Threes", featuring Björk.]
qd and qt are simple synonyms for "query date" and "query time", respectively. Not that useful if you are not used to use those two-letters commands to get current date/time;
recurse is used to repeat a command in each subdirectories beneath the current directory. The order in which the subdirectories are enumerated is filesystem-dependent. The only guarantee is that a child subdirectory comes after its parent. The given command is not run on the current directory.
map and revmap are two commands used to map (i.e., apply) a command over the list of subdirectories. The order in which the subdirectories are enumerated is filesystem-dependent. The only guarantee is that a subdirectory comes after its parent for map and before its parent for revmap. The command passed in argument receives one additional parameter, a full directory name. That is, if we suppose the current directory contains two subdirectories, one of which contains another subdirectory, the following commands would be issued:
map aCommand --> aCommand x:\curdir\subdir1 aCommand x:\curdir\subdir2 aCommand x:\curdir\subdir1\subsubdir1 revmap aCommand arg1 --> aCommand arg1 x:\curdir\subdir2 aCommand arg1 x:\curdir\subdir1\subsubdir1 aCommand arg1 x:\curdir\subdir1
So the following would define a simple "deltree" command:
ALIAS zap=del %1* /n ^& rd %1* ALIAS deltree=revmap zap
And the following...
ALIAS tricky=pushd ^& alias _foo=cd ^%1 ^^^& %1* ^& map _foo ^& popd
...is another way to define the recurse alias given above. How it works is left as an exercise to the reader :-)
except is used to exclude a list of file from the effect of the specified command (in most case). For example, if you want to move all .class files except the ones starting with test or tmp to a given directory, use:
except (test* tmp*) move *.class foo\bar\baz
[This alias is not 100% bullet-proof in that it simply temporarily sets the hidden attribute for the specified files. If the command ignores this attribute, then strange results may occur.]
This section describes useful CmdShl internal functions. Please note that theses functions may evolve in future releases.
The addAlias command adds (or removes) an alias to (from) the alias database.
No return value.
call addAlias "foo=cd e:2_X/unix/emacs19.29/info/beta" call addAlias "foo=cd d:/local" call addAlias "foo="
The addRule command adds (or removes) a rule to (from) the rule database.
No return value.
call addRule "CD=%d|%f %f|/?|" call addRule "foo=%e %d*" call addRule "foo="
The canonize function returns path in which all occurrences of environment variables surrounded by "%" are substituted by their values, and in which all possible extended path notations are expanded if the pathExt variable is set to 1. Double quotes are removed and slashes are converted to backslashes too.
If an environment variable contains extended path notations, they will be expanded if appropriate.
With pathExt set to 1 say canonize('~/foo') --> 'c:\home\me\foo' say canonize('./~/foo') --> '.\~\foo' say canonize('".../bar"') --> '..\..\bar' say canonize('%etc%/.../baz') --> 'c:\baz' With pathExt set to 0 (default) say canonize('~/foo') --> '~\foo' say canonize('./~/foo') --> '.\~\foo' say canonize('".../bar"') --> '...\bar' say canonize('%etc%/.../baz') --> 'c:\MPTN\ETC\...\baz'
The double function returns expr in which all occurrences of "%" are doubled.
say double('foo bar') --> 'foo bar' say double('echo %abc%') --> 'echo %%abc%%' say double(double('5%')) --> '5%%%%'
The eval command evaluate its line argument. The optional current parameter is here to prevent recursive execution of aliases (current is a space-delimited list of alias names).
Returns 0 if it evaluates the QUIT command, 1 otherwise.
call eval "FOO" If FOO is an alias or an external command, it is executed. call eval "FOO", "FOO" If FOO is an external command, it is executed. Error SYS1041 occurs otherwise. call eval "FOO & BAR", "ZOO BAZ" FOO and BAR will be executed in sequence. If they are alias, and if they call ZOO or BAZ (either directly or indirectly), it is the external command ZOO or BAZ that will be used.
The expand function returns string where all occurrences of environment variables surrounded by "%" are substituted by their values.
say expand('%tmp%\foo') --> 'E:\IBMCPP\TMP\foo' say expand('%unknown%') --> '%unknown%' say expand('%unknown%tmp%') --> '%unknownE:\IBMCPP\TMP' say expand('100%') --> '100%'
The expandpathext function returns path where all extended path notations are replaced with their standard translations if the variable pathExt is set to 1. Nothing is done otherwise.
The recognized extended path notations are "~" , either alone or followed by a slash or a backslash at the begining of the path, and "...", "...." and so on.
path must not contains double quotes, or else incorrect expansion may take place.
say expandpathext('~/foo/bar') --> 'c:\home\mo\foo/bar' say expandpathext('"~/foo"') --> '"~/foo"' say expandpathext('~/.../b') --> 'c:\home\me\..\../b' say expandpathext('"~/.../b"') --> '"~/../../b"'
The findcommand function returns the expanded command name defined by xline, if any, or "" if xline is not a valid command.
If arg is specified, the real command name is returned. If no arg is used (or if arg is empty) an approximation is returned (in this case, aliases and internal commands take precedence over directories, regardless of the "implied" CD status -- it is faster, because the possible disk access is delayed).
xline = "keyb"; say findcommand() --> 'C:\OS2\keyb.COM' xline = "xyzzy"; say findcommand() --> ''
The findcompletion function returns 1 if it can find a file name completion for the element preceding the cursor position, or 0 otherwise.
If successful, tree. contains the possible completions.
If type is specified, only names of the specified type are returned. The possible types are "F" or "D", for respectively file and directory.
if findcompletion() then do i = 1 to tree.0 say tree.i end else say "No match!"
The findcontextcompletion function returns 1 if it can find a completion for the element preceding the cursor position, or 0 otherwise. It uses the context (as defined by rules) to find a completion:
if findcontextcompletion() then do i = 1 to tree.0 say tree.i end else say "No match!"
The findcontexttype function returns the type of the element preceding the cursor position (or, if cmd is provided, the cursor is supposed to follow the last character of cmd). The returned value is one of: "a", "c", "d", "e", "f", "(list)", "" or "0":
say findcontexttype('cd') --> 'c' say findcontexttype('cd ') --> 'd' say findcontexttype('cd e:') --> 'd' say findcontexttype('cd e: ') --> 'f' say findcontexttype('for %i is') --> '0'
If we assume the default rules for the CD and FOR commands, which are "%d|%f %f|/?|" and "%%%l IN (%*) DO %x".
The findcurrentcommand function returns the command ending cmd. It does just return the command, its (possible) arguments are not. If the line is empty, an empty string is returned.
It does not always returns the finest command (for example, in the third example below, "for" is returned, not "del") but it nonetheless returns a valid one, so that the context can be correctly determined.
This function modifies the xline global variable. It contains the command plus its arguments, if any. (Warning: the length of xline is correct, but all opening and closing parents in it are replaced by spaces.)
say findcurrentcommand('dir *foo') --> 'dir' say xline --> 'dir *foo' say findcurrentcommand('dir & cd bar') --> 'cd' say xline --> 'cd bar' say findcurrentcommand('for %i in (a b) do del %i') --> 'for' say xline --> 'for %i in a b do del %i' say findcurrentcommand('for %i in (a b) do (echo %i & del') --> 'del' say xline --> 'del'
The findenvcompletion function returns 1 if it can find an environment variable completion for the element preceding the cursor position, or 0 otherwise.
If successful, tree. contains the possible completions.
if findenvcompletion() then do i = 1 to tree.0 say tree.i end else say "No match!"
The findmulticompletion function returns 1 if it can find a file name completion whose name matches at least an element of the space- or comma-delimited list for the element preceding the cursor position, or 0 otherwise.
If successful, tree. contains the possible completions.
if findmulticompletion('*.exe *.cmd') then do i = 1 to tree.0 say tree.i end else say "No match!"
The getArg function returns the first argument contained in cmd. An argument can contain spaces if they are enclosed in quotes. If the first argument of cmd contains no spaces, getArg is equivalent to word(cmd, 1). If the first argument contains an open quote, cmd is returned.
say getArg('dir /w') --> 'dir' say getArg('"Desktop archive"') --> '"Desktop archive"' say getArg('A" "funny" command" !') --> 'A" "funny" command"' say getArg('"Oops ...') --> '"Oops ...'
The getFileSpec function returns the (possibly) partial file name ending cmd. It also sets the fileOfs variable to point to the first symbol of the file specification.
say getFileSpec('dir c:\os2\dll') --> c:\os2\dll say getFileSpec('dir "My Desktop"') --> "My Desktop"
This function returns the home directory, followed by a trailing backslash.
The home directory is either the value of the HOME environment variable, if defined, or the root of the boot drive. No check is made to ensure that the returned directory exists, or even that it is a valid directory name.
This function reads a key from the keyboard, and returns its value, as defined by the DEFine command. If the key has not been DEFined, the key itself is returned.
As a side effect, the ckey value is set to the internal representation of the key (a "_" followed by 2 to 4 hexadecimal digits).
say getKey() --> F3 --> OSNOWAIT EXIT (ckey is _003D) say getKey() --> a --> a (ckey is _61)
This function reads an entry from the user, and returns it. It can be a multi-line entry. All currently defined editing keys can be used. If line is specified, it is the default value.
Warning: getLine can be used recursively, but the command history is shared among all calls.
This function is called when an alias execution is interrupted by the user (by using either Ctrl+C or Ctrl+Break).
Its default action is to stop the execution of the command, switch to the orgdir directory (if defined) and resume execution of the command interpreter.
This function handles mark management. It is used to remove or copy mark, and to mark word/elements. It sets the following variables: markLen, markOfs and markLine.
This function has no argument, but it uses the second word of the key variable ("word", "char", "clear", "delete", "move" or "copy"). It can only be used while in editing mode.
This function returns the string corresponding to the current prompt (as defined by the CMDSHL.PROMPT.environment (or CMDSHL.PROMPT or PROMPT) environment variable, if any). It can then be displayed by charout.
call charout, print()
This procedure read a profile file from disk, and interpret it. The real file name is derived from the profileName variable (if it is not an absolute path, it is searched via DPATH).
No return value.
[This procedure can be used to execute enhanced command scripts, that is, command script calling CmdShl-specific commands -- but keep in mind that CmdShl profiles suffer some syntax restrictions.]
profileName = 'D:\tmp\foo.cmd'; call profile 'ALIAS EXEC=RX profileName = SysSearchPath("PATH","%*"); call profile'
This procedure is called when a syntax error is detected in the profile file. It displays the offending file and line number, as well as the error message. Interpretation of the profile is aborted, but the execution of CmdShl continues.
This function returns string, where all occurrences of """ are removed. Other characters are left unchanged.
say stripdoublequotes('foo bar') --> 'foo bar' say stripdoublequotes('foo" "bar') --> 'foo bar' say stripdoublequotes('"""') --> ''
This function returns line, where all occurrences of %[n]* or %n (if any) have been replaced with the nth word of arg (or the nth word of arg and all following word if n is followed by *).
say substitute('bla bla', 'xxx') --> bla bla say substitute("it's %1 (%2)", 'yyy zzz') --> it's yyy (zzz) say substitute('%1 (%2*)', 'x y z') --> x (y z)
This section describes useful CmdShl internal variables. Please note that theses variables may evolve in future releases.
What to display when the "ALIAS /?" command is issued. You can translate this message (the recommended place to do so is in your PROFILE.SHL).
A space-delimited list of name (case is sensitive) which enumerates all defined aliases. This list is maintained automatically by the ALIAS command, but you can use it to check the existence of an alias, or ...
'ALIAS EXISTS?=RX if wordpos("%*",aliasNames) > 0 then say YES; else say NO'
The aliases definitions.
If enabled (i.e., set to 1), path conversion will be attempted on commands listed in cnvList. If disabled (i.e., set to 0, the default), no path conversion will occur.
What to display in addition to the default "CD /?" output (in fact, a description of the "CD -" and "CD path1 path2" commands). You can translate this message (the recommended place to do so is in your PROFILE.SHL)
What to display when the "CMDSHL /?" command is issued. You can translate this message (the recommended place to do so is in your PROFILE.SHL).
The list of all internal command interpreter commands, in uppercase (that is, CD, DIR, etc.). Used when command validation is enabled.
The history-list behavior. Can be 0 or 1 (the default). If cmdQueue is 1, a recalled command is moved to the end of the history list; otherwise, it remains in place.
[the default behavior mimics the CMD.EXE behavior.]
The list of all internal command interpreter commands, in uppercase, that may need path conversions, if autoPathExt is set to 1. This is a subset of cmdList.
Path extension is performed if autoPathExt is set to 1, and if the currently evaluated command is in both cmdList and cnvList.
What to display when the "DEFine /?" command is issued. You can translate this message (the recommended place to do so is in your PROFILE.SHL).
The extensions to be tried by the findcommand function. Its value is "exe cmd bat com" by default.
The position of the first symbol of the last file name specification queried by getFileSpec.
When trying to find a file name, where to stop. Used by filename completion. Its value is " =;<&>|().&" by default.
helpColor1, helpColor2 [strings]
helpColor1 contains the ANSI escape sequence to use at the beginning of the (optional) top line help string, and helpColor2 contains the ANSI escape sequence to use at the end of this string. Theses two strings should not move the cursor or ... They should only change the color attribute. Their default values is:
helpColor1='1b'x'[34;47m' -- blue on white background helpColor2='1b'x'[0m' -- default color
helpSwitches contains the list of blank-separated switches used to obtain help from an internal command. Its value is "/?" by default.
For example, if you come from an UNIX background, you may be used to type "-h" to get help. Changing helpSwitches to be "/? -h" will then suits your habits.
See HELP.COMMAND and HELP.SWITCHES for more details on how to define an optional help subsystem. (If you redefine helpSwitches in your PROFILE.SHL, this redefinition will take precedence over the HELP.SWITCHES environment variable.)
The "implied CD" (aka "executable" directories) state (1 by default, can be overridden in your PROFILE.SHL).
If impCD is 0, the "implied CD" feature is disabled. When impCD is 1, a directory name takes precedence over a possible command with no arguments. When impCD is 2, a command with no arguments takes precedence over a directory name.
To explain the difference between the 1 and 2 values, lets assume the following command was entered:
If impCD is 1, and if there exists a directory named HELP accessible via the CDPATH environment variable, the current directory will be changed to it. Otherwise, the "\OS2\HELP.CMD" command is executed.
If impCD is 2, the "\OS2\HELP.CMD" command is executed, regardless of the presence of a possible HELP directory accessible via the CDPATH environment variable. (You can naturally still reach it by issuing "help/" or "help\" or "cd help".)
How to display the cursor in insert/overwrite mode (by default, "-80 -90", i.e. a low bar, and "0 -90", i.e. a plain box).
insertMode.1 = '-80 -90' insertMode.0 = '0 -90'The two numbers for each state are the horizontal scan lines that mark the top and bottom of the cursor. 0 is the top scan line, and n-1 is the bottom one (where n is the scan lines in the character cell -- it cannot exceeds 32).
To set start line and end line independent of the number of scan lines for each character cell, you may specify these parameters as percentages. OS/2 then calculates the physical start and end scan lines, respectively, by multiplying the percentage specified for the parameter by the total number of scan lines in the character cell and rounding to the nearest scan line. Percentages are specified as negative values (or 0) in the range 0 through -100. Specifying start line = -90 and end line = -100 requests a cursor that occupies the bottom 10 percent of the character cell.
The default insertion state (1 by default, can be overridden via CmdShl's "/O" switch). Each time you start to edit a new command, the insertion state is reset to insertState value (when editing a command, you can change the insertion state by using the Ins key -- by default, but theses changes are local).
What to interpret when an invalid command is found on the command line. In addition to the usual editing variables, xlen contains the position of the first symbol of the offending command and xline is the offending command. invalidCmd default's value is
invalidCmd = "call VioWrtNAttr origRow + xlen % col, xlen // col, length(xline), 12;", "xOfs = currOfs+1"
[That is, it displays the offending command in red.]
The current recursion level of the eval command.
The previously visited directory. This variable is maintained by CmdShl's CD command.
The command string required by the STREAM build-in function to open a file in (shared) read mode only. The required value changes whether Object REXX is enabled or not. openread default value is
"open read shared"
when Object REXX is enabled and
The path extension state (0 if disabled, by default ; 1 if enabled). When enabled, extended path notations are recognized by filename completion and such. I.e., leading "~" in paths are recognized as denoting the home directory, and "..." as denoting "..\..".
Enabling path extension does not enable automatic conversions, though. In order to do that, you must set autoPathExt accordingly.
preEvalCmd, postEvalCmd [strings]
What to interpret when a command is about to be evaluated, or after it has completed. In addition to the internal variables described in this section, three variables are of interest: cmd contains the command to be executed, ucmd contains the command to be executed in uppercase, and args contains the command arguments. [Please note that the commands and args are not preprocessed in any way. Alias and variable substitution is not performed at this stage.]
By default, those strings are empty.
If we want to have a "special" _TIME variable that represent the current time, we can define:
preEvalCmd = 'call value "_TIME", time(), "OS2ENVIRONMENT"'
Then, using "ECHO %_TIME%" will display the current time. The pre- and post-eval variables are interpreted (if not empty) before and after each command. If multiple commands are provided in the command line, the pre- and post-eval variables are interpreted multiple times. Hence, in the example above, "ECHO %_TIME% & ECHO %_TIME" may display two different times.
The commands history list. prevLine.0 contains the history size.
The file name to be used by the profile() internal function.
What to display when the "QUIT /?" command is issued. You can translate this message (the recommended place to do so is in your PROFILE.SHL).
The rules definitions.
A space-delimited list of name (case is sensitive) which enumerates all defined rules. This list is maintained automatically by the RULE command, but you can use it to check the existence of a rule, or ...
'ALIAS SHOWRULE=RX if wordpos("%*",rulesList) > 0 then say rules.%*; else say "(undefined)"'
The list of enabled CmdShl internal commands (in uppercase). Used when command validation is enabled.
This section describes the variables which can be used while editing a command (that is, only usable when used in a key definition).
The current screen width.
The current cursor position in the command (first char is at currOfs 1).
If not null, we are in filename completion mode. If null, we are not (or, no longer). The "tab" and "backtab" internal actions enter completion mode. ALL OTHER internal actions exit completion mode. If you want to remain in completion mode after having used another action, add the following code after your action definition:
key = "tab"
The internal action name being executed (see currTab for an important note).
The line being edited.
The position and length of the mark. if markLen is null, there is no mark.
The edited line before its last modification.
The initial cursor position (that is to say, where the cursor was just after displaying the prompt).
The current screen height.
If tree.0 is not null, the stem contains the matching file names.
WARNING: This product does work well with Object REXX as included in DEVCON 10 or higher. It does not work well with the one included in DEVCON 8/9. 1.40.000 May 25 2006 --- New feature: o preliminary support for generic path extensions (autoPathExt and cnvList added). --- Misc. changes: o CDPATH no longer used if CDing to an absolute destination or one starting with a drive name or "./" or "../" and so on. --- Bug fix: o fixed incorrect double quotes handling in file name completion. o fixed incorrect trailing '/' or '\' handling in CD command when pathExt enabled. 1.39.000 Feb 24 2004 --- New feature: o optionally allows path extensions ('~', '...', and the likes). Set pathExt to 1 to enable. 1.38.000 Sep 16 2002 --- Bug fix: o findcommand now handles leading double quotes correctly. (I.e., entering a double quote followed by a space in a command position no longer crashes.) 1.37.000 Feb 24 2002 --- New feature: o added pre- and post-eval optional user-definable commands (preEvalCmd and postEvalCmd, respectively). 1.36.000 Nov 12 2000 --- Bug fix: o possible call to a supposedly loaded SysLoaded function now catched. 1.35.000 Sep 12 2000 --- Bug fix: o profile file (if any) is now open in shared read mode only when using Object Rexx. 1.34.000 Jul 03 2000 --- Bug fix: o profile file (if any) is now open in read mode only, so that multiple instances could start simultaneously. 1.33.000 Sep 09 1998 --- Bug fix: o incorrect behavior (and REXX/CMD.EXE bug?) when '|' abutted to a single command (i.e., things like "dir|less"). 1.32.000 Jun 26 1998 --- Misc. change: o 'file:///' recognized while completing filename. 1.31.000 Jan 28 1998 --- New feature: o %u implemented in rules. --- Bug fix: o fixed problems while completing an item specified by a %(list) rule. 1.30.000 Dec 22 1997 --- New feature: o %(list) implemented in rules. --- Misc. change: o Default rule provided for CHDIR. 1.29.000 Dec 21 1997 --- New features: o better error handling in profiles. o halt procedure added for use in aliases. 1.28.000 Dec 09 1997 --- New feature: o Optional external help subsystem added (use HELP.COMMAND and HELP.SWITCHES if defined). 1.27.000 Nov 27 1997 --- Bug fix: o CD sets RC when called (either directly or indirectly). 1.26.000 Nov 25 1997 --- Bug fix: o findcontexttype abend when called with an argument. --- Misc. changes: o Using CMDSHL.PROMPT instead of CMDSHLPROMPT. o Case sensitiveness added to rule names. --- New feature: o Added command-handler-dependent prompts (CMDSHL.PROMPT.*). 1.25.000 Nov 19 1997 [Those changes were made to unify CmdShl with Ulrich Möller's CommandPak.] --- Misc. changes: o The priority of implicit CDs is now user-definable (that is, it can now preempt or not a command with no argument). o User-definable help switch (helpSwitches) so that internal commands can use -h or whatever the user expects for obtaining help. o quitHelp added to describe QUIT usage. o SHELL allowed as OSNowait synonym. --- New feature: o If a CMDSHLPROMPT environment variable is defined, it is used in place of PROMPT. 1.24.000 Nov 15 1997 --- Misc. change: o "expand" also uses rules. So commands are expanded even when they are not in first position. 1.23.000 Nov 07 1997 --- Bug fix: o %c in findcontexttype was not initializing xline correctly (the current context was flaged as incorrect, not just the offending command). 1.22.000 Nov 06 1997 --- Bug fixes: o findcurrentcommand was returning incorrect result when command was either START or DETACH. o file was not cleared in findenvcompletion. --- Misc. changes: o %o implemented in rules. o "space" uses rules, too. 1.21.000 Nov 03 1997 --- Bug fix: o Environment variable in commands were incorrectly handled. --- Misc. change: o "expand" now also expands rules. 1.20.000 Nov 02 1997 --- Misc. changes: o '*' allowed in rules definition to denote repetition. o Default rules provided for RD and RMDIR. 1.19.000 Oct 31 1997 --- Bug fix: o RC is now a public variable. --- New features: o Enhanced rules definition. o Default rule provided for FOR. 1.18.000 Oct 23 1997 --- New features: o RULE command added. o Default rules provided for START, DETACH, CD and SET. 1.17.000 Oct 22 1997 --- New features: o Completion also completes environment variable name if the current command is 'SET'. o Rules (partialy) implemented to help providing smart completion and command checking. --- Misc. change: o Enhancing command detection algorithm. 1.16.000 Jun 17 1997 --- New feature: o A "dup" internal action added. 1.15.000 Jun 10 1997 --- Bug fix: o Quoted elements now supported in path substitution. 1.14.000 Jun 03 1997 --- Bug fixes: o Quoted command and directory names now correctly handled. o Multiple commands in "/c" and "/k" correctly handled when specified in quotes. o Incorrect display if cursor is on lower right corner and spacebar is pressed. 1.13.000 Mar 13 1997 --- Bug fix: o interactive was not initialised when using the "/k" switch. 1.12.000 Oct 07 1996 --- Bug fix: o OSNowait now accepts quoted '&'. 1.11.000 Sep 28 1996 --- Bug fix: o xOfs reseted by "esc", "match", "backmatch", "cup" and "cdown". --- Misc. changes: o Removed "STDOUT:" statements. o "space" now understands START and DETACH. 1.10.000 Sep 16 1996 --- Bug fixes: o '%' handled correctly in command name and arguments. o Filenames with '(' or ')' correctly handled during filename completion. o CD no longer overrides oldDir if not relevant. --- Misc. changes: o Enhancing CD with path substitution. 1.09.000 Sep 13 1996 --- Misc. changes: o Speeding up filename completion. o Speeding up command line display. 1.08.000 Sep 12 1996 --- Bug fixes: o "PROMPT" added in the CMD internal command list. o Fully qualidied directory path correctly recognized as a valid command when implicit CD is enabled. o Unit specification correctly recognized as a valid command. --- Misc. change: o '/' or '\' allowed at the end of directories names during CD (either implicit or explicit). 1.07.000 May 23 1996 --- Bug fixes: o '&' added to fileSeparator. o "space" handles stream redirections ('>&') correctly. o "expand" was duplicating command name when there was only spaces between cursor and command name. o '&&' correctly handled. --- Misc. change: o findcommand speed optimized when checking aliases and internal commands. 1.06.000 Apr 29 1996 --- Misc. changes: o Displaying helpString is a bit faster now. o Removing the unused assignment to line in loop:. o Executable filename extensions are stored in extList instead of beeing hardcoded. 1.05.000 Apr 19 1996 --- Bug fixes: o Fully qualified directory specifications recognized by findcommand (and hence by on the fly command checking). o The eval function is now safely recursive. --- New feature: o A new "backmatch" command. 1.04.000 Mar 26 1996 --- Bug fix: o Stream redirection (i.e., things like 2>&1) handled correctly. 1.03.000 Mar 07 1996 --- New features: o A new key-related function, MC. o "expand" now also expands aliases. o "mark move" and "mark delete" have been added (if the mark is not on current line, "mark move" do a copy, and "mark delete" do nothing). 1.02.000 Mar 05 1996 --- New feature: o The "expand" internal action also expands command name (with its path and extension, if applicable). --- Buf fixes: o getFileSpec failed if first char was '"' in arg(1) and there was an odd number of '"'. o A fully qualified path was incorrectly flagged as being an invalid command. --- Misc. changes: o RexxVIO is now required (was optional since 0.98.000). o "f1" internal action now called "match". 1.01.000 Mar 04 1996 --- New features: o A new "expand" internal action (bound to C_X by default). o Command line copy/paste added (mark char|clear|copy|word). 1.00.000 Feb 22 1996 --- New feature: o File name completion understands environment variables. 0.99.000 Feb 19 1996 --- Bug fixes: o Re-enabling environment variable substitution in 'CD' commands. o Command line checking now handles fully qualified commands. --- New feature: o User-definable file separator (fileSeparator, ' =;<&>|()' by. default). 0.98.000 Feb 15 1996 --- New feature: o If RexxVIO is present, cursor reflects insert state (insertMode, overwriteMode). 0.97.000 Feb 02 1996 --- Bug fixes: o Incorrect alias handling when no substitution was required. o Blank lines no longer emitted while processing profile file. o helpColor1 and helpColor2 are now public. --- New feature: o backtab added. 0.96.000 Nov 15 1995 --- Bug fixes: o Command line checking now handles correctly quoted "&" and "|". o Quoted "&" and "|" are now correctly handled when defining an alias from the command prompt. --- New features: o Command line checking now uses a user-defined function to warn the user (so, if you prefer an audible clue, you can define it) (invalidCmd). o The help line color is user-definable (helpColor1, helpColor2). 0.95.000 Oct 18 1995 --- New features: o CmdShl internal commands can be enabled/disabled. o Enhanced ALIAS substitution parameters (%[0-9]?[*]). 0.94.000 Oct 12 1995 --- Bug fix: o CMD.EXE quoting symbol (^) is now correctly handled. 0.93.000 Oct 11 1995 --- Bug fixes: o Command line checking handles '|', '(' and ')' correctly. o DEFINE no longer crashes if its first parameter is invalid. o "CD -" now works with implicit CDs. --- New features: o Improved command line parsing (strings and subexpressions are now recognized). o Speed improvement when using CMD.EXE internal commands. 0.92.000 Oct 06 1995 --- New features: o Implicit "CD" feature is now optional (impCD). o Optional command line checking (if a command is nonexistent, its name is highlighted). o Faster screen updates. 0.91.000 Aug 08 1995 --- Bug fixes: o Default messages are now in English. o Newline no longer automatically emitted after a RX command. --- New commands: o A new DEFINE internal command. o And two new key-related functions, TEXT and OSNOWAIT. --- New features: o An improved profile interpreter (multi-lines, REXX expression allowed in external commands). o getLine can be called recursively. o Interesting internal functions have been documented. o Some key names have been defined (for use with the DEFINE command). 0.90.000 Jul 27 1995 --- First public release