DIRECTORY Atom USING [GetPName, MakeAtom], EditSpan USING [CompareNodeOrder], NodeAddrs USING [GetTextAddr, MapTextAddrs, PutTextAddr, RemTextAddr, TextAddrNotFound], NodeStyleOps USING [StyleNameForNode], Rope USING [IsEmpty, ROPE, Size], TEditDocument USING [Selection, SelectionGrain, SelectionId, TEditDocumentData], TEditInput USING [Cancel, CurrentEvent, MakePointSelection, Repeat, RestoreSelectionA, RestoreSelectionB, SaveSelectionA, SaveSelectionB], TEditInputOps USING [BackSpace, BackWord, Break, Capitalise, ChangeCaretLooks, ChangeLooks, Copy, CopyLooks, CopyFormat, Delete, DeleteNextChar, DeleteNextWord, ExpandAbbreviation, GetFormat, GoToNextChar, GoToNextNode, GoToNextWord, GoToPreviousChar, GoToPreviousNode, GoToPreviousWord, InsertBrackets, InsertChar, InsertLineBreak, InsertRope, InsertTime, Join, MakeControlCharacter, MakeOctalCharacter, Nest, Paste, RegisterAbbrevFailedProc, SaveForPaste, SaveSpanForPaste, SetCommentProp, SetStyleName, SetFormat, SetFormatName, Transpose, UnMakeControlCharacter, UnMakeOctalCharacter, UnNest], TEditLocks USING [Lock, Unlock], TEditMesaOps USING [SetMesaLooksOp], TEditOps USING [CaretLoc, GetSelContents, RegisterFileNameProc], TEditSelection USING [Alloc, CaretAfterSelection, CaretBeforeSelection, Deselect, DoFind, FindWhere, Free, fSel, GrowSelection, GrowSelectionToBlanks, GrowSelectionToSomething, LockSel, MakeSelection, pSel, SelectionRoot, SetSelLooks, sSel, UnlockSel], TextEdit USING [ChangeStyle, GetFormat, PutFormat, FetchLooks, PutProp, Size], TextLooks USING [allLooks, Looks, LooksToRope, noLooks, RopeToLooks], TextNode USING [BadArgs, Location, LocOffset, LocRelative, NarrowToTextNode, NodeItself, Ref, RefTextNode, Root, StepForward], TiogaExtraOps USING [], TiogaOps USING [FirstChild, GetRope, LastChild, LastWithin, SearchDir, SelectionErrorCode, ViewerDoc, WhichLooks], TiogaOpsDefs USING [Location, Ref, SelectionGrain, WhichNodes, WhichSelection], ViewerClasses USING [Viewer]; TiogaOpsImpl: CEDAR MONITOR IMPORTS Atom, EditSpan, NodeAddrs, NodeStyleOps, Rope, TEditInput, TEditInputOps, TEditLocks, TEditMesaOps, TEditOps, TEditSelection, TextEdit, TextLooks, TextNode, TiogaOps EXPORTS TiogaOps, TiogaExtraOps = BEGIN OPEN TiogaOps, TiogaOpsDefs; ROPE: TYPE = Rope.ROPE; Viewer: TYPE = ViewerClasses.Viewer; Offset: TYPE = INT; CallWithLocks: PUBLIC PROC [proc: PROC [root: Ref], root: Ref ¬ NIL] = { lockedSel, lockedDoc: BOOL ¬ FALSE; Cleanup: PROC = { IF lockedSel THEN { UnlockSel; lockedSel ¬ FALSE }; IF lockedDoc THEN { Unlock[root]; lockedDoc ¬ FALSE }; }; { ENABLE UNWIND => Cleanup; LockSel; lockedSel ¬ TRUE; IF root=NIL AND (root ¬ SelectionRoot[])=NIL THEN { Cleanup; ERROR NoSelection }; Lock[root]; lockedDoc ¬ TRUE; proc[root] }; Cleanup }; NoSelection: PUBLIC ERROR = CODE; -- raised by CallWithLocks when there is no selection Lock: PUBLIC PROC [root: Ref] = { [] ¬ TEditLocks.Lock[root, "TiogaOpsClient"] }; Unlock: PUBLIC PROC [root: Ref] = { TEditLocks.Unlock[root] }; GetSelectionId: PROC [which: WhichSelection] RETURNS [TEditDocument.SelectionId] ~ INLINE { RETURN[which] }; LockSel: PUBLIC PROC [which: WhichSelection ¬ primary] = { TEditSelection.LockSel[GetSelectionId[which], "TiogaOpsClient"] }; UnlockSel: PUBLIC PROC [which: WhichSelection ¬ primary] = { TEditSelection.UnlockSel[GetSelectionId[which]] }; DocGran: PROC [granularity: SelectionGrain] RETURNS [TEditDocument.SelectionGrain] ~ INLINE { RETURN[granularity] }; MyGran: PROC [granularity: TEditDocument.SelectionGrain] RETURNS [SelectionGrain] ~ INLINE { RETURN[granularity] }; DocLoc: PROC [loc: Location] RETURNS [TextNode.Location] ~ INLINE { RETURN[loc] }; MyLoc: PROC [loc: TextNode.Location] RETURNS [Location] ~ INLINE { RETURN[loc] }; GetSelection: PUBLIC PROC [which: WhichSelection ¬ primary] RETURNS [ viewer: Viewer, start, end: Location, level: SelectionGrain, caretBefore: BOOL, pendingDelete: BOOL] = { sel: TEditDocument.Selection = SELECT which FROM primary => TEditSelection.pSel, secondary => TEditSelection.sSel, feedback => TEditSelection.fSel, ENDCASE => ERROR; RETURN [sel.viewer, MyLoc[sel.start.pos], MyLoc[sel.end.pos], MyGran[sel.granularity], sel.insertion=before, sel.pendingDelete] }; SelectionRoot: PUBLIC PROC [which: WhichSelection ¬ primary] RETURNS [root: Ref] = { RETURN [TextNode.NarrowToTextNode[ TEditSelection.SelectionRoot[ SELECT which FROM primary => TEditSelection.pSel, secondary => TEditSelection.sSel, feedback => TEditSelection.fSel, ENDCASE => ERROR]]] }; SelectionError: PUBLIC ERROR [ec: SelectionErrorCode] = CODE; CheckSelection: PROC [sel: TEditDocument.Selection] = { root, first, last: TextNode.Ref; t1, t2: TextNode.RefTextNode; tdd: TEditDocument.TEditDocumentData; IF sel.viewer=NIL OR sel.viewer.destroyed OR (tdd ¬ NARROW[sel.viewer.data])=NIL OR (root ¬ tdd.text)=NIL THEN ERROR SelectionError[IllegalViewer]; IF (first ¬ sel.start.pos.node)=NIL OR (last ¬ sel.end.pos.node)=NIL THEN ERROR SelectionError[IllegalNode]; IF TextNode.Root[first] # root THEN ERROR SelectionError[WrongDoc]; IF first # last THEN -- make sure nodes in same tree and right order IF EditSpan.CompareNodeOrder[first,last] # before THEN ERROR SelectionError[WrongOrder]; 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 ERROR SelectionError[BadStartOffset]; 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 ERROR SelectionError[BadEndOffset]; IF t1 # NIL AND t1 = t2 THEN -- make sure start is not after end IF sel.start.pos.where > sel.end.pos.where THEN ERROR SelectionError[BadEndOffset]; }; SetSelection: PUBLIC PROC [viewer: Viewer, start, end: Location, level: SelectionGrain ¬ char, caretBefore: BOOL ¬ TRUE, pendingDelete: BOOL ¬ FALSE, which: WhichSelection ¬ primary] = { ENABLE UNWIND => NULL; tempSel: TEditDocument.Selection ¬ TEditSelection.Alloc[]; tempSel­ ¬ SELECT which FROM primary => TEditSelection.pSel­, secondary => TEditSelection.sSel­, feedback => TEditSelection.fSel­, ENDCASE => ERROR; tempSel.viewer ¬ viewer; tempSel.data ¬ NARROW[viewer.data]; tempSel.start.pos ¬ DocLoc[start]; tempSel.end.pos ¬ DocLoc[end]; tempSel.granularity ¬ DocGran[level]; tempSel.insertion ¬ IF caretBefore OR tempSel.granularity=point THEN before ELSE after; tempSel.pendingDelete ¬ pendingDelete; CheckSelection[tempSel]; TEditSelection.MakeSelection[tempSel, SELECT which FROM primary => primary, secondary => secondary, feedback => feedback, ENDCASE => ERROR]; TEditSelection.Free[tempSel] }; SelectNodes: PUBLIC PROC [viewer: Viewer, start, end: Ref, level: SelectionGrain ¬ node, caretBefore: BOOL ¬ TRUE, pendingDelete: BOOL ¬ FALSE, which: WhichSelection ¬ primary] = { SetSelection[viewer, [start,0], [end, MAX[Rope.Size[GetRope[end]],1]-1], level, caretBefore, pendingDelete, which] }; SelectBranches: PUBLIC PROC [viewer: Viewer, start, end: Ref, level: SelectionGrain ¬ node, caretBefore: BOOL ¬ TRUE, pendingDelete: BOOL ¬ FALSE, which: WhichSelection ¬ primary] = { SelectNodes[viewer, start, LastWithin[end], level, caretBefore, pendingDelete, which] }; SelectDocument: PUBLIC PROC [viewer: Viewer, level: SelectionGrain ¬ node, caretBefore: BOOL ¬ TRUE, pendingDelete: BOOL ¬ FALSE, which: WhichSelection ¬ primary] = { tdd: TEditDocument.TEditDocumentData ¬ NARROW[viewer.data]; root: Ref ¬ ViewerDoc[viewer]; SelectBranches[viewer, FirstChild[root], LastChild[root], level, caretBefore, pendingDelete, which] }; CancelSelection: PUBLIC PROC [which: WhichSelection ¬ primary] = { TEditSelection.Deselect[GetSelectionId[which]] }; SaveSelA: PUBLIC PROC = { [] ¬ TEditInput.SaveSelectionA[] }; RestoreSelA: PUBLIC PROC = { [] ¬ TEditInput.RestoreSelectionA[] }; SaveSelB: PUBLIC PROC = { [] ¬ TEditInput.SaveSelectionB[] }; RestoreSelB: PUBLIC PROC = { [] ¬ TEditInput.RestoreSelectionB[] }; GrowSelection: PUBLIC PROC = { TEditSelection.GrowSelection[] }; GrowSelectionToBlanks: PUBLIC PROC = { TEditSelection.GrowSelectionToBlanks[] }; GrowSelectionToSomething: PUBLIC PROC [left, right: PROC [CHAR] RETURNS [BOOLEAN]] = { TEditSelection.GrowSelectionToSomething[left, right] }; SearchWhere: PROC [whichDir: SearchDir] RETURNS [TEditSelection.FindWhere] = { RETURN [SELECT whichDir FROM forwards => forwards, backwards => backwards, anywhere => anywhere, ENDCASE => ERROR] }; FindText: PUBLIC PROC [viewer: Viewer, rope: ROPE ¬ NIL, whichDir: SearchDir ¬ forwards, which: WhichSelection ¬ primary, case: BOOL ¬ TRUE -- case => case of characters is significant -- ] RETURNS [found: BOOL] = { IF rope=NIL THEN rope ¬ TEditOps.GetSelContents[]; RETURN [TEditSelection.DoFind[ viewer: viewer, rope: rope, id: GetSelectionId[which], case: case, findWhere: SearchWhere[whichDir]]] }; FindWord: PUBLIC PROC [viewer: Viewer, rope: ROPE ¬ NIL, whichDir: SearchDir ¬ forwards, which: WhichSelection ¬ primary, case: BOOL ¬ TRUE -- case => case of characters is significant -- ] RETURNS [found: BOOL] = { IF rope=NIL THEN rope ¬ TEditOps.GetSelContents[]; RETURN [TEditSelection.DoFind[viewer: viewer, rope: rope, case: case, id: GetSelectionId[which], findWhere: SearchWhere[whichDir], word: TRUE]] }; FindDef: PUBLIC PROC [viewer: Viewer, rope: ROPE ¬ NIL, whichDir: SearchDir ¬ forwards, which: WhichSelection ¬ primary, case: BOOL ¬ TRUE -- case => case of characters is significant -- ] RETURNS [found: BOOL] = { IF rope=NIL THEN rope ¬ TEditOps.GetSelContents[]; RETURN [TEditSelection.DoFind[viewer: viewer, rope: rope, case: case, id: GetSelectionId[which], findWhere: SearchWhere[whichDir], word: TRUE, def: TRUE]] }; LocRelative: PUBLIC PROC [location: Location, count: Offset, break: NAT ¬ 1, skipCommentNodes: BOOL ¬ FALSE] RETURNS [Location] = { RETURN [MyLoc[TextNode.LocRelative[DocLoc[location], count, break, skipCommentNodes]]]; }; LocOffset: PUBLIC PROC [loc1, loc2: Location, break: NAT ¬ 1, skipCommentNodes: BOOL ¬ FALSE] RETURNS [count: Offset] = { count ¬ TextNode.LocOffset[DocLoc[loc1], DocLoc[loc2], break, skipCommentNodes ! TextNode.BadArgs => ERROR BadArgs]; }; BadArgs: PUBLIC ERROR=CODE; GetCaret: PUBLIC PROC RETURNS [loc: Location] = { RETURN [MyLoc[TEditOps.CaretLoc[]]] }; CaretBefore: PUBLIC PROC = { TEditSelection.CaretBeforeSelection[] }; CaretAfter: PUBLIC PROC = { TEditSelection.CaretAfterSelection[] }; CaretOnly: PUBLIC PROC = { [] ¬ TEditInput.MakePointSelection[] }; GoToNextCharacter: PUBLIC PROC [n: INT ¬ 1] = { TEditInputOps.GoToNextChar[n] }; GoToNextWord: PUBLIC PROC [n: INT ¬ 1] = { TEditInputOps.GoToNextWord[n] }; GoToNextNode: PUBLIC PROC [n: INT ¬ 1] = { TEditInputOps.GoToNextNode[n] }; GoToPreviousCharacter: PUBLIC PROC [n: INT ¬ 1] = { TEditInputOps.GoToPreviousChar[n] }; GoToPreviousWord: PUBLIC PROC [n: INT ¬ 1] = { TEditInputOps.GoToPreviousWord[n] }; GoToPreviousNode: PUBLIC PROC [n: INT ¬ 1] = { TEditInputOps.GoToPreviousNode[n] }; ToPrimary: PUBLIC PROC = { TEditInputOps.Copy[primary] }; ToSecondary: PUBLIC PROC = { TEditInputOps.Copy[secondary] }; Transpose: PUBLIC PROC = { TEditInputOps.Transpose[] }; InsertRope: PUBLIC PROC [rope: ROPE] = { TEditInputOps.InsertRope[rope] }; InsertChar: PUBLIC PROC [char: CHAR] = { TEditInputOps.InsertChar[char] }; InsertLineBreak: PUBLIC PROC = { TEditInputOps.InsertLineBreak[] }; BackSpace: PUBLIC PROC [n: INT ¬ 1] = { TEditInputOps.BackSpace[n] }; BackWord: PUBLIC PROC [n: INT ¬ 1] = { TEditInputOps.BackWord[n] }; DeleteNextCharacter: PUBLIC PROC [n: INT ¬ 1] = { TEditInputOps.DeleteNextChar[n] }; DeleteNextWord: PUBLIC PROC [n: INT ¬ 1] = { TEditInputOps.DeleteNextWord[n] }; InsertTime: PUBLIC PROC = { TEditInputOps.InsertTime[] }; InsertBrackets: PUBLIC PROC [left, right: CHAR] = { TEditInputOps.InsertBrackets[left, right] }; MakeControlCharacter: PUBLIC PROC = { TEditInputOps.MakeControlCharacter[] }; UnMakeControlCharacter: PUBLIC PROC = { TEditInputOps.UnMakeControlCharacter[] }; MakeOctalCharacter: PUBLIC PROC = { TEditInputOps.MakeOctalCharacter[] }; UnMakeOctalCharacter: PUBLIC PROC = { TEditInputOps.UnMakeOctalCharacter[] }; ExpandAbbreviation: PUBLIC PROC = { TEditInputOps.ExpandAbbreviation[] }; Delete: PUBLIC PROC = { TEditInputOps.Delete[] }; Paste: PUBLIC PROC = { TEditInputOps.Paste[] }; SaveForPaste: PUBLIC PROC = { TEditInputOps.SaveForPaste[] }; SaveSpanForPaste: PUBLIC PROC [startLoc, endLoc: Location, grain: SelectionGrain ¬ char] = { TEditInputOps.SaveSpanForPaste[DocLoc[startLoc], DocLoc[endLoc], DocGran[grain]] }; AllLower: PUBLIC PROC = { TEditInputOps.Capitalise[allLower] }; AllCaps: PUBLIC PROC = { TEditInputOps.Capitalise[allCaps] }; InitialCaps: PUBLIC PROC = { TEditInputOps.Capitalise[initCaps] }; FirstCap: PUBLIC PROC = { TEditInputOps.Capitalise[firstCap] }; MesaFormatting: PUBLIC PROC = { [] ¬ TEditMesaOps.SetMesaLooksOp[] }; Repeat: PUBLIC PROC = { [] ¬ TEditInput.Repeat[] }; Undo: PUBLIC PROC = { [] ¬ TEditInput.Cancel[] }; Break: PUBLIC PROC = { TEditInputOps.Break[] }; Join: PUBLIC PROC = { TEditInputOps.Join[] }; Nest: PUBLIC PROC = { TEditInputOps.Nest[] }; UnNest: PUBLIC PROC = { TEditInputOps.UnNest[] }; SetSelectionLooks: PUBLIC PROC [which: WhichSelection ¬ primary] = { TEditSelection.SetSelLooks[SELECT which FROM primary => TEditSelection.pSel, secondary => TEditSelection.sSel, feedback => TEditSelection.fSel, ENDCASE => ERROR] }; FetchLooks: PUBLIC PROC [node: Ref, index: Offset] RETURNS [ROPE] = { RETURN [TextLooks.LooksToRope[TextEdit.FetchLooks[TextNode.NarrowToTextNode[node],index]]] }; SetLooks: PUBLIC PROC [looks: ROPE, which: WhichLooks ¬ selection] = { lks: TextLooks.Looks = TextLooks.RopeToLooks[looks]; IF which=selection THEN TEditInputOps.ChangeLooks[add: lks, remove: TextLooks.allLooks] ELSE TEditInputOps.ChangeCaretLooks[add: lks, remove: TextLooks.allLooks] }; AddLooks: PUBLIC PROC [looks: ROPE, which: WhichLooks ¬ selection] = { lks: TextLooks.Looks = TextLooks.RopeToLooks[looks]; IF which=selection THEN TEditInputOps.ChangeLooks[add: lks, remove: TextLooks.noLooks] ELSE TEditInputOps.ChangeCaretLooks[add: lks, remove: TextLooks.noLooks] }; SubtractLooks: PUBLIC PROC [looks: ROPE, which: WhichLooks ¬ selection] = { lks: TextLooks.Looks = TextLooks.RopeToLooks[looks]; IF which=selection THEN TEditInputOps.ChangeLooks[add: TextLooks.noLooks, remove: lks] ELSE TEditInputOps.ChangeCaretLooks[add: TextLooks.noLooks, remove: lks] }; ClearLooks: PUBLIC PROC [which: WhichLooks ¬ selection] = { IF which=selection THEN TEditInputOps.ChangeLooks[add: TextLooks.noLooks, remove: TextLooks.allLooks] ELSE TEditInputOps.ChangeCaretLooks[add: TextLooks.noLooks, remove: TextLooks.allLooks] }; CopyLooks: PUBLIC PROC = { TEditInputOps.CopyLooks[] }; GetFormat: PUBLIC PROC [node: Ref] RETURNS [ROPE] = { name: ATOM = TextEdit.GetFormat[node]; RETURN [IF name=NIL THEN "default" ELSE Atom.GetPName[name]]; }; ForEachNode: PROC [which: WhichNodes, proc: PROC [TextNode.Ref]] = { pSel: TEditDocument.Selection = TEditSelection.pSel; SELECT which FROM root => proc[TextNode.Root[pSel.start.pos.node]]; selection => FOR node: TextNode.Ref ¬ pSel.start.pos.node, TextNode.StepForward[node] DO proc[node]; IF node = pSel.end.pos.node THEN EXIT; ENDLOOP; ENDCASE => ERROR }; SetFormat: PUBLIC PROC [format: ROPE, which: WhichNodes ¬ selection] = { Set: PROC [ref: TextNode.Ref] = { TEditInputOps.SetFormatName[format, ref] }; ForEachNode[which, Set] }; SetNodeFormat: PUBLIC PROC [format: ROPE, node: Ref] = { root: TextNode.Ref; formatName: ATOM ¬ IF format.IsEmpty THEN NIL ELSE Atom.MakeAtom[format]; root ¬ TextNode.Root[node]; [] ¬ TEditLocks.Lock[root, "TiogaOpsSetNodeFormat"]; TextEdit.PutFormat[node, formatName]; TEditLocks.Unlock[root] }; SetNodeStyle: PUBLIC PROC [style: ROPE, node: Ref] = { root: TextNode.Ref ¬ TextNode.Root[node]; [] ¬ TEditLocks.Lock[root, "TiogaOpsSetNodeStyle"]; TextEdit.ChangeStyle[node, style]; TEditLocks.Unlock[root] }; CaretNodeFormat: PUBLIC PROC = { TEditInputOps.SetFormat[] }; InsertFormat: PUBLIC PROC = { TEditInputOps.GetFormat[] }; CopyFormat: PUBLIC PROC = { TEditInputOps.CopyFormat[] }; GetStyle: PUBLIC PROC [node: Ref] RETURNS [ROPE] = { name: ATOM ~ NodeStyleOps.StyleNameForNode[node]; RETURN [IF name=NIL THEN "default" ELSE Atom.GetPName[name]] }; SetStyle: PUBLIC PROC [style: ROPE, which: WhichNodes ¬ selection] = { Set: PROC [ref: TextNode.Ref] = { TEditInputOps.SetStyleName[style, ref] }; ForEachNode[which, Set] }; IsComment: PUBLIC PROC [node: Ref] RETURNS [BOOL] = { txt: TextNode.RefTextNode = TextNode.NarrowToTextNode[node]; RETURN [txt # NIL AND txt.comment] }; SetComment: PUBLIC PROC = { TEditInputOps.SetCommentProp[TRUE] }; SetNotComment: PUBLIC PROC = { TEditInputOps.SetCommentProp[FALSE] }; SetProp: PUBLIC PROC [name: ATOM, value: REF, which: WhichNodes ¬ selection] = { Put: PROC [node: TextNode.Ref] = { TextEdit.PutProp[node, name, value, TEditInput.CurrentEvent[]] }; ForEachNode[which, Put] }; RegisterAbbrevFailedProc: PUBLIC PROC [proc: PROC RETURNS [BOOL]] = { TEditInputOps.RegisterAbbrevFailedProc[proc] }; RegisterFileNameProc: PUBLIC PROC [ proc: PROC [ROPE, Viewer] RETURNS [fileName: ROPE, search: ROPE] ] = { TEditOps.RegisterFileNameProc[proc] }; PutTextKey: PUBLIC PROC [node: Ref, where: Offset, key: REF] = { NodeAddrs.PutTextAddr[TextNode.NarrowToTextNode[node], key, where] }; GetTextKey: PUBLIC PROC [node: Ref, key: REF] RETURNS [loc: Location] = { where: Offset; n: TextNode.RefTextNode; [n, where] ¬ NodeAddrs.GetTextAddr[TextNode.NarrowToTextNode[node], key ! NodeAddrs.TextAddrNotFound => GOTO Error]; RETURN [[n, where]]; EXITS Error => ERROR TextKeyNotFound }; TextKeyNotFound: PUBLIC ERROR = CODE; RemoveTextKey: PUBLIC PROC [node: Ref, key: REF] = { NodeAddrs.RemTextAddr[TextNode.NarrowToTextNode[node], key] }; MapTextKeys: PUBLIC PROC [node: Ref, proc: PROC [key: REF, where: Offset] RETURNS [BOOLEAN]] RETURNS [BOOLEAN] = { Do: PROC [addr: REF, location: Offset] RETURNS [BOOLEAN] = { RETURN [proc[addr, location]] }; RETURN [NodeAddrs.MapTextAddrs[TextNode.NarrowToTextNode[node], Do]]; }; END. p TiogaOpsImpl.mesa Copyright Ó 1985, 1991, 1992 by Xerox Corporation. All rights reserved. written by Bill Paxton. June 1982 last written by Paxton. December 28, 1982 12:38 pm Last Edited by: Paxton, January 10, 1983 4:14 pm Last Edited by: Maxwell, January 19, 1983 12:31 pm Last Edited by: Plass, March 29, 1985 3:52:36 pm PST Michael Plass, March 13, 1989 10:19:47 am PST Rick Beach, March 28, 1985 10:14:40 am PST Doug Wyatt, July 9, 1992 3:00 pm PDT Document Locks Selections Find Location procedures Caret (for primary selection) Edits requiring secondary selections Editing applying to primary selection Node Editing Looks sets the selection looks from the looks of the character next to the caret Formats Styles Comment Property Node Property Lists Miscellaneous call-back procedures Text keys: persistent "addresses" for characters in text nodes Associates the key with the given offset in the text node. Key moves with the text as edits take place in the node. Key doesn't move to new node. May use same key with different nodes without interference. Tells you where the key is in the node at the current time. Êö•NewlineDelimiter –(cedarcode) style™codešœ™Kšœ Ïeœ<™HKšÏc!™!Kšž2™2Kšœžœ™0K™2K™4K™-K™*K™$K™—šÏk ˜ KšœŸœ˜ Kšœ Ÿœ˜"Kšœ ŸœI˜XKšœ Ÿœ˜&KšœŸœ Ÿœ˜!KšœŸœ=˜PKšœ Ÿœz˜ŠKšœŸœÂ˜ÕKšœ Ÿœ˜ Kšœ Ÿœ˜$Kšœ Ÿœ2˜@KšœŸœè˜üKšœ Ÿœ@˜NKšœ Ÿœ6˜EKšœ Ÿœp˜~KšœŸœ˜Kšœ Ÿœd˜rKšœ Ÿœ=˜OKšœŸœ ˜—K˜KšÏn œŸœŸ˜KšŸœ¦˜­KšŸœ˜!šŸœŸœ˜"K˜KšŸœŸœŸœ˜KšœŸœ˜$KšœŸœŸœ˜—headšœ™š   œŸœŸœŸœŸœ˜HKšœŸœŸœ˜#š œŸœ˜KšŸœ ŸœŸœ˜3KšŸœ ŸœŸœ˜6Kšœ˜—šœŸœŸœ ˜KšœŸœ˜š ŸœŸœŸœŸœŸœ˜3Kšœ Ÿœ˜—KšœŸœ˜K˜ —K˜ —K˜Kš   œŸœŸœŸœž5˜WK˜Kš œŸœŸœ@˜QK˜Kš œŸœŸœ+˜>K˜Kš  œŸœŸœœŸœŸœ ˜lK˜š œŸœŸœ&˜:KšœB˜B—K˜š  œŸœŸœ&˜˜Ž—šœ™š  œŸœŸœ˜NšŸœŸœ Ÿ˜Kšœ˜Kšœ˜Kšœ˜KšŸœŸœ˜K˜——š œŸœŸœŸœŸœ Ÿœ'ŸœŸœž,œŸœ Ÿœ˜×KšŸœŸœŸœ"˜2šŸœ˜Kšœ6˜6Kšœ2˜2—K˜—š œŸœŸœŸœŸœ Ÿœ'ŸœŸœž,œŸœ Ÿœ˜×KšŸœŸœŸœ"˜2šŸœ'˜-Kšœ2˜2Kšœ(Ÿœ˜1K˜——š œŸœŸœŸœŸœ Ÿœ'ŸœŸœž,œŸœ Ÿœ˜ÖKšŸœŸœŸœ"˜2šŸœ'˜-Kšœ2˜2Kšœ(ŸœŸœ˜<———šœ™š   œŸ œ,ŸœŸœŸœŸœ˜ƒKšŸœQ˜WKšœ˜K˜—š   œŸ œŸœŸœŸœŸœ˜yšœP˜PKšœŸœ ˜#—Kšœ˜K˜—Kšœ ŸœŸœŸœ˜—šœ™Kš  œŸœŸœŸœŸœ ˜XK˜Kš  œŸœŸœ-˜EK˜Kš  œŸœŸœ,˜CK˜Kš  œŸœŸœ,˜BK˜Kš œŸœŸœŸœ*˜PK˜Kš  œŸœŸœŸœ*˜KK˜Kš  œŸœŸœŸœ*˜KK˜Kš œŸœŸœŸœ.˜XK˜Kš œŸœŸœŸœ.˜SK˜Kš œŸœŸœŸœ.˜S—šœ$™$Kš  œŸœŸœ#˜9K˜Kš  œŸœŸœ%˜=K˜Kš  œŸœŸœ!˜7—šœ%™%Kš  œŸœŸœŸœ'˜JK˜Kš  œŸœŸœŸœ'˜JK˜Kš œŸœŸœ'˜CK˜Kš  œŸœŸœŸœ'˜EK˜Kš œŸœŸœŸœ&˜CK˜Kš œŸœŸœŸœ,˜TK˜Kš œŸœŸœŸœ,˜OK˜Kš  œŸœŸœ"˜9K˜š œŸœŸœŸœ˜3K˜,K˜—Kš œŸœŸœ,˜MK˜Kš œŸœŸœ.˜QK˜Kš œŸœŸœ*˜IK˜Kš œŸœŸœ,˜MK˜Kš œŸœŸœ*˜IK˜Kš œŸœŸœ˜1K˜Kš œŸœŸœ˜/K˜Kš  œŸœŸœ$˜=K˜š œŸœŸœ?˜\K˜SK™—Kš œŸœŸœ*˜?K˜Kš œŸœŸœ)˜=K˜Kš  œŸœŸœ*˜BK˜Kš œŸœŸœ*˜?K˜Kš œŸœŸœ*˜EK˜Kš œŸœŸœ ˜3K˜Kš œŸœŸœ ˜1—šœ ™ Kš œŸœŸœ˜/K˜Kš œŸœŸœ˜-K˜Kš œŸœŸœ˜-K˜Kš œŸœŸœ˜1—šœ™š œŸœŸœ&˜DKšœJ™JšœŸœŸ˜,Kšœ˜Kšœ!˜!Kšœ ˜ KšŸœŸœ˜—K™—š   œŸœŸœŸœŸœ˜EKšŸœW˜]K˜—š œŸœŸœ Ÿœ$˜FKšœ4˜4šŸœŸ˜K˜?—KšŸœH˜LK˜—š œŸœŸœ Ÿœ$˜FKšœ4˜4šŸœŸ˜K˜>—KšŸœG˜KK˜—š  œŸœŸœ Ÿœ$˜KKšœ4˜4šŸœŸ˜K˜>—KšŸœG˜KK˜—š  œŸœŸœ$˜;šŸœŸ˜K˜M—šŸ˜K˜UK˜——Kš  œŸœŸœ!˜7—šœ™š   œŸœŸœ ŸœŸœ˜5KšœŸœ˜&Kš ŸœŸœŸœŸœ Ÿœ˜=šœ˜K˜——š  œŸœŸœ˜DK˜4šŸœŸ˜K˜1˜ šŸœFŸ˜KK˜ KšŸœŸœŸœ˜&KšŸœ˜——KšŸœŸœ˜K˜——š  œŸœŸœ Ÿœ$˜HKš œŸœD˜MK˜K˜—š  œŸœŸœ Ÿœ˜8K˜Kš œ ŸœŸœŸœŸœŸœ˜IK˜K˜4Kšœ%˜%Kšœ˜—K˜š  œŸœŸœ Ÿœ˜6K˜)K˜3Kšœ"˜"Kšœ˜—K˜Kš œŸœŸœ!˜=K˜Kš  œŸœŸœ!˜:K˜Kš  œŸœŸœ"˜9—šœ™š  œŸœŸœ ŸœŸœ˜4KšœŸœ'˜1š ŸœŸœŸœŸœ Ÿœ˜?K˜——š œŸœŸœ Ÿœ$˜FKš œŸœB˜KK˜——šœ™š   œŸœŸœ ŸœŸœ˜5K˜™>š  œŸ œ!Ÿœ˜@KšœÐ™ÐKšœE˜E—K˜š  œŸ œŸœŸœ˜IK™;K˜K˜˜IKšœŸœ˜*—KšŸœ˜KšŸœ Ÿœ˜'—K˜KšœŸœŸœŸœ˜%K˜š  œŸ œŸœ˜4Kšœ>˜>—K˜š  œŸ œŸœŸœŸœŸœŸœŸœ˜rš œŸœŸœŸœŸœ˜