Edited by Teitelman on June 24, 1983 10:56 am
Note: if you import this interface, make sure that either the UserExecutive has been run, or else that you explicitly run CommandProcOpsImpl.bcd
The purpose of this interface is to provide various conveniences when invoking lower level facilities, such as Resource, AskUser, and the spelling corrector, for clients that register commands via Commander.Register. These conveniences include the ability to call the spelling corrector or AskUser by simply specifying a Commander.Handle and having the appropriate arguments for confirming, aborting, etc. be constructed using the Handle. Note that a similar set of conveniences are available through the UserExec interface for clients that register commands via UserExec.Register.
All of these procedures are written so that when invoked from an event that was originally typed into a UserExec Work Area, they operate by obtaining the UserExec.ExecHandle and calling the corresponding UserExec procedures. Thus, for example, AskUser will allow response either vai keyboard or menu, and will correctly handle the problem of typeahead. When called from an event that originated in a CommandTool tool, they still perform the corresponding operation, but with restricted functionality and features. For example, AskUser will use the keyboard for interaction, but will not post any menus.
This interface is implemented via CommandProcOpsImpl, which while dependent on the UserExec interface, is not dependent on the UserExec implementation, except when an event has been typed into a work area, which can only occur when the UserExecutive has been loaded. In other words, CommandProcOpsImpl can be loaded into a leaner meaner cedar to enable execution of command procs that import CommandProcOps, and everything will continue to work. For example, if the spelling corrector has not been loaded, then all spelling corrector operations will operate as though they could not find a correction.
DIRECTORY
Commander USING [Handle],
IO USING [STREAM, UserAbort, SetUserAbort, ResetUserAbort, UserAborted],
Rope USING [ROPE],
Spell USING [SpellingList, SpellingGenerator, Filter, Modes]
;
CommandProcOps: CEDAR DEFINITIONS IMPORTS IO =
BEGIN
Synonym Types
ROPE: TYPE = Rope.ROPE;
Aborting: UserAbort, UserAborted
CheckForAbort: PROC [handle: Commander.Handle, msg: ROPENIL]
= INLINE {IF handle # NIL AND UserAbort[handle] THEN UserAborted[handle, msg]};
UserAborted: PROC [handle: Commander.Handle, msg: ROPENIL]
= INLINE {ERROR IO.UserAborted[handle, msg]};
UserAbort: PROC [handle: Commander.Handle] RETURNS [abort: BOOLEAN]
= INLINE {RETURN[IO.UserAbort[handle.in] OR IO.UserAbort[handle.out]]};
returns TRUE if the user has requested an abort of the operation running in corresponding handle. The client program is responsible for effecting the abort, which is typically performed by raising the signal UserAborted.
SetUserAbort: PROC [handle: Commander.Handle]
sets the user abort, i.e. provides a programmable way to abort (the operation currently running in) an exec.
= INLINE {IO.SetUserAbort[handle.in]; IO.SetUserAbort[handle.out]};
ResetUserAbort: PROC [handle: Commander.Handle]
turn the abort bit off.
= INLINE {IO.ResetUserAbort[handle.in]; IO.ResetUserAbort[handle.out]};
EventFailed: PROC [handle: Commander.Handle, msg: ROPE ← NIL, offender: ROPENIL];
for use from inside of a commandProc to indicate that the commandProc was not successful. offender is the "bad guy", e.g. if msg is File Not Found: Foo.mesa, offender would be Foo.mesa.
When called from a commandtool, this simply prints msg and returns. When the corresponding event was invoked under a work area, if msg # NIL, terminates the event by raising a signal. The event is also marked as having failed so that if it appears as part of a compound event, e.g., compile fooimpl; bind foo; run foo, the subsequent events will not be executed. If msg = NIL, EventFailed simply records the offender in the event as a bad guy and goes on. This is for use in conjunction with various history commands.
Confirmation: AskUser, Confirm
AskUser provides for a standard way of interacting with the user to obtain one of a small, specified set of responses, such as Yes or No, or Yes, No, All, or Quit. If the Commander.Handle in reality was constructed by the UserExec, i.e. if the corresponding event was executed in a WorkArea, then AskUser will simply call through to the UserExec.AskUser. In this case, the case of typeahead will be handled correctly by allowing the user to respond via menu buttons etc. Otherwise, i.e. if the corresponding event was executed in a CommanderTool, then interaction will only be via the keyboard, and typeahead will be taken as response to the indicated question.
AskUser: PROC [msg: ROPE, timeout: INT ← -1, defaultKey: ATOMNIL, handle: Commander.Handle ← NIL, keyList: LIST OF ATOMNIL] RETURNS[value: ATOM];
provides a standard way of asking a user to respond/confirm to a proposed operation using either the specified exec, or viewer. keyList = NIL => LIST[$Yes, $No].
If handle = NIL and if keyList = NIL, i.e. the client simply wants a yes no confirmation, the message is posted in the message window and MessageWindow.Confirm is used for confirmation, which then gets translated back into $Yes or $No. Otherwise, AskUser simply returns NIL.
Confirm: PROC [msg: ROPE, timeout: INT ← -1, defaultConfirm: BOOLFALSE, handle: Commander.Handle ← NIL] RETURNS[BOOLEAN]
= INLINE {RETURN[AskUser[msg: msg, timeout: timeout, defaultKey: IF defaultConfirm THEN $Yes ELSE $No, handle: handle] = $Yes]};
Invoking spelling corrector via Commander Handle: GetTheOne, GetMatchingList, GetTheFile, GetMatchingFileList
The procedures described below enable invoking the spelling corrector using a Commander.Handle for feedback and confirmation. (If the spelling corrector has not been loaded, i.e. user is running in "leaner meaner cedar", then they all return NIL.) If the Commander.Handle in reality was constructed by the UserExec, i.e. if the corresponding event was executed in a WorkArea, then these procedures call through to the corresponding UserExec procedures. Otherwise, i.e. if the corresponding event was executed in a CommanderTool but in a full Cedar system, the spelling corrector is called but confirmation and aborting are performed via the keyboard only. If handle = NIL, then output will go to the message window, and confirmation will be via MessageWindow.Confirm.
GetTheOne: PROCEDURE [
unknown: ROPE,
spellingList: Spell.SpellingList ← NIL,
generator: Spell.SpellingGenerator ← NIL,
handle: Commander.Handle ← NIL,
filter: Spell.Filter ← NIL,
modes: Spell.Modes ← NIL
]
RETURNS [correct: ROPE];
GetMatchingList: PROCEDURE [
unknown: ROPE,
spellingList: Spell.SpellingList ← NIL,
generator: Spell.SpellingGenerator ← NIL,
handle: Commander.Handle ← NIL,
filter: Spell.Filter ← NIL,
modes: Spell.Modes ← NIL
]
RETURNS [matches: LIST OF ROPE];
GetTheFile: PROC [
file: ROPE,
defaultExt: ROPENIL,
handle: Commander.Handle ← NIL,
modes: Spell.Modes ← NIL
]
RETURNS [correct: ROPE];
First checks to see if file (or file.defaultExt) exists, and if so, returns immediately.
GetMatchingFileList: PROC [
file: ROPE,
defaultExt: ROPENIL,
handle: Commander.Handle,
modes: Spell.Modes ← NIL
] RETURNS[matches: LIST OF ROPE];
Acquire, Release: AcquireResource, ReleaseResource
The Resource interface contains facilities for managing resources that support only one client at a time (e.g. Compiler, Binder, DFFile software). This version of Acquire takes a Commander Handle as an argument and emulates the behavior of UserExec.AcquireResource, i.e. if waitForIt = TRUE, and the resource is busy, a message is printed informing the user. The call to Resource.Acquire supplies an appropriate abortProc for aborting via in this handle.
Acquire: PROC [
resource: REF ANY,
waitForIt: BOOLFALSE,
owner: Rope.ROPENIL,
handle: Commander.Handle
] RETURNS[success: BOOL, ownedBy: Rope.ROPE];
Calls through to Resource.Acquire with an appropraite abortProc. If waitForIt = TRUE, and the resource is busy, first prints a message informing user.
Release: PROC [resource: REF ANY] RETURNS[success: BOOL];
same as Resource.Release.
miscellaneous
CheckForFile: PROC [file: ROPE] RETURNS [found: BOOLEAN];
returns TRUE if file is on the local disk
PutProperty: PROCEDURE [handle: Commander.Handle, key: REF ANY, val: REF ANY, thisEventOnly: BOOLFALSE] ;
if thisEventOnly is TRUE, the property is added to the handle in such a fashion that it will NOT be seen for subsequent events. If FALSE, the property will be seen, i.e. is a permanent change.
END. -- CommanderOps
WaitUntilSaved