DIRECTORY AMBridge USING [TVForReferent], AMModel USING [ContextName, ParentContext], BBContext USING [GlobalFrameSearch], Buttons USING [Create], DeskTops USING [Create], Directory USING [Lookup, ignore, GetProps], File USING [Capability], Icons USING [IconFlavor], InputFocus USING [GetInputFocus], IO USING [char, CharsAvail, CreateOutputStreamToRope, EndOfStream, Flush, GetChar, GetOutputStreamRope, GetToken, IDProc, int, Put, PutF, PutTV, ROPE, rope, Signal, STREAM, TokenProc, TV, WhiteSpace], Menus USING [AppendMenuEntry, MenuEntry, ClickProc, CreateEntry, Menu], MessageWindow USING [Append, Blink], Process USING [Detach, Pause], Rope USING [Cat, Concat, Equal, Find, IsEmpty, Length, Replace, ROPE, Substr], Spell USING [defaultModes], TiogaMenuOps USING [Open, DefaultMenus, Save], TiogaOps USING [GetSelection, GetTextKey, LastLocWithin, TextKeyNotFound, ViewerDoc, SelectPoint, Location, SelectionGrain], TypeScript USING [Create], UserExec USING [CheckForAbort, CommandProc, Confirm, CreateUserExecutive, ExecHandle, GetExecHandle, GetStreams, HistoryEvent, HistoryList, MethodProc, RegisterCommand, RegisterMethod, SetUserResponse, StartListening, UserAborted], UserExecExtras USING [], UserExecPrivate USING [CaptionForExec, DestroyExec, execHandleList, ExecPrivateRecord, GetPrivateStuff, HistoryEventPrivateRecord, version, SplitViewerProc, StoreInSymTab], UserProfile USING [Boolean, ProfileChanged, GetErrorLog], ViewerAbort USING [SetUserAbort], ViewerClasses USING [Column, Viewer], ViewerEvents USING [EventProc, RegisterEventProc], ViewerLocks USING [CallUnderColumnLock], ViewerOps USING [ComputeColumn, CreateViewer, DestroyViewer, FindViewer, OpenIcon], ViewerTools USING [GetSelectedViewer, GetSelectionContents, SelPos, SetSelection] ; ViewerExecOpsImpl: CEDAR PROGRAM IMPORTS AMBridge, AMModel, BBContext, Buttons, DeskTops, Directory, InputFocus, IO, Menus, MessageWindow, Process, Rope, Spell, TiogaMenuOps, TiogaOps, TypeScript, UserExec, UserExecPrivate, UserProfile, ViewerAbort, ViewerEvents, ViewerLocks, ViewerOps, ViewerTools EXPORTS UserExec, UserExecExtras, UserExecPrivate SHARES UserProfile = BEGIN OPEN IO; ExecHandle: TYPE = UserExec.ExecHandle; HistoryEvent: TYPE = UserExec.HistoryEvent; Viewer: TYPE = ViewerClasses.Viewer; ClickProc: TYPE = Menus.ClickProc; ExecPrivateRecord: PUBLIC TYPE = UserExecPrivate.ExecPrivateRecord; HistoryEventPrivateRecord: PUBLIC TYPE = UserExecPrivate.HistoryEventPrivateRecord; CreateExecProc: UserExec.CommandProc = { private: REF ExecPrivateRecord = exec.privateStuff; CreateExec[private.evalMode]; }; CreateExec: PROC [evalMode: BOOL] = { exec: UserExec.ExecHandle = UserExec.CreateUserExecutive[paint: FALSE, startListening: FALSE, iconic: TRUE]; viewer: ViewerClasses.Viewer = exec.viewer; private: REF ExecPrivateRecord = exec.privateStuff; private.evalMode _ evalMode; [] _ UserExecPrivate.CaptionForExec[exec: exec, paint: FALSE]; ViewerOps.OpenIcon[viewer]; ViewerTools.SetSelection[viewer]; UserExec.StartListening[exec]; }; DestroyExec: UserExec.CommandProc = TRUSTED { IF exec = NIL THEN RETURN[FALSE]; IF UserExecPrivate.execHandleList.rest = NIL THEN Process.Detach[FORK CreateNewWorkAreaButton[]]; UserExecPrivate.DestroyExec[exec]; }; newWorkAreaButtonUp: BOOL _ FALSE; CreateNewWorkAreaButton: PROC = { IF NOT newWorkAreaButtonUp THEN { [] _ Buttons.Create[info: [name: "Exec"], documentation: "Create New Work Area", proc: NewExec]; newWorkAreaButtonUp _ TRUE; }; }; Herald: UserExec.CommandProc = { commandLine: ROPE = event.commandLine; out: STREAM; IF exec = NIL THEN RETURN; out _ UserExec.GetStreams[exec].out; out.PutF["*n"]; out.Flush[]; [] _ exec.viewer.class.scroll[self: exec.viewer, op: up, amount: LAST[INTEGER]]; out.PutF[UserExecPrivate.version]; out.PutF[commandLine]; }; ChangeAreaMode: UserExec.CommandProc = { private: REF ExecPrivateRecord = exec.privateStuff; private.evalMode _ NOT private.evalMode; [] _ UserExecPrivate.CaptionForExec[exec]; }; Desktop: UserExec.CommandProc = TRUSTED { commandLineStream: STREAM = event.commandLineStream; name: ROPE; name _ IO.GetToken[commandLineStream, IO.IDProc]; IF Rope.IsEmpty[name] THEN name _ "Default"; [] _ DeskTops.Create[name: name]; RETURN[TRUE]; }; NewExec: ClickProc -- PROC [viewer: Viewer, clientData: REF ANY, redButton: BOOL] -- = { CreateExec[(mouseButton = blue)]; }; Stop: ClickProc -- [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: MouseButton _ red, shift, control: BOOL _ FALSE] -- = { viewer: Viewer = NARROW[parent]; exec: ExecHandle = FindExecFromViewer[viewer]; private: REF UserExecPrivate.ExecPrivateRecord = UserExecPrivate.GetPrivateStuff[exec]; stream: IO.STREAM; stream _ private.in; UNTIL stream = NIL DO FlushChars: PROC [stream: IO.STREAM] = { WHILE stream.CharsAvail[] DO [] _ stream.GetChar[! IO.Signal => IF ec = Rubout THEN CONTINUE; ]; ENDLOOP; }; FlushChars[stream]; stream _ stream.backingStream; -- so that if user mistakenly stuffs a large amount of text, can clear it out. ENDLOOP; ViewerAbort.SetUserAbort[viewer]; UserExec.SetUserResponse[viewer, NIL]; -- in case exec is waiting on confirmation. }; CompileButton: ClickProc -- [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: MouseButton _ red, shift, control: BOOL _ FALSE] -- = { viewer: Viewer = NARROW[parent]; exec: ExecHandle = FindExecFromViewer[viewer]; selectedViewer: Viewer _ ViewerTools.GetSelectedViewer[]; sel: Rope.ROPE _ ViewerTools.GetSelectionContents[]; r: ROPE; pointSel: BOOL _ FALSE; Failed: PROC [rope: ROPE] = TRUSTED { MessageWindow.Append[rope, TRUE]; -- don't acquire streams, because may already be acquired. MessageWindow.Blink[]; }; FindConfig: PROC [name: ROPE] RETURNS[config: ROPE] = TRUSTED { tv: TV; i: INT; IF Rope.Find[s1: name, s2: ".config", case: FALSE] # -1 THEN RETURN[Rope.Concat[name, "\n"]]; IF (i _ Rope.Find[name, "."]) # -1 THEN name _ Rope.Substr[base: name, len: i]; tv _ BBContext.GlobalFrameSearch[context: NIL, frameName: name].gf; IF tv # NIL THEN {ENABLE ANY => CONTINUE; name: ROPE = AMModel.ContextName[AMModel.ParentContext[tv]]; IF NOT Rope.IsEmpty[name] AND (i _ Rope.Find[name, ":"]) # -1 THEN config _ Rope.Substr[base: name, len: Rope.Find[name, ":"]]; }; IF Rope.IsEmpty[config] THEN {MessageWindow.Append[Rope.Concat["Couldn't find config containing ", name], TRUE]; MessageWindow.Blink[]; }; }; IF selectedViewer = NIL THEN {Failed["No selected viewer"]; RETURN}; IF Rope.Length[sel] <= 1 THEN { IF selectedViewer.class.flavor # $Text THEN {Failed["Selected viewer not a tioga document"]; RETURN}; pointSel _ TRUE; sel _ selectedViewer.name; -- point selection, compile indicated viewer }; IF ViewerTools.GetSelectedViewer[] # viewer THEN ViewerTools.SetSelection[viewer, NIL]; { i: INT _ 0; WHILE (i _ Rope.Find[s1: sel, s2: "\n", pos1: i]) # -1 DO IF i + 1 < Rope.Length[sel] THEN sel _ Rope.Replace[base: sel, start: i, len: 1, with: " "]; i _ i + 1; ENDLOOP; }; SELECT mouseButton FROM red => r _ Rope.Cat[IF Rope.Find[s1: sel, s2: ".config", case: FALSE] # -1 THEN "Bind " ELSE "Compile ", sel, "\n"]; yellow => IF NOT pointSel THEN r _ Rope.Cat["Bind ", sel, "\n"] ELSE IF NOT Rope.IsEmpty[r _ FindConfig[sel]] THEN r _ Rope.Cat["Bind ", r]; blue => {r _ FindConfig[sel]; IF Rope.IsEmpty[r] THEN r _ "??"; r _ Rope.Cat["Compile ", sel, "; Bind ", r]; }; ENDCASE => ERROR; IF NOT Rope.IsEmpty[r] THEN StuffIt[exec, Rope.Cat["\021", r]];-- control q to erase any typeahead on the line. }; EvalButton: ClickProc -- [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: MouseButton _ red, shift, control: BOOL _ FALSE] -- = { viewer: Viewer = NARROW[parent]; exec: ExecHandle = FindExecFromViewer[viewer]; selectedViewer: Viewer _ ViewerTools.GetSelectedViewer[]; sel: Rope.ROPE _ ViewerTools.GetSelectionContents[]; Failed: PROC [rope: ROPE] = TRUSTED { MessageWindow.Append[rope, TRUE]; -- don't acquire streams, because may already be acquired. MessageWindow.Blink[]; }; IF selectedViewer = NIL THEN {Failed["No selection"]; RETURN}; StuffIt[exec, IF mouseButton = blue THEN "\021CurrentSelection\n" ELSE Rope.Cat["\021", "_ ", sel, "\n"]];-- control q to erase any typeahead on the line. }; RedoButton: Menus.ClickProc -- [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: MouseButton _ red, shift, control: BOOL _ FALSE] -- = { viewer: Viewer = NARROW[parent]; exec: UserExec.ExecHandle = FindExecFromViewer[viewer]; start, end: HistoryEvent; startsPrivateStuff, endsPrivateStuff: REF HistoryEventPrivateRecord; out: STREAM = CreateOutputStreamToRope[]; [start, end] _ GetEventsFromSelection[exec]; IF start = NIL THEN RETURN; startsPrivateStuff _ start.privateStuff; endsPrivateStuff _ end.privateStuff; FOR i: NAT IN [startsPrivateStuff.eventNum..endsPrivateStuff.eventNum] DO out.Put[char[' ], int[i]]; ENDLOOP; StuffIt[exec, Rope.Cat["\021", "Redo", IO.GetOutputStreamRope[out], IF mouseButton = red THEN "\n" ELSE "\030"]]; }; StuffIt: PUBLIC PROCEDURE [exec: UserExec.ExecHandle, rope: ROPE, list: LIST OF REF ANY _ NIL] = { private: REF UserExecPrivate.ExecPrivateRecord = UserExecPrivate.GetPrivateStuff[exec]; viewer: Viewer = exec.viewer; IF TiogaOps.GetSelection[].viewer = viewer THEN TiogaOps.SelectPoint[viewer: viewer, caret: TiogaOps.LastLocWithin[TiogaOps.ViewerDoc[viewer]]]; IF NOT Rope.IsEmpty[rope] THEN viewer.class.notify[viewer, LIST[rope]]; IF list # NIL THEN viewer.class.notify[viewer, list]; }; GetEventsFromSelection: PUBLIC PROC [exec: UserExec.ExecHandle] RETURNS [start, end: HistoryEvent] = { viewer: ViewerClasses.Viewer; private: REF UserExecPrivate.ExecPrivateRecord = UserExecPrivate.GetPrivateStuff[exec]; loc1, loc2: TiogaOps.Location; [viewer, loc1, loc2] _ TiogaOps.GetSelection[]; IF FindExecFromViewer[viewer] # exec THEN RETURN[private.historyList.first, private.historyList.first]; -- selection is in some other viewer other than the one containing the redo button IF loc1.node # loc2.node THEN ERROR; -- should worry about being in separate nodes FOR l: UserExec.HistoryList _ private.historyList, l.rest UNTIL l = NIL DO event: HistoryEvent = l.first; loc: TiogaOps.Location = TiogaOps.GetTextKey[node: loc1.node, key: l.first ! TiogaOps.TextKeyNotFound => GOTO Cant]; IF loc.node # loc1.node THEN ERROR; IF end = NIL AND loc.where < loc2.where THEN end _ event; IF loc.where < loc1.where THEN {start _ event; RETURN}; ENDLOOP; EXITS Cant => { MessageWindow.Append[message: "Can't find corresponding event", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN; }; }; NewProc: UserExec.CommandProc = { commandLineStream: STREAM = event.commandLineStream; name: ROPE; UNTIL Rope.IsEmpty[name _ IO.GetToken[commandLineStream, IO.WhiteSpace ! IO.EndOfStream => GOTO Out]] DO OpenViewer[name: name, event: event, exec: exec, newViewer: TRUE]; ENDLOOP; EXITS Out => RETURN; }; OpenProc: UserExec.CommandProc = { commandLineStream: STREAM = event.commandLineStream; name: ROPE; UNTIL Rope.IsEmpty[name _ IO.GetToken[commandLineStream, IO.WhiteSpace ! IO.EndOfStream => GOTO Out]] DO OpenViewer[name: name, event: event, exec: exec, newViewer: FALSE]; ENDLOOP; EXITS Out => RETURN; }; ImplicitOpen: UserExec.MethodProc = { commandLineStream: STREAM = event.commandLineStream; name: ROPE; UNTIL Rope.IsEmpty[name _ IO.GetToken[commandLineStream, IO.WhiteSpace ! IO.EndOfStream => GOTO Out]] DO IF Rope.Find[s1: name, s2: ".mesa", case: FALSE] = -1 THEN RETURN[FALSE]; OpenViewer[name: name, event: event, exec: exec, newViewer: FALSE]; ENDLOOP; EXITS Out => RETURN; }; OpenViewer: PROC [name: ROPE, event: HistoryEvent, exec: ExecHandle, newViewer: BOOLEAN _ FALSE] = { viewer: Viewer; out: IO.STREAM = UserExec.GetStreams[exec].out; IF newViewer THEN { proc: PROC = { viewer _ ViewerOps.CreateViewer[flavor: $Text, info: [name: IF Rope.IsEmpty[name] THEN "No Name" ELSE name, file: name, iconic: FALSE], paint: FALSE]; TiogaMenuOps.DefaultMenus[viewer, FALSE]; -- does not recompute column }; ViewerLocks.CallUnderColumnLock[proc, left]; ViewerOps.ComputeColumn[viewer.column]; } ELSE viewer _ TiogaMenuOps.Open[name-- , exec.viewer --]; -- workaround IF viewer = NIL THEN out.PutF["*n*mViewer file not found: %g*s", rope[name]] ELSE TRUSTED { tv: TV = AMBridge.TVForReferent[NEW[ViewerClasses.Viewer _ viewer]]; out.PutF["*nCreated Viewer: %g\n", rope[viewer.name]]; out.PutTV[tv: tv]; UserExecPrivate.StoreInSymTab[value: tv, event: event, exec: exec]; }; }; DirectoryLookup: PROC [name: LONG STRING] = TRUSTED { f: File.Capability _ Directory.Lookup[fileName: name, permissions: Directory.ignore]; [] _ Directory.GetProps[f, name]; }; FindExecFromViewer: PUBLIC PROC [viewer: Viewer] RETURNS [ExecHandle] = { FOR lst: LIST OF ExecHandle _ UserExecPrivate.execHandleList, lst.rest UNTIL lst = NIL DO v1: Viewer _ NARROW[lst.first.viewer]; v2: Viewer; IF v1 = viewer THEN RETURN[lst.first]; IF (v2 _ v1.link) # NIL THEN UNTIL v2 = v1 DO IF v2 = viewer THEN RETURN[lst.first]; v2 _ v2.link; ENDLOOP; ENDLOOP; RETURN[NIL]; }; CurrentSelection: UserExec.CommandProc = { value: REF ANY; handle: UserExec.ExecHandle; TiogaSelection: TYPE = RECORD[ viewer: Viewer, start, end: TiogaOps.Location, level: TiogaOps.SelectionGrain, caretBefore: BOOL, pendingDelete: BOOL ]; TiogaSelection1: TYPE = RECORD[ handle: UserExec.ExecHandle, viewer: Viewer, start, end: TiogaOps.Location, level: TiogaOps.SelectionGrain, caretBefore: BOOL, pendingDelete: BOOL ]; sel: TiogaSelection; [sel.viewer, sel.start, sel.end, sel.level, sel.caretBefore, sel.pendingDelete] _ TiogaOps.GetSelection[]; IF sel.viewer = NIL THEN { viewer: Viewer _ ViewerTools.GetSelectedViewer[]; IF viewer # NIL THEN { IF (handle _ UserExec.GetExecHandle[viewer: viewer]) # NIL THEN value _ NEW[UserExec.ExecHandle _ handle] ELSE value _ NEW[ViewerClasses.Viewer _ viewer]; }; } ELSE { IF (handle _ UserExec.GetExecHandle[viewer: sel.viewer]) # NIL THEN value _ NEW[TiogaSelection1 _ [handle, sel.viewer, sel.start, sel.end, sel.level, sel.caretBefore, sel.pendingDelete]] ELSE value _ NEW[TiogaSelection _ sel]; }; IF value = NIL THEN UserExec.GetStreams[exec].out.PutF["*n*mNothing selected\n"] ELSE TRUSTED { tv: TV = AMBridge.TVForReferent[value]; UserExec.GetStreams[exec].out.PutTV[tv: tv]; UserExecPrivate.StoreInSymTab[value: tv, event: event, exec: exec]; }; }; ForAllSplitViewers: PUBLIC PROC [viewer: Viewer, proc: UserExecPrivate.SplitViewerProc] = { v: Viewer _ viewer; proc[viewer]; WHILE (v _ v.link) # NIL AND (v # viewer) DO proc[v]; ENDLOOP; }; WaitUntilSaved: PUBLIC PROC [fileName: ROPE, exec: UserExec.ExecHandle] = { viewer: Viewer = ViewerOps.FindViewer[fileName]; IF viewer # NIL AND viewer.newVersion THEN { SomeSaveInProgress: PROC RETURNS[someSaveInProgress: BOOL _ FALSE] = CHECKED { v: Viewer _ viewer; IF viewer.saveInProgress THEN RETURN[TRUE]; WHILE (v _ v.link) # NIL AND (v # viewer) DO IF v.saveInProgress THEN RETURN[TRUE]; ENDLOOP; RETURN[FALSE]; }; WaitForSaveToComplete: PROC [exec: ExecHandle] = CHECKED { WHILE SomeSaveInProgress[] OR viewer.newVersion -- save may not have started yet -- DO Process.Pause[100]; UserExec.CheckForAbort[exec]; ENDLOOP; }; out: IO.STREAM; IF NOT SomeSaveInProgress[] THEN { IF UserProfile.Boolean["Compiler.AutoSave", FALSE] THEN NULL ELSE IF NOT UserExec.Confirm[msg: Rope.Concat["Save ", viewer.name], timeout: Spell.defaultModes.timeout, defaultConfirm: Spell.defaultModes.defaultConfirm, exec: exec] THEN UserExec.UserAborted[exec]; }; out _ UserExec.GetStreams[exec].out; IF SomeSaveInProgress[] THEN -- if we get to here, either a save is in progress, or the user said it was ok to save. The reason for calling SomeSaveInProgress again is that if the user clicked Save and then called compile, the save might not have started at the time the user was asked whether or not to save above. While he was responding to that question, the save got started. TRUSTED { out.PutF["*n*mWaiting for %g to finish being saved...", rope[viewer.name]]; WaitForSaveToComplete[exec]; } ELSE { out.PutF["*n*mSaving %g...", rope[viewer.name]]; TiogaMenuOps.Save[viewer]; WaitForSaveToComplete[exec]; }; out.PutF["ok*s\n"]; } }; WasProfileEdited: ViewerEvents.EventProc -- [viewer: ViewerClasses.Viewer, event: ViewerEvent] -- = { name: ROPE = viewer.name; pos: INT = Rope.Find[name, "."]; IF pos # -1 AND Rope.Equal["profile", Rope.Substr[base: name, start: pos + 1], FALSE] THEN TRUSTED {Process.Detach[FORK ProcessProfile[]]}; }; WasAnExecDestroyed: ViewerEvents.EventProc -- [viewer: ViewerClasses.Viewer, event: ViewerEvent] -- = { exec: ExecHandle = FindExecFromViewer[viewer]; IF exec # NIL THEN { v: Viewer _ viewer; WHILE (v _ v.link) # NIL AND (v # viewer) DO -- split IF NOT v.destroyed THEN { exec.viewer _ v; IF ViewerTools.GetSelectedViewer[] = viewer THEN ViewerTools.SetSelection[v, NIL]; RETURN; }; ENDLOOP; [] _ DestroyExec[event: NIL, exec: exec]; }; }; ProcessProfile: PUBLIC PROC = { errorLog: ROPE; MessageWindow.Append[message: "Processing User Profile for changed entries...", clearFirst: TRUE]; UserProfile.ProfileChanged[edit]; IF (errorLog _ UserProfile.GetErrorLog[]) # NIL THEN MessageWindow.Append[Rope.Cat["problems encountered, see ", errorLog, "..."]]; MessageWindow.Append["Done"]; IF errorLog # NIL THEN MessageWindow.Blink[]; }; experimentalNewFeatures: PUBLIC BOOLEAN; execMenu: PUBLIC Menus.Menu _ NIL; Init: PROC = { viewer: ViewerClasses.Viewer = TypeScript.Create[info: [], paint: FALSE]; execMenu _ viewer.menu; ViewerOps.DestroyViewer[viewer]; -- created solely to get hold of the menu Menus.AppendMenuEntry[menu: execMenu, entry: Menus.CreateEntry[name: "New", proc: NewExec, documentation: "Create New Work Area", fork: FALSE]]; -- not forked since is going to change the input focus Menus.AppendMenuEntry[menu: execMenu, entry: Menus.CreateEntry[name: "Stop", proc: Stop, documentation: "Aborts current operation", fork: FALSE]]; Menus.AppendMenuEntry[menu: execMenu, entry: Menus.CreateEntry [name: "Compile", proc: CompileButton, fork: TRUE, documentation: "Compiles the indicated file/viewer, first saving contents if edits have been performed."]]; Menus.AppendMenuEntry[menu: execMenu, entry: Menus.CreateEntry [name: "Eval", proc: EvalButton, fork: TRUE, documentation: "Evaluates the current selection in the corresponding work area."]]; Menus.AppendMenuEntry[menu: execMenu, entry: Menus.CreateEntry[name: "Redo", proc: RedoButton, documentation: "Redo selected event(s)"]]; }; UserExec.RegisterCommand["New", NewProc, "Create new viewer(s)."]; UserExec.RegisterCommand["Open", OpenProc, "Create viewer(s) on existing file(s)."]; UserExec.RegisterMethod[proc: ImplicitOpen, name: "Implicit Open", doc: "If the first token on the input line is of the form file.mesa, same as Open file.mesa, i.e. creates a viewer on file.mesa."]; UserExec.RegisterCommand["DestroyExec", DestroyExec, "Terminates an executive."]; UserExec.RegisterCommand["CreateExec", CreateExecProc, "Creates a new executive.", "Creates a new executive."]; UserExec.RegisterCommand["Desktop", Desktop, "Creates a new desktop with the given name."]; UserExec.RegisterCommand["Herald", Herald, "Scrolls executive to top and reprints herald."]; UserExec.RegisterCommand["ChangeAreaMode", ChangeAreaMode, "Makes an Interpreter into an Executive and vice versa."]; UserExec.RegisterCommand["CurrentSelection", CurrentSelection, "Describes the selected object.", "Describes the selected object. Not terribly useful unless invoked via (right clicking) the Eval menu button."]; [] _ ViewerEvents.RegisterEventProc[proc: WasProfileEdited, event: save, filter: $Text, before: FALSE]; [] _ ViewerEvents.RegisterEventProc[proc: WasAnExecDestroyed, filter: $Typescript, event: destroy]; Init[]; END. Pedited by Teitelman June 20, 1983 3:27 pm Type Definitions connecting concrete and opaque types to access evalMode in CreateExecProc, CreateExec, and ChangeAreaMode, and historyList in GetEventsFromSelection to access eventNum in RedoButton Creating and Destroying Execs Exec Buttons: Stop, Compile, Eval, Redo Viewer related operations Miscellaneous Initialization Edited on December 8, 1982 9:52 pm, by Teitelman fixed bug in RunCompiler causing bogus compiler.log when spelling correction failed changes to: RunCompiler Edited on December 9, 1982 2:00 pm, by Teitelman yellow button => bind, blue button => compile and bind changes to: CompileButton, DIRECTORY, IMPORTS Edited on December 17, 1982 3:44 pm, by Teitelman New button now creates a new interpreter area if clicked with blue, otherwise an executive area, rather than flipping the mode of the previous area. changes to: NewExec, UserExec.RegisterCommand["CreateExec" Edited on December 21, 1982 3:26 pm, by Teitelman changes to: DIRECTORY, IMPORTS, ProcessLine, NameDesktop, DoViewerOp, ImplicitOpen Edited on January 23, 1983 7:42 pm, by Teitelman changes to: EvalButton Edited on January 29, 1983 1:57 pm, by Teitelman changes to: DIRECTORY, IMPORTS, ShowResult, NewProc, OpenProc, ImplicitOpen, OpenViewer, UserExec, UserExec, NewProc, binderRec, RunCompiler Edited on February 1, 1983 8:38 pm, by Teitelman changes to: RunCompiler, DIRECTORY, Compile, Bind, ShowLog, DIRECTORY, compilerRec, Compile Edited on February 3, 1983 12:42 pm, by Teitelman changes to: BinderRec, RunCompiler, CFinishItem, ShowLog, TiogaMenuOpsOpen, BlinkIcon, DIRECTORY, Compile Edited on February 4, 1983 3:17 pm, by Teitelman changes to: CFinishItem Edited on February 7, 1983 1:41 pm, by Teitelman changes to: NameDesktop, Desktop, NewExec, UserExec, UserExec Edited on March 1, 1983 4:00 pm, by Teitelman changes to: newWorkAreaButtonUp, CreateNewWorkAreaButton Edited on March 7, 1983 11:20 am, by Teitelman changes to: ProcessLine, WaitUntilSaved, destroyLogOnSuccess, CompileButton, DIRECTORY, IMPORTS, Desktop Edited on March 10, 1983 2:54 am, by Teitelman changes to: DIRECTORY, EXPORTS Edited on March 25, 1983 4:40 pm, by Teitelman changes to: ShowLog, DIRECTORY Edited on March 28, 1983 3:43 pm, by Teitelman changes to: FindExecFromViewer, ForAllSplitViewers, DIRECTORY, TiogaOps, TiogaOps, UserProfile, RunBinder, RunCompiler Edited on March 29, 1983 5:18 pm, by Teitelman changes to: DIRECTORY Edited on April 6, 1983 3:59 pm, by Teitelman changes to: EvalButton, FindExecFromViewer, SelectedObject, SelectedObject, DIRECTORY, IMPORTS, SetDefaultSwitches, UserExec, UserExec, CurrentSelection, UserExec, DIRECTORY, CreateLog, CreateLog Edited on April 15, 1983 4:03 pm, by Teitelman changes to: CurrentSelection, DIRECTORY, Stop, FlushChars (local of Stop), DIRECTORY, Stop Edited on April 19, 1983 5:47 pm, by Teitelman changes to: RedoButton, GetEventsFromSelection Edited on April 21, 1983 5:34 pm, by Teitelman changes to: GetEventsFromSelection Edited on April 24, 1983 12:07 pm, by Teitelman changes to: OpenViewer, WaitUntilSaved Edited on May 2, 1983 8:10 pm, by Teitelman changed registration of event for WasAnExecDestroyed to before from after. Problem was the links were already gone by the time I got in. changes to: [  Edited on May 4, 1983 12:27 pm, by Teitelman added filters to call to ViewerEvents.RegisterEventProc ΚΏ– "Cedar" style˜JšΟcœ™+J˜šΟk ˜ Jšœ žœ˜Jšœžœ˜+Jšœ žœ˜$Jšœžœ ˜Jšœ žœ ˜Jšœ žœ˜+Jšœžœ˜Jšœžœ˜Jšœ žœ˜!Jš žœžœ‰žœžœ žœ˜ΘJšœžœ<˜GJšœžœ˜$Jšœžœ˜Jšœžœ6žœ ˜NJšœžœ˜Jšœ žœ˜.Jšœ žœn˜|Jšœ žœ ˜Jšœ žœΪ˜θJšœžœ˜Jšœžœ—˜¬Jšœ žœ(˜9Jšœ žœ˜!Jšœžœ˜%Jšœ žœ ˜2Jšœ žœ˜(Jšœ žœD˜SJšœ žœ@˜QJ˜—J˜JšΠblœžœžœ˜$J˜JšžœIžœΊ˜ŒJ˜Jšžœ*˜1J˜Jšžœ ˜J˜Jšœžœžœžœ˜head™JšΟn œžœ˜'Jš Πkn œ˜+Jš œžœ˜$Jš  œžœ˜"Kšœ$™$š œžœžœ%˜CJ™o—š œžœžœ-˜SJ™ ——šœ™š œ˜)Jšœ žœ'˜3J˜J˜J˜—š  œžœ žœž˜%Jšœ@žœžœ žœ˜lJšœ+˜+Jšœ žœ'˜3J˜Jšœ7žœ˜@Jšœ˜Jšœ!˜!J˜J˜J˜—š  œž ˜-Jš žœžœžœžœžœ˜!Jšžœ'žœžœžœ˜aJ˜"J˜J˜—Jš œžœžœ˜"š œžœž˜!šžœžœž˜!Jšœ`˜`Jšœžœ˜J˜—J˜J˜—š œž˜ Jšœ žœ˜&Jšœžœ˜ Jšžœžœžœžœ˜Jšœ$˜$Jšœ˜Jšœ ˜ JšœAžœžœ˜PJšœ"˜"Jšœ˜J˜—š œž˜(Jšœ žœ'˜3Jšœžœ˜(J˜+J˜J˜——šœΠpr™'š œžœ˜*Jšœžœ˜4Jšœžœ˜ Jšœ1˜1Jšžœžœ˜-Jšœ!˜!Jšžœžœ˜ J˜J˜—š œ žAœ˜XJšœ!˜!J˜J˜—š œ žpœž˜…Jšœžœ ˜ J˜.Jšœ žœK˜WJšœžœžœ˜Jšœ˜šžœ žœž˜š  œžœ žœžœ˜(šžœž˜šœ˜Jšžœ žœ žœžœ˜*Jšœ˜—Jšžœ˜—J˜—J˜JšœO˜mJšžœ˜—J˜!Jšœ!žœ+˜SJ˜J˜—š  œ žpœž˜ŽJšœžœ ˜ J˜.J˜9Jšœ žœ&˜4Jšœžœ˜Jšœ žœžœ˜š œžœžœž ˜%Jšœžœ:˜]Jšœ˜J˜—š   œžœžœžœ žœžœ˜@J˜Jšœžœ˜Jšžœ*žœžœžœ˜]Jšžœ!žœ)˜PJšœ*žœ˜Cšžœžœž˜Jšœžœžœžœ˜Jšœžœ2˜Jšœžœžœžœ$1˜›J˜J˜—š  œžpœ˜Jšœžœ ˜ J˜7J˜Jšœ&žœ˜DJšœžœ˜)J˜,Jšžœ žœžœžœ˜Jšœ(˜(Jšœ$˜$šžœžœžœ:ž˜JJšœ˜Jšžœ˜—Jš œ'žœžœžœžœ ˜qJ˜J˜—procš œžœž œ#žœžœžœžœžœžœ˜cJšœ žœK˜WJšœ˜Jšžœ)žœa˜Jšžœžœžœžœ˜GJšžœžœžœ#˜5Jšœ˜J˜—š œž œžœ˜fJ˜Jšœ žœK˜WJšœ˜J˜/Jšžœ#žœžœ9S˜ΌJšžœžœžœ.˜Sšžœ7žœž˜JJ˜Jšœižœ˜uJšžœžœžœ˜#Jšžœžœžœžœ˜;Jšžœžœžœ˜7Jšžœ˜—šž˜šœ ˜ JšœLžœ˜RJšœ˜Jšžœ˜ —Jšœ˜—J˜——šœ™š œ˜"Jšœžœ˜4Jšœžœ˜ š žœžœžœžœžœž˜hJšœ<žœ˜BJšžœ˜—šž˜Jšœžœ˜—J˜J˜—š œ˜#Jšœžœ˜4Jšœžœ˜ š žœžœžœžœžœž˜hJšœ<žœ˜CJšžœ˜—šž˜Jšœžœ˜—J˜J˜—š  œ˜%Jšœžœ˜4Jšœžœ˜ š žœžœžœžœžœž˜hJš žœ(žœžœžœžœ˜JJšœ<žœ˜CJšžœ˜—šž˜Jšœžœ˜—J˜J˜—š   œžœžœ4žœžœ˜eJ˜Jšœžœžœ!˜/šžœ žœ˜š œžœ˜Jšœ<žœžœ žœ˜lJšœžœ žœ˜*Jšœ"žœ˜GJ˜—Jšœ,˜,J˜'J˜—Jšžœ7Οb ˜HJšžœ žœžœ8˜Lšžœžœ˜Jšœžœžœ!˜DJšœ6˜6Jšœ˜JšœC˜CJ˜—J˜J˜—š  œžœžœžœžœ˜5J˜UJ˜!J˜J˜—š œžœžœžœ˜Iš žœžœžœ7žœžœž˜YJšœ žœ˜&J˜ Jšžœ žœžœ ˜&šžœžœž˜šžœ ž˜Jšžœ žœžœ ˜&J˜ Jšžœ˜——Jšžœ˜—Jšžœžœ˜ J˜J˜—š œ˜+Jšœžœ˜J˜š œžœžœ˜J˜J˜J˜Jšœ žœ˜Jšœž˜J˜—š œžœžœ˜J˜J˜J˜J˜Jšœ žœ˜Jšœž˜J˜—J˜J˜jšžœžœžœ˜Jšœ1˜1šžœ žœžœ˜Jšžœ5žœžœ žœ˜iJšžœ žœ!˜1J˜—J˜—šžœ˜Jšžœ9žœžœ žœk˜ΊJšžœ žœ˜'J˜—Jšžœ žœžœ=˜Pšžœžœ˜Jšœžœ!˜'Jšœ,˜,JšœC˜CJšœ˜—J˜J˜——šœ ™ š œž œ<˜[J˜J˜ šžœžœžœžœ˜-J˜Jšžœ˜ —J˜J˜—š œžœžœ žœ ˜KJšœ0˜0šžœ žœžœž˜*šœ˜š  œžœžœžœžœžœ˜OJšœ˜Jšžœžœžœžœ˜+šžœžœžœž˜,Jšžœžœžœžœ˜&Jšžœ˜—Jšžœžœ˜J˜—š œžœžœ˜;šžœžœ#œž˜VJšœ˜Jšœ˜Jšžœ˜—J˜—Jšœžœžœ˜šžœžœž˜"Jšžœ*žœžœž˜