FormImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Michael Plass, June 18, 1986 3:41:14 pm PDT
A simple command for creating a new file or viewer from a form.
DIRECTORY Commander, FS, IO, Rope, TiogaMenuOps, ViewerClasses, ViewerOps, ViewerTools;
FormImpl: CEDAR PROGRAM
IMPORTS Commander, FS, IO, Rope, TiogaMenuOps, ViewerOps, ViewerTools
~ BEGIN
Viewer: TYPE ~ ViewerClasses.Viewer;
ROPE: TYPE ~ Rope.ROPE;
CanonicalWorkingDirectory: PROC [txt: ROPE, wDir: ROPENIL] RETURNS [ROPE] = {
fname: ROPENIL; cp: FS.ComponentPositions;
[fullFName: fname, cp: cp] ← FS.ExpandName[name: txt.Concat["*"], wDir: wDir
! FS.Error => CONTINUE];
IF fname=NIL THEN RETURN [NIL]
ELSE IF cp.base.length+cp.ext.length = 1 THEN RETURN [fname.Substr[len: cp.base.start]]
ELSE ERROR FS.Error[error: [group: user, code: $badDir, explanation:
Rope.Cat["\"", txt, "\" is not a valid directory."]
]]
};
MalformedName: ERROR ~ CODE;
ViewerFromForm: PROC [fileName: ROPE, formName: ROPE] RETURNS [viewer: Viewer] ~ {
fileName is the name of the new file or working directory; may be short.
Opens as an icon.
fname: ROPENIL;
cp: FS.ComponentPositions;
dirOnly: BOOLFALSE;
IF fileName # NIL THEN [fullFName: fname, cp: cp] ← FS.ExpandName[name: fileName ! FS.Error => CONTINUE];
IF fname = NIL THEN {
[fullFName: fname, cp: cp] ← FS.ExpandName[name: fileName.Concat["*"] ! FS.Error => ERROR MalformedName];
dirOnly ← TRUE;
fname ← fname.Substr[len: cp.base.start];
};
IF dirOnly
THEN {
viewer ← ViewerTools.MakeNewTextViewer[info: [name: fname, file: formName], paint: TRUE];
viewer.file ← NIL;
}
ELSE {
fname ← FS.Copy[from: formName, to: fname, setKeep: TRUE, keep: 2];
viewer ← ViewerTools.MakeNewTextViewer[info: [name: fname.Substr[len: cp.ext.start+cp.ext.length], file: fname], paint: TRUE];
};
TiogaMenuOps.DefaultMenus[viewer];
};
GetWD: PROC RETURNS [ROPE] ~ {
fname: ROPENIL;
cp: FS.ComponentPositions;
[fullFName: fname, cp: cp] ← FS.ExpandName[name: "*"];
fname ← fname.Substr[len: cp.base.start];
RETURN [fname];
};
startupDir: ROPE ← GetWD[];
searchRules: LIST OF ROPELIST[startupDir];
GetFormName: PROC [shortName: ROPE] RETURNS [fileName: ROPENIL] ~ {
action: PROC [c: CHAR] RETURNS [BOOL]
~ {RETURN [c='[ OR c='] OR c='< OR c='> OR c='/ OR c='. OR c='!]};
IF Rope.Map[base: shortName, action: action]
THEN fileName ← FS.FileInfo[shortName].fullFName
ELSE {
FOR each: LIST OF ROPE ← searchRules, each.rest DO
fileName ← FS.FileInfo[name: shortName.Concat[".form"], wDir: each.first !
FS.Error => IF error.group=user AND each.rest#NIL THEN CONTINUE
].fullFName;
IF fileName # NIL THEN RETURN;
ENDLOOP;
};
};
ViewerFromShortForm: PROC [fileName: ROPE, shortName: ROPE] RETURNS [Viewer] ~ {
RETURN [ViewerFromForm[fileName, GetFormName[shortName]]];
};
CmdTokenBreak: PROC [char: CHAR] RETURNS [IO.CharClass] = {
IF char = '← THEN RETURN [break];
IF char = ' OR char = '\t OR char = ', OR char = '; OR char = '\n THEN RETURN [sepr];
RETURN [other];
};
GetCmdToken: PROC [stream: IO.STREAM] RETURNS [rope: ROPE] = {
rope ← NIL;
rope ← stream.GetTokenRope[CmdTokenBreak ! IO.EndOfStream => CONTINUE].token;
};
FormCommand: Commander.CommandProc = {
[cmd: Commander.Handle] RETURNS [result: REF ANY ← NIL, msg: ROPE ← NIL]
stream: IO.STREAMIO.RIS[cmd.commandLine];
outputName: ROPE ← GetCmdToken[stream];
gets: ROPE ← GetCmdToken[stream];
inputName: ROPE ← GetCmdToken[stream];
viewer: Viewer ← NIL;
IF NOT gets.Equal["←"] THEN { inputName ← outputName; outputName ← NIL };
viewer ← ViewerFromShortForm[outputName, inputName !
FS.Error => IF error.group = user THEN {result ← $Failure; msg ← error.explanation; CONTINUE};
MalformedName => {result ← $Failure; msg ← Rope.Cat[" Error: `",inputName,"' is not a valid file or directory name"]};
];
IF viewer # NIL THEN ViewerOps.OpenIcon[viewer];
};
FormSearchRulesCommand: Commander.CommandProc = {
[cmd: Commander.Handle] RETURNS [result: REF ANY ← NIL, msg: ROPE ← NIL]
stream: IO.STREAMIO.RIS[cmd.commandLine];
reset: BOOLFALSE;
additions: LIST OF ROPE ~ LIST[NIL];
end: LIST OF ROPE ← additions;
FOR item: ROPE ← GetCmdToken[stream], GetCmdToken[stream] UNTIL item = NIL DO
IF Rope.Equal[item, "-r", FALSE]
THEN reset ← TRUE
ELSE {
wd: ROPENIL;
wd ← CanonicalWorkingDirectory[item ! FS.Error => IF error.group = user THEN {result ← $Failure; msg ← error.explanation; CONTINUE}];
IF result # NIL THEN RETURN;
end.rest ← LIST[wd];
end ← end.rest;
};
ENDLOOP;
IF reset THEN searchRules ← NIL;
end.rest ← searchRules;
searchRules ← additions.rest;
IF searchRules = NIL THEN searchRules ← LIST[startupDir];
cmd.out.PutRope["Forms search rules = "];
FOR each: LIST OF ROPE ← searchRules, each.rest UNTIL each = NIL DO
cmd.out.PutRope[each.first];
cmd.out.PutRope[" "];
ENDLOOP;
cmd.out.PutRope["\n"];
};
Commander.Register[key: "Form", proc: FormCommand, doc: "Make a new viewer from a form ([ newFileNameOrDirectory ← ] formName"];
Commander.Register[key: "FormSearchRules", proc: FormSearchRulesCommand, doc: "Modify the list of directories that the `Form' command uses (-r resets the old list; paths are added to the list)"];
END.