<> <> <> <<>> <> <<>> 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: ROPE _ NIL] RETURNS [ROPE] = { fname: ROPE _ NIL; 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] ~ { <> <> fname: ROPE _ NIL; cp: FS.ComponentPositions; dirOnly: BOOL _ FALSE; 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: ROPE _ NIL; 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 ROPE _ LIST[startupDir]; GetFormName: PROC [shortName: ROPE] RETURNS [fileName: ROPE _ NIL] ~ { 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.STREAM _ IO.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.STREAM _ IO.RIS[cmd.commandLine]; reset: BOOL _ FALSE; 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: ROPE _ NIL; 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.