<> <> <> <> <> <> <> <<>> DIRECTORY Atom USING [GetPName], EditSpan USING [CompareNodeOrder], MessageWindow USING [Append, Blink, Clear], NodeAddrs USING [AddNotifyProc], RefTab USING [Create, Delete, Fetch, Ref, Store], Rope USING [Concat, FromRefText, ROPE], SafeStorage USING [GetSystemZone], TEditDocument USING [Selection, SelectionId, SelectionRec, TEditDocumentData], TEditImpl USING [], TEditInput USING [CloseEvent, closeEvent, CloseEventNow, CommandProc, EditState, RecordChar, RecordInt, RecordRef], TEditInputOps USING [BackSpace, BackWord, BufferedInsertChar, BufferedInsertText, ChangeCaretLooks, ChangeLooks, Copy, CopyLooks, CopyFormat, Delete, DeleteNextChar, DeleteNextWord, DoPendingDelete, ExpandAbbreviation, GoToNextChar, GoToNextNode, GoToNextWord, GoToPreviousChar, GoToPreviousNode, GoToPreviousWord, InsertChar, InsertRope, InsertTime, ModifyCaretLook, ModifyLook, Move, SetStyle, Transpose, TransposeLooks, TransposeFormat, WaitForInsertToFinish], TEditOps USING [RememberCurrentPosition], TEditProfile USING [CategoryOfUser, userCategory], TEditScrolling USING [ScrollToPosition], TEditSelection USING [CallWithSelAndDocAndTddLocks, Copy, Create, Extend, FakeSecondary, Find, fSel, InsertionPoint, LevelChange, LockSel, MakePointSelection, MakeSelection, oldSel, pSel, SelectBranch, SelectChar, SelectNode, SelectWord, ShowPosition, sSel, UnlockSel, Update], TEditSplit USING [Split], TextEdit USING [Size], TextLooks USING [allLooks, Look, noLooks], TextNode USING [FirstChild, Location, NarrowToTextNode, NodeItself, Offset, Ref, RefTextNode, Root], TiogaOps USING [], TIPUser USING [TIPScreenCoords], ViewerClasses USING [NotifyProc, Viewer], ViewerOps USING [AddProp]; TEditInputImpl: CEDAR MONITOR IMPORTS Atom, NodeAddrs, RefTab, EditSpan, MessageWindow, Rope, SafeStorage, TEditInput, TEditInputOps, TEditOps, TEditProfile, TEditScrolling, TEditSelection, TEditSplit, TextEdit, TextNode, ViewerOps EXPORTS TEditInput, TEditImpl, TiogaOps = BEGIN OPEN TEditInput, TEditSelection; mx, my: INTEGER; -- global Coord param for ops below n: LONG INTEGER; -- global Numeric param for ops below sel: TEditDocument.SelectionId _ primary; -- global sel ID; can be set to "secondary" by $SelSecondary changeLevel: TEditSelection.LevelChange; -- change granularity when extend pDel: BOOL _ FALSE; <<-- global sel ID; can be set to TRUE by $SelPendDel, FALSE by $SelNotPendDel>> EditObject: TYPE = { text, -- operate on the text of the selection looks, -- operate on the looks only format -- operate on the format only }; editState: PUBLIC EditState _ reset; editObject: EditObject _ text; SelState: TYPE = { reset, -- not specified yet primary, -- making a primary selection secondary }; selState: SelState _ reset; PDelState: TYPE = { reset, -- not specified yet pending, -- making a pending delete selection not }; pdelState: PDelState _ reset; commandTable: RefTab.Ref _ RefTab.Create[mod: 101]; editMessage: Rope.ROPE _ NIL; MessageArray: TYPE = ARRAY BOOL OF ARRAY BOOL OF Rope.ROPE; toPrimaryMessages: REF MessageArray _ NEW [MessageArray]; toSecondaryMessages: REF MessageArray _ NEW [MessageArray]; EditMessage: PROC = { msg: Rope.ROPE _ SELECT editState FROM tolimbo => "Select for delete", toprimary => SELECT editObject FROM text => toPrimaryMessages[pSel.pendingDelete][sSel.pendingDelete], looks => "Select looks to copy", format => "Select format to copy", ENDCASE => NIL, tosecondary => SELECT editObject FROM text => toSecondaryMessages[pSel.pendingDelete][sSel.pendingDelete], looks => "Select destination for copy looks", format => "Select destination for copy format", ENDCASE => NIL, toboth => SELECT editObject FROM text => "Select for transpose", looks => "Select for transpose looks", format => "Select for transpose format", ENDCASE => NIL, ENDCASE => NIL; IF msg = NIL OR msg = editMessage THEN RETURN; MessageWindow.Append[msg,TRUE]; editMessage _ msg }; prevPSel: TEditDocument.Selection _ NEW[TEditDocument.SelectionRec]; <<-- for EditAbort>> qZone: ZONE _ SafeStorage.GetSystemZone[]; Interpret: PUBLIC PROC [viewer: ViewerClasses.Viewer, params: LIST OF REF ANY] = { InterpInput[viewer,params] }; InterpretAtom: PUBLIC PROC [viewer: ViewerClasses.Viewer, atom: ATOM] = { InterpAtom[viewer,atom] }; TEditNotifyProc: PUBLIC ViewerClasses.NotifyProc = BEGIN InterpInput[self,input]; END; InterpAtom: PROC [viewer: ViewerClasses.Viewer, atom: ATOM] = { p: REF ANY = RefTab.Fetch[commandTable,atom].val; IF p=NIL THEN MessageWindow.Append[ Rope.Concat["Unknown atom given to Tioga: ", Atom.GetPName[atom]], TRUE] ELSE { procList: LIST OF CommandProc = NARROW[p]; recordAtom: BOOL _ FALSE; TEditInputOps.WaitForInsertToFinish[]; -- make sure previous characters have gone in FOR list: LIST OF CommandProc _ procList, list.rest UNTIL list=NIL DO record, quit: BOOL; [record, quit] _ list.first[viewer]; IF record THEN recordAtom _ TRUE; IF quit THEN EXIT; ENDLOOP; IF recordAtom THEN RecordRef[atom] }}; ResetInputStuff: PUBLIC PROC = { changeLevel _ same }; SaveCoords: PUBLIC PROC [x,y: INTEGER] = { mx _ x; my _ y }; InterpInput: PUBLIC PROC [viewer: ViewerClasses.Viewer, params: LIST OF REF ANY, increaseNestingCount: BOOL _ TRUE] = BEGIN OPEN TEditInputOps; NormaliseSelection: PROC = BEGIN IF ~pSel.pendingDelete THEN RETURN; LockSel[primary, "InterpInput"]; { ENABLE UNWIND => UnlockSel[primary]; IF pSel.pendingDelete THEN DoPendingDelete[]; IF ~InsSel[] THEN MakePointSelection[pSel, InsertionPoint[]]; }; UnlockSel[primary]; END; InsSel: PROC RETURNS [BOOL] = {RETURN[pSel.granularity=point AND pSel.insertion=before AND sSel.viewer=NIL]}; BumpNesting: ENTRY PROC = { IF (interpreterNesting _ interpreterNesting+1) <= 1 THEN { interpreterNesting _ 1; closeEvent _ FALSE }}; DecrementNesting: ENTRY PROC RETURNS [BOOL] = { RETURN [(interpreterNesting _ interpreterNesting-1) <= 0] }; AllText: PROC [LIST OF REF ANY] RETURNS [BOOL] = { FOR input: LIST OF REF ANY _ params, input.rest UNTIL input=NIL DO WITH input.first SELECT FROM z: REF CHAR => NULL; z: Rope.ROPE => NULL; z: REF TEXT => NULL; ENDCASE => RETURN [FALSE]; ENDLOOP; RETURN [TRUE] }; ResetInputStuff; IF interpreterNesting=0 AND ~pSel.pendingDelete AND AllText[params] THEN { <<-- hand it off to buffered input routines>> FOR input: LIST OF REF ANY _ params, input.rest UNTIL input=NIL DO WITH input.first SELECT FROM z: REF CHAR => { NormaliseSelection[]; BufferedInsertChar[z^]; RecordChar[z^]}; z: Rope.ROPE => { NormaliseSelection[]; BufferedInsertText[z]; RecordRef[z]}; z: REF TEXT => { NormaliseSelection[]; BufferedInsertText[Rope.FromRefText[z]]; RecordRef[z]}; ENDCASE => ERROR; ENDLOOP } ELSE { IF increaseNestingCount THEN BumpNesting[]; FOR input: LIST OF REF ANY _ params, input.rest UNTIL input=NIL DO WITH input.first SELECT FROM z: ATOM => InterpAtom[viewer,z ! BadMouse, DontDoIt => EXIT]; z: TIPUser.TIPScreenCoords => SaveCoords[z.mouseX, viewer.ch-z.mouseY]; z: REF CHAR => { InsertChar[z^]; RecordChar[z^] }; z: REF LONG INTEGER => { n _ z^; RecordInt[n] }; z: Rope.ROPE => { InsertRope[z]; RecordRef[z] }; z: REF TEXT => { InsertRope[Rope.FromRefText[z]]; RecordRef[z] }; ENDCASE => MessageWindow.Append["Unknown input given to Tioga.", TRUE]; ENDLOOP; IF increaseNestingCount AND DecrementNesting[] AND closeEvent THEN CloseEventNow[]; }; END; interpreterNesting: PUBLIC INTEGER _ 0; NumberToLook: PROC RETURNS [l: CHAR] = BEGIN <<-- maps global value in n to => ['a..'z];>> RETURN['a+n]; END; <<-- ***** Command Procs *****>> ApplyCaretLook: CommandProc = { TEditInputOps.ModifyCaretLook[NumberToLook[], add] }; ApplyLook: CommandProc = { TEditInputOps.ModifyLook[NumberToLook[], add] }; ClearCaretLooks: CommandProc = { TEditInputOps.ChangeCaretLooks[add: TextLooks.noLooks, remove: TextLooks.allLooks] }; ClearLooks: CommandProc = { TEditInputOps.ChangeLooks[add: TextLooks.noLooks, remove: TextLooks.allLooks] }; BackSpace: CommandProc = { TEditInputOps.BackSpace[n] }; BackWord: CommandProc = { TEditInputOps.BackWord[n] }; DeleteNextChar: CommandProc = { TEditInputOps.DeleteNextChar[n] }; DeleteNextWord: CommandProc = { TEditInputOps.DeleteNextWord[n] }; GoToPreviousWord: CommandProc = { TEditInputOps.GoToPreviousWord[n] }; GoToNextWord: CommandProc = { TEditInputOps.GoToNextWord[n] }; GoToPreviousChar: CommandProc = { TEditInputOps.GoToPreviousChar[n] }; GoToNextChar: CommandProc = { TEditInputOps.GoToNextChar[n] }; GoToPreviousNode: CommandProc = { TEditInputOps.GoToPreviousNode[n] }; GoToNextNode: CommandProc = { TEditInputOps.GoToNextNode[n] }; Copy: CommandProc = { IF sSel.viewer#NIL THEN { TEditInputOps.Copy[sel]; RecordRef[$GetSecondary] }}; Delete: CommandProc = { TEditInputOps.Delete[TRUE] }; ExpandAbbrev: CommandProc = { TEditInputOps.ExpandAbbreviation[] }; Move: CommandProc = { IF sSel.viewer#NIL THEN { TEditInputOps.Move[sel]; RecordRef[$GetSecondary] }}; RemoveCaretLook: CommandProc = { TEditInputOps.ModifyCaretLook[NumberToLook[], remove] }; RemoveLook: CommandProc = { TEditInputOps.ModifyLook[NumberToLook[], remove] }; SetStyle: CommandProc = { TEditInputOps.SetStyle[] }; Time: CommandProc = { TEditInputOps.InsertTime[] }; Split: CommandProc = { TEditSplit.Split[viewer]; RETURN[FALSE] }; Transpose: CommandProc = { IF sSel.viewer#NIL THEN { TEditInputOps.Transpose[sel]; RecordRef[$GetSecondary] }}; ToBoth: CommandProc = { IF editState=reset OR editState=tolimbo THEN { editState _ toboth; EditMessage[] }; RETURN [FALSE] }; ToLimbo: CommandProc = { IF editState=reset THEN editState _ tolimbo; RETURN [FALSE] }; ToPrimary: CommandProc = { IF editState=reset OR editState=tolimbo THEN editState _ toprimary; RETURN [FALSE] }; ToSecondary: CommandProc = { IF editState=reset OR editState=tolimbo THEN { editState _ tosecondary; EditMessage[] }; RETURN [FALSE] }; EditText: CommandProc = { editObject _ text; RETURN [FALSE] }; EditLooks: CommandProc = { editObject _ looks; EditMessage[]; RETURN [FALSE] }; EditFormat: CommandProc = { editObject _ format; EditMessage[]; RETURN [FALSE] }; EditReset: CommandProc = { editState _ reset; editObject _ text; selState _ reset; pdelState _ reset; RETURN [FALSE] }; EditAbort: CommandProc = { IF viewer#NIL AND pSel.viewer=viewer AND pSel.granularity=point AND sSel.viewer=NIL THEN ViewerOps.AddProp[viewer, $Abort, NEW[BOOL _ FALSE]]; MessageWindow.Append["Cancelled",TRUE]; MakeSelection[NIL,secondary]; MakeSelection[IF CheckSelection[prevPSel] THEN prevPSel ELSE NIL, primary]; editState _ abort; editObject _ text; mouseColor _ dead; -- stop tracking the mouse RETURN [FALSE] }; GetSecondary: CommandProc = { IF sSel.viewer=NIL AND CheckSelection[oldSel] THEN FakeSecondary[oldSel]; RETURN [FALSE] }; UpdateSavedSelections: PROC [ node: TextNode.RefTextNode, new: PROC [old: TextNode.Offset] RETURNS [TextNode.Offset]] = { Check: PROC [loc: TextNode.Location] RETURNS [TextNode.Location] = { IF loc.node # node THEN RETURN [loc]; RETURN [[loc.node, new[loc.where]]] }; <<-- oldSel is saved version of sSel for use in Repeat>> oldSel.start.pos _ Check[oldSel.start.pos]; oldSel.end.pos _ Check[oldSel.end.pos]; <<-- savedSelA is saved by SaveSelectionA and restored by RestoreSelectionA>> savedSelA.start.pos _ Check[savedSelA.start.pos]; savedSelA.end.pos _ Check[savedSelA.end.pos]; <<-- savedSelB is saved by SaveSelectionB and restored by RestoreSelectionB>> savedSelB.start.pos _ Check[savedSelB.start.pos]; savedSelB.end.pos _ Check[savedSelB.end.pos]; <<-- fSel is saved feedback selection>> fSel.start.pos _ Check[fSel.start.pos]; fSel.end.pos _ Check[fSel.end.pos]; }; CheckSelection: PUBLIC PROC [sel: TEditDocument.Selection] RETURNS [BOOL] = { root, first, last: TextNode.Ref; t1, t2: TextNode.RefTextNode; tdd: TEditDocument.TEditDocumentData; IF sel=NIL THEN RETURN [FALSE]; IF sel.viewer=NIL OR sel.viewer.destroyed THEN GOTO Failed; IF (first _ sel.start.pos.node)=NIL OR (last _ sel.end.pos.node)=NIL THEN GOTO Failed; IF (tdd _ NARROW[sel.viewer.data])=NIL THEN GOTO Failed; IF (root _ tdd.text)=NIL THEN GOTO Failed; IF TextNode.Root[first] # root THEN GOTO Failed; -- make sure still in the tree IF first # last THEN -- make sure nodes in same tree and right order IF EditSpan.CompareNodeOrder[first,last] # before THEN GOTO Failed; IF sel.start.pos.where # TextNode.NodeItself THEN -- make sure start index is ok IF (t1 _ TextNode.NarrowToTextNode[first])=NIL OR sel.start.pos.where NOT IN [0..TextEdit.Size[t1]] THEN GOTO Failed; IF sel.end.pos.where # TextNode.NodeItself THEN -- make sure end index is ok IF (t2 _ TextNode.NarrowToTextNode[last])=NIL OR sel.end.pos.where NOT IN [0..TextEdit.Size[t2]] THEN GOTO Failed; IF t1 # NIL AND t1 = t2 THEN -- make sure start is not after end IF sel.start.pos.where > sel.end.pos.where THEN GOTO Failed; RETURN [TRUE]; EXITS Failed => { sel.viewer _ NIL; RETURN [FALSE] }; }; MakePDel: CommandProc = { pSel.pendingDelete _ TRUE; RETURN [FALSE] }; DoEdit: CommandProc = { IF pSel.viewer = NIL THEN { IF sSel.viewer # NIL THEN MakeSelection[NIL,secondary]; -- get rid of secondary recordAtom _ FALSE } ELSE IF editState = tolimbo THEN { recordAtom _ FALSE; RecordRef[$Delete]; TEditInputOps.Delete[TRUE] } ELSE IF sSel.viewer = NIL THEN recordAtom _ FALSE ELSE { RecordEditObject: PROC = { RecordRef[SELECT editObject FROM text => $EditText, looks => $EditLooks, format => $EditFormat, ENDCASE => ERROR] }; recordAtom _ TRUE; SELECT editState FROM reset, abort => recordAtom _ FALSE; toprimary => { RecordRef[$GetSecondary]; RecordRef[$ToPrimary]; RecordEditObject[]; SELECT editObject FROM text => { IF pSel.pendingDelete THEN RecordRef[$MakePDel]; TEditInputOps.Copy[primary] }; looks => TEditInputOps.CopyLooks[primary]; format => TEditInputOps.CopyFormat[primary]; ENDCASE => ERROR }; tosecondary => { RecordRef[$GetSecondary]; RecordRef[$ToSecondary]; RecordEditObject[]; SELECT editObject FROM text => { IF pSel.pendingDelete THEN RecordRef[$MakePDel]; TEditInputOps.Copy[secondary] }; looks => TEditInputOps.CopyLooks[secondary]; format => TEditInputOps.CopyFormat[secondary]; ENDCASE => ERROR }; toboth => { RecordRef[$GetSecondary]; RecordRef[$ToBoth]; RecordEditObject[]; SELECT editObject FROM text => TEditInputOps.Transpose[]; looks => TEditInputOps.TransposeLooks[]; format => TEditInputOps.TransposeFormat[]; ENDCASE => ERROR }; ENDCASE => ERROR }; editState _ reset; editObject _ text; pdelState _ reset; pDel _ FALSE; selState _ reset; sel _ primary; mouseColor _ red; -- put these back to normal IF editMessage # NIL THEN MessageWindow.Clear[]; editMessage _ NIL }; NormalizeViewer: PROC [ viewer: ViewerClasses.Viewer, loc: TextNode.Location, tdd: TEditDocument.TEditDocumentData, tSel: TEditDocument.Selection] = { IF loc.node = NIL OR tdd.text # TextNode.Root[loc.node] THEN -- scroll to start of document loc _ [TextNode.FirstChild[tdd.text],0]; TEditOps.RememberCurrentPosition[viewer]; TEditScrolling.ScrollToPosition[viewer, loc] }; NormalizeToStart: PUBLIC CommandProc = { DoIt: PROC [tdd: TEditDocument.TEditDocumentData, tSel: TEditDocument.Selection] = { NormalizeViewer[viewer, IF tSel.viewer=NIL THEN [NIL,0] ELSE tSel.start.pos, tdd, tSel] }; TEditSelection.CallWithSelAndDocAndTddLocks[viewer, primary, DoIt] }; NormalizeToCaret, Normalize: PUBLIC CommandProc = { DoIt: PROC [tdd: TEditDocument.TEditDocumentData, tSel: TEditDocument.Selection] = { NormalizeViewer[viewer, IF tSel.viewer=NIL THEN [NIL,0] ELSE InsertionPoint[tSel], tdd, tSel] }; TEditSelection.CallWithSelAndDocAndTddLocks[viewer, primary, DoIt] }; NormalizeToEnd: PUBLIC CommandProc = { DoIt: PROC [tdd: TEditDocument.TEditDocumentData, tSel: TEditDocument.Selection] = { NormalizeViewer[viewer, IF tSel.viewer=NIL THEN [NIL,0] ELSE tSel.end.pos, tdd, tSel] }; TEditSelection.CallWithSelAndDocAndTddLocks[viewer, primary, DoIt] }; FindNext: CommandProc = { Find[viewer: viewer, findWhere: forwards]; CloseEvent[]; RETURN [FALSE] }; FindAny: CommandProc = { Find[viewer: viewer, findWhere: anywhere]; CloseEvent[]; RETURN [FALSE] }; FindPrev: CommandProc = { Find[viewer: viewer, findWhere: backwards]; CloseEvent[]; RETURN [FALSE] }; FindNextWord: CommandProc = { Find[viewer: viewer, findWhere: forwards, def: FALSE, word: TRUE]; CloseEvent[]; RETURN [FALSE] }; FindAnyWord: CommandProc = { Find[viewer: viewer, findWhere: anywhere, def: FALSE, word: TRUE]; CloseEvent[]; RETURN [FALSE] }; FindPrevWord: CommandProc = { Find[viewer: viewer, findWhere: backwards, def: FALSE, word: TRUE]; CloseEvent[]; RETURN [FALSE] }; FindNextDef: CommandProc = { Find[viewer: viewer, findWhere: forwards, def: TRUE, word: TRUE]; CloseEvent[]; RETURN [FALSE] }; FindAnyDef: CommandProc = { Find[viewer: viewer, findWhere: anywhere, def: TRUE, word: TRUE]; CloseEvent[]; RETURN [FALSE] }; FindPrevDef: CommandProc = { Find[viewer: viewer, findWhere: backwards, def: TRUE, word: TRUE]; CloseEvent[]; RETURN [FALSE] }; FindNextCaseless: CommandProc = { Find[viewer: viewer, findWhere: forwards, case: FALSE]; CloseEvent[]; RETURN [FALSE] }; FindAnyCaseless: CommandProc = { Find[viewer: viewer, findWhere: anywhere, case: FALSE]; CloseEvent[]; RETURN [FALSE] }; FindPrevCaseless: CommandProc = { Find[viewer: viewer, findWhere: backwards, case: FALSE]; CloseEvent[]; RETURN [FALSE] }; FindNextWordCaseless: CommandProc = { Find[viewer: viewer, findWhere: forwards, def: FALSE, word: TRUE, case: FALSE]; CloseEvent[]; RETURN [FALSE] }; FindAnyWordCaseless: CommandProc = { Find[viewer: viewer, findWhere: anywhere, def: FALSE, word: TRUE, case: FALSE]; CloseEvent[]; RETURN [FALSE] }; FindPrevWordCaseless: CommandProc = { Find[viewer: viewer, findWhere: backwards, def: FALSE, word: TRUE, case: FALSE]; CloseEvent[]; RETURN [FALSE] }; FindNextDefCaseless: CommandProc = { Find[viewer: viewer, findWhere: forwards, def: TRUE, word: TRUE, case: FALSE]; CloseEvent[]; RETURN [FALSE] }; FindAnyDefCaseless: CommandProc = { Find[viewer: viewer, findWhere: anywhere, def: TRUE, word: TRUE, case: FALSE]; CloseEvent[]; RETURN [FALSE] }; FindPrevDefCaseless: CommandProc = { Find[viewer: viewer, findWhere: backwards, def: TRUE, word: TRUE, case: FALSE]; CloseEvent[]; RETURN [FALSE] }; savedSelA: TEditDocument.Selection _ TEditSelection.Create[]; savedSelB: TEditDocument.Selection _ TEditSelection.Create[]; RestoreSelectionA: PUBLIC CommandProc = { IF CheckSelection[savedSelA] THEN MakeSelection[selection: primary, new: savedSelA] }; SaveSelectionA: PUBLIC CommandProc = { IF pSel # NIL THEN TEditSelection.Copy[source: pSel, dest: savedSelA] }; RestoreSelectionB: PUBLIC CommandProc = { IF CheckSelection[savedSelB] THEN MakeSelection[selection: primary, new: savedSelB] }; SaveSelectionB: PUBLIC CommandProc = { IF pSel # NIL THEN TEditSelection.Copy[source: pSel, dest: savedSelB] }; Position: CommandProc = { CloseEvent[]; TEditSelection.ShowPosition[viewer: viewer, skipCommentNodes: TRUE]; RETURN[FALSE] }; PositionIncludingComments: CommandProc = { CloseEvent[]; TEditSelection.ShowPosition[viewer: viewer, skipCommentNodes: FALSE]; RETURN[FALSE] }; MouseColor: TYPE = { red, yellow, blue, dead }; mouseColor: MouseColor _ red; BadMouse: PUBLIC SIGNAL = CODE; RedMouse: CommandProc = { IF mouseColor = dead THEN SIGNAL BadMouse; mouseColor _ red; TEditSelection.Copy[source: pSel, dest: prevPSel]; RETURN [FALSE] }; YellowMouse: CommandProc = { IF mouseColor = dead THEN SIGNAL BadMouse; mouseColor _ yellow; TEditSelection.Copy[source: pSel, dest: prevPSel]; RETURN [FALSE] }; BlueMouse: CommandProc = { IF mouseColor = dead THEN SIGNAL BadMouse; mouseColor _ blue; TEditSelection.Copy[source: pSel, dest: prevPSel]; RETURN [FALSE] }; RedDown: CommandProc = { IF mouseColor # red THEN SIGNAL BadMouse; RETURN [FALSE] }; YellowDown: CommandProc = { IF mouseColor # yellow THEN SIGNAL BadMouse; RETURN [FALSE] }; BlueDown: CommandProc = { IF mouseColor # blue THEN SIGNAL BadMouse; RETURN [FALSE] }; AbortSecondary: PROC = { MessageWindow.Append["Make a primary selection first.",TRUE]; MessageWindow.Blink[]; editState _ abort; mouseColor _ dead }; SelBranch: CommandProc = { tdd: TEditDocument.TEditDocumentData ~ NARROW[viewer.data]; IF tdd = NIL THEN RETURN; interpreterNesting _ 0; IF editState=abort THEN RETURN; IF sel=secondary AND pSel.viewer = NIL THEN { AbortSecondary[]; RETURN }; TEditSelection.SelectBranch[viewer, tdd, mx, my, sel, pDel]; IF editState=tolimbo OR sel=secondary THEN EditMessage[]; IF sel=primary THEN CloseEvent[]; RETURN [FALSE] }; SelChar: CommandProc = { tdd: TEditDocument.TEditDocumentData ~ NARROW[viewer.data]; IF tdd = NIL THEN RETURN; interpreterNesting _ 0; IF editState=abort THEN RETURN; IF sel=secondary AND pSel.viewer = NIL THEN { AbortSecondary[]; RETURN }; TEditSelection.SelectChar[viewer, tdd, mx, my, sel, pDel]; IF editState=tolimbo OR sel=secondary THEN EditMessage[]; IF sel=primary THEN CloseEvent[]; RETURN [FALSE] }; SelExpand: CommandProc = { changeLevel _ expand; IF sel=primary THEN CloseEvent[]; RETURN [FALSE] }; SelExtend: CommandProc = { Extend[viewer, FALSE]; RETURN [FALSE] }; SelStartExtend: CommandProc = { Extend[viewer, TRUE]; RETURN [FALSE] }; Extend: PROC [viewer: ViewerClasses.Viewer, saveEnds: BOOL] = { tdd: TEditDocument.TEditDocumentData ~ NARROW[viewer.data]; IF tdd = NIL THEN RETURN; interpreterNesting _ 0; IF editState=abort THEN RETURN; IF mouseColor # blue THEN { [] _ BlueMouse[]; saveEnds _ TRUE }; TEditSelection.Extend[viewer,tdd,mx,my,sel,pDel,changeLevel,saveEnds]; IF sel=secondary THEN EditMessage[] ELSE IF sel=primary THEN CloseEvent[] }; SelNode: CommandProc = { tdd: TEditDocument.TEditDocumentData ~ NARROW[viewer.data]; IF tdd = NIL THEN RETURN; interpreterNesting _ 0; IF editState=abort THEN RETURN; IF sel=secondary AND pSel.viewer = NIL THEN { AbortSecondary[]; RETURN }; SelectNode[viewer, tdd, mx, my, sel, pDel]; IF editState=tolimbo OR sel=secondary THEN EditMessage[]; IF sel=primary THEN CloseEvent[]; RETURN [FALSE] }; SelNotPendDel: CommandProc = { IF pdelState=reset THEN { pdelState _ not; pDel _ FALSE; IF sel=primary THEN CloseEvent[] }; RETURN [FALSE] }; SelPendDel: CommandProc = { IF pdelState=reset THEN { pdelState _ pending; pDel _ TRUE; IF sel=primary THEN CloseEvent[] }; RETURN [FALSE] }; ForceSelPendDel: CommandProc = { -- force pending delete pdelState _ reset; [] _ SelPendDel[]; RETURN [FALSE] }; ForceSelNotPendDel: CommandProc = { -- force not pending delete pdelState _ reset; [] _ SelNotPendDel[]; RETURN [FALSE] }; SelSamePendDel: CommandProc = { IF sel=primary THEN CloseEvent[]; RETURN [FALSE] }; SelPrimary: CommandProc = { IF selState=reset THEN { selState _ primary; sel _ primary; CloseEvent[] }; RETURN [FALSE] }; SelReduce: CommandProc = { changeLevel _ reduce; IF sel=primary THEN CloseEvent[]; RETURN [FALSE] }; SelSame: CommandProc = { -- this is no longer needed. delete it after release new TIP tables }; SelSameEnd: CommandProc = { -- get rid of this when change Tioga.Tip RETURN [FALSE] }; SelSecondary: CommandProc = { IF selState=reset THEN { selState _ secondary; sel _ secondary }; RETURN [FALSE] }; SelUpdate: CommandProc = { tdd: TEditDocument.TEditDocumentData ~ NARROW[viewer.data]; IF tdd = NIL THEN RETURN; IF editState=abort THEN RETURN; IF sel=secondary AND pSel.viewer = NIL THEN { AbortSecondary[]; RETURN }; Update[viewer, tdd, mx, my, sel, pDel]; IF sel=secondary THEN EditMessage[]; IF sel=primary THEN CloseEvent[]; RETURN [FALSE] }; SelWord: CommandProc = { tdd: TEditDocument.TEditDocumentData ~ NARROW[viewer.data]; IF tdd = NIL THEN RETURN; interpreterNesting _ 0; IF editState=abort THEN RETURN; IF sel=secondary AND pSel.viewer = NIL THEN { AbortSecondary[]; RETURN }; SelectWord[viewer, tdd, mx, my, sel, pDel]; IF editState=tolimbo OR sel=secondary THEN EditMessage[]; IF sel=primary THEN CloseEvent[]; RETURN [FALSE] }; IntermediateUser: CommandProc = { CheckUser[intermediate]; RETURN [FALSE] }; AdvancedUser: CommandProc = { CheckUser[advanced]; RETURN [FALSE] }; ExpertUser: CommandProc = { CheckUser[expert]; RETURN [FALSE] }; DontDoIt: PUBLIC SIGNAL = CODE; -- raised if user category is too low CheckUser: PROC [category: TEditProfile.CategoryOfUser] = { IF TEditProfile.userCategory < category THEN SIGNAL DontDoIt }; Register: PUBLIC ENTRY PROC [name: ATOM, proc: CommandProc, before: BOOL _ TRUE] = { ENABLE UNWIND => NULL; p: REF ANY = RefTab.Fetch[commandTable,name].val; list: LIST OF CommandProc _ NARROW[p]; IF before OR list=NIL THEN list _ CONS[proc,list] ELSE FOR l: LIST OF CommandProc _ list, l.rest DO IF l.rest=NIL THEN { l.rest _ LIST[proc]; EXIT }; ENDLOOP; [] _ RefTab.Store[commandTable,name,list] }; UnRegister: PUBLIC ENTRY PROC [name: ATOM, proc: CommandProc] = { ENABLE UNWIND => NULL; p: REF ANY = RefTab.Fetch[commandTable,name].val; procList: LIST OF CommandProc _ NARROW[p]; IF procList=NIL THEN NULL ELSE IF procList.first = proc THEN procList _ procList.rest ELSE { prev: LIST OF CommandProc _ procList; FOR list: LIST OF CommandProc _ procList.rest, list.rest UNTIL list=NIL DO IF list.first=proc THEN { prev.rest _ list.rest; RETURN }; prev _ list; ENDLOOP }; IF procList=NIL THEN [] _ RefTab.Delete[commandTable,name] ELSE IF procList # p THEN [] _ RefTab.Store[commandTable,name,procList] }; IsRegistered: PUBLIC ENTRY PROC [name: ATOM, proc: CommandProc] RETURNS [BOOL] = { ENABLE UNWIND => NULL; p: REF ANY = RefTab.Fetch[commandTable,name].val; procList: LIST OF CommandProc _ NARROW[p]; FOR l: LIST OF CommandProc _ procList, l.rest UNTIL l=NIL DO IF l.first=proc THEN RETURN[TRUE]; ENDLOOP; RETURN [FALSE] }; RegisterCommandAtoms: PROC = { Register[$ApplyCaretLook, ApplyCaretLook]; Register[$ApplyLook, ApplyLook]; Register[$ClearCaretLooks, ClearCaretLooks]; Register[$ClearLooks, ClearLooks]; Register[$BackSpace, BackSpace]; Register[$BackWord, BackWord]; Register[$DeleteNextChar, DeleteNextChar]; Register[$DeleteNextWord, DeleteNextWord]; Register[$GoToPreviousWord, GoToPreviousWord]; Register[$GoToNextWord, GoToNextWord]; Register[$GoToPreviousChar, GoToPreviousChar]; Register[$GoToNextChar, GoToNextChar]; Register[$GoToPreviousNode, GoToPreviousNode]; Register[$GoToNextNode, GoToNextNode]; Register[$Copy, Copy]; Register[$Delete, Delete]; Register[$DoEdit, DoEdit]; Register[$ExpandAbbrev, ExpandAbbrev]; Register[$Move, Move]; Register[$NormalizeToStart, NormalizeToStart]; Register[$NormalizeToCaret, NormalizeToCaret]; Register[$NormalizeToEnd, NormalizeToEnd]; Register[$RemoveCaretLook, RemoveCaretLook]; Register[$RemoveLook, RemoveLook]; Register[$SetStyle, SetStyle]; Register[$Time, Time]; Register[$RedSplit, Split]; Register[$YellowSplit, Split]; Register[$BlueSplit, Split]; Register[$Transpose, Transpose]; Register[$ToBoth, ToBoth]; Register[$ToLimbo, ToLimbo]; Register[$ToPrimary, ToPrimary]; Register[$ToSecondary, ToSecondary]; Register[$EditReset, EditReset]; Register[$EditAbort, EditAbort]; Register[$EditText, EditText]; Register[$EditFormat, EditFormat]; Register[$EditType, EditFormat]; -- For compatability Register[$EditLooks, EditLooks]; Register[$GetSecondary, GetSecondary]; Register[$MakePDel, MakePDel]; Register[$FindNext, FindNext]; Register[$FindAny, FindAny]; Register[$FindPrev, FindPrev]; Register[$FindNextDef, FindNextDef]; Register[$FindAnyDef, FindAnyDef]; Register[$FindPrevDef, FindPrevDef]; Register[$FindNextWord, FindNextWord]; Register[$FindAnyWord, FindAnyWord]; Register[$FindPrevWord, FindPrevWord]; Register[$FindNextCaseless, FindNextCaseless]; Register[$FindAnyCaseless, FindAnyCaseless]; Register[$FindPrevCaseless, FindPrevCaseless]; Register[$FindNextDefCaseless, FindNextDefCaseless]; Register[$FindAnyDefCaseless, FindAnyDefCaseless]; Register[$FindPrevDefCaseless, FindPrevDefCaseless]; Register[$FindNextWordCaseless, FindNextWordCaseless]; Register[$FindAnyWordCaseless, FindAnyWordCaseless]; Register[$FindPrevWordCaseless, FindPrevWordCaseless]; Register[$PushSelection, SaveSelectionA]; Register[$PopSelection, RestoreSelectionA]; Register[$SaveSelection, SaveSelectionA]; Register[$RestoreSelection, RestoreSelectionA]; Register[$SaveSelectionA, SaveSelectionA]; Register[$RestoreSelectionA, RestoreSelectionA]; Register[$SaveSelectionB, SaveSelectionB]; Register[$RestoreSelectionB, RestoreSelectionB]; Register[$Position, Position]; Register[$PositionIncludingComments, PositionIncludingComments]; Register[$RedMouse, RedMouse]; Register[$YellowMouse, YellowMouse]; Register[$BlueMouse, BlueMouse]; Register[$RedDown, RedDown]; Register[$YellowDown, YellowDown]; Register[$BlueDown, BlueDown]; Register[$SelBranch, SelBranch]; Register[$SelChar, SelChar]; Register[$SelExpand, SelExpand]; Register[$SelExtend, SelExtend]; Register[$SelStartExtend, SelStartExtend]; Register[$SelNode, SelNode]; Register[$SelNotPendDel, SelNotPendDel]; Register[$SelPendDel, SelPendDel]; Register[$ForceSelPendDel, ForceSelPendDel]; Register[$ForceSelNotPendDel, ForceSelNotPendDel]; Register[$SelSamePendDel, SelSamePendDel]; Register[$SelPrimary, SelPrimary]; Register[$SelReduce, SelReduce]; Register[$SelSame, SelSame]; Register[$SelSameEnd, SelSameEnd]; Register[$SelSecondary, SelSecondary]; Register[$SelUpdate, SelUpdate]; Register[$SelWord, SelWord]; Register[$IntermediateUser, IntermediateUser]; Register[$AdvancedUser, AdvancedUser]; Register[$ExpertUser, ExpertUser]; }; toPrimaryMessages[FALSE][FALSE] _ "Select for copy to caret"; toPrimaryMessages[FALSE][TRUE] _ "Select for move to caret"; toPrimaryMessages[TRUE][FALSE] _ "Select replacement"; toPrimaryMessages[TRUE][TRUE] _ "Select for move onto"; toSecondaryMessages[FALSE][FALSE] _ "Select destination for copy"; toSecondaryMessages[FALSE][TRUE] _ "Select for replacement"; toSecondaryMessages[TRUE][FALSE] _ "Select destination for move"; toSecondaryMessages[TRUE][TRUE] _ "Select destination for move onto"; RegisterCommandAtoms; NodeAddrs.AddNotifyProc[UpdateSavedSelections]; END.