DIRECTORY Atom USING [GetPName, GetProp], Buttons USING [ButtonProc], Char USING [XCHAR, Set, Narrow, Widen], Convert USING [RopeFromInt], EditToolBuilder USING [BuildButton, BuildDataFieldPair, BuildPair, BuildTriple, DataFieldButton, GetDataLooks, GetDataNode], EditToolPrivate, Labels USING [Set], Menus USING [MenuProc], MessageWindow USING [Append, Blink], NodeAddrs USING [GetTextAddr, PutTextAddr, RemTextAddr], NodeStyleOps USING [StyleNameForNode], Rope USING [Concat, ROPE], TEditDocument USING [BeforeAfter, Selection, SelectionGrain, SelectionRec, TEditDocumentData], TEditInput USING [CommandProc, CurrentEvent, Interpret], TEditInputOps USING [CheckReadonly], TEditLocks USING [Lock], TEditOps USING [GetSelData], TEditRefresh USING [ScrollToEndOfSel], TEditSelection USING [Deselect, LockSel, MakeSelection, pSel, SelectionRoot, UnlockDocAndPSel, UnlockSel], TextEdit, TextNode USING [Root], Tioga, TiogaFind, ViewerClasses USING [Viewer]; EditToolSubsImpl: CEDAR PROGRAM IMPORTS Atom, Char, Convert, EditToolBuilder, EditToolPrivate, Labels, MessageWindow, NodeAddrs, NodeStyleOps, Rope, TEditInput, TEditInputOps, TEditLocks, TEditOps, TEditRefresh, TEditSelection, TextEdit, TextNode, TiogaFind EXPORTS EditToolPrivate = BEGIN Node: TYPE ~ Tioga.Node; Viewer: TYPE ~ ViewerClasses.Viewer; sourceArgAtom: LIST OF REF ~ EditToolPrivate.Register[$ReplaceBy,SourceArgOp]; clearSourceArgAtom: LIST OF REF ~ EditToolPrivate.Register[$ClearReplaceBy,ClearSourceArgOp]; SourceButton: Buttons.ButtonProc ~ { EditToolPrivate.DoButton[sourceArgAtom, clearSourceArgAtom, mouseButton=red]; }; SourceArgOp: TEditInput.CommandProc ~ { SourceArg[EditToolPrivate.mainToolInfo]; }; SourceArg: PROC [info: EditToolPrivate.Info] ~ { EditToolPrivate.SavePSel[]; EditToolBuilder.DataFieldButton[info.sourceArg, FALSE]; }; ClearSourceArgOp: TEditInput.CommandProc ~ { ClearSourceArg[EditToolPrivate.mainToolInfo]; }; ClearSourceArg: PROC [info: EditToolPrivate.Info] ~ { EditToolPrivate.SavePSel[]; EditToolBuilder.DataFieldButton[info.sourceArg,TRUE]; }; BuildSourceEntry: PUBLIC PROC [info: EditToolPrivate.Info] ~ { [,info.sourceArg] ¬ EditToolBuilder.BuildDataFieldPair[info.layout, "Replacement:", SourceButton, info, 2]; }; BuildDoItEntries: PUBLIC PROC [info: EditToolPrivate.Info] ~ { info.substituteButton ¬ EditToolBuilder.BuildButton[info.layout, "Substitute", DoSubstitute, info, TRUE]; [] ¬ EditToolBuilder.BuildButton[info.layout, "Yes", DoYes, info]; [] ¬ EditToolBuilder.BuildButton[info.layout, "No", DoNo, info]; info.doitButton ¬ EditToolBuilder.BuildButton[info.layout, "Replace", DoIt, info]; [] ¬ EditToolBuilder.BuildButton[info.layout, "Count", DoCount, info]; }; DoSubstituteMenuButton: PUBLIC Menus.MenuProc ~ { DoSubstitute[NARROW[parent], clientData, mouseButton]; }; DoYesMenuButton: PUBLIC Menus.MenuProc ~ { DoYes[NARROW[parent], clientData, mouseButton]; }; DoNoMenuButton: PUBLIC Menus.MenuProc ~ { DoNo[NARROW[parent], clientData, mouseButton]; }; DoItMenuButton: PUBLIC Menus.MenuProc ~ { DoIt[NARROW[parent], clientData, mouseButton]; }; DoCountMenuButton: PUBLIC Menus.MenuProc ~ { DoCount[NARROW[parent], clientData, mouseButton]; }; replaceOperation: Rope.ROPE; specifiedOperation: Rope.ROPE; doOperationsAtom: LIST OF REF ~ EditToolPrivate.Register[$DoOperations,DoOperationsOp]; doReplaceAtom: LIST OF REF ~ EditToolPrivate.Register[$DoReplace,DoReplaceOp]; OperationButton: Buttons.ButtonProc ~ { EditToolPrivate.ChangeState[EditToolPrivate.mainToolInfo.doReplace,doReplaceAtom,doOperationsAtom]; }; DoOperationsOp: TEditInput.CommandProc ~ { DoOperations[EditToolPrivate.mainToolInfo] }; DoOperations: PROC [info: EditToolPrivate.Info] ~ { info.doReplace ¬ FALSE; Labels.Set[info.operationLabel, specifiedOperation]; }; DoReplaceOp: TEditInput.CommandProc ~ { DoRep[EditToolPrivate.mainToolInfo] }; DoRep: PROC [info: EditToolPrivate.Info] ~ { info.doReplace ¬ TRUE; Labels.Set[info.operationLabel, replaceOperation]; }; BuildOperationEntry: PUBLIC PROC [info: EditToolPrivate.Info, realNames: BOOL ¬ FALSE] ~ { info.doReplace ¬ TRUE; IF realNames THEN { replaceOperation ¬ "DoReplace"; specifiedOperation ¬ "DoOperations"; } ELSE { replaceOperation ¬ "Do Replace"; specifiedOperation ¬ "Do Operations"; }; [info.operationLabel,] ¬ EditToolBuilder.BuildPair[info.layout,OperationButton, info.doReplace,replaceOperation,specifiedOperation,info]; }; forcingInitCap: Rope.ROPE; ignoringInitCap: Rope.ROPE; forceInitCapAtom: LIST OF REF ~ EditToolPrivate.Register[$ChangeInitCap,ChangeInitCapOp]; ignoreInitCapAtom: LIST OF REF ~ EditToolPrivate.Register[$LeaveInitCap,LeaveInitCapOp]; InitCapButton: Buttons.ButtonProc ~ { EditToolPrivate.ChangeState[EditToolPrivate.mainToolInfo.forceInitCap, forceInitCapAtom,ignoreInitCapAtom]; }; ChangeInitCapOp: TEditInput.CommandProc ~ { ChangeInitCap[EditToolPrivate.mainToolInfo] }; ChangeInitCap: PROC [info: EditToolPrivate.Info] ~ { info.forceInitCap ¬ TRUE; Labels.Set[info.initCapLabel,forcingInitCap]; }; LeaveInitCapOp: TEditInput.CommandProc ~ { LeaveInitCap[EditToolPrivate.mainToolInfo] }; LeaveInitCap: PROC [info: EditToolPrivate.Info] ~ { info.forceInitCap ¬ FALSE; Labels.Set[info.initCapLabel,ignoringInitCap]; }; BuildInitCapEntry: PUBLIC PROC [info: EditToolPrivate.Info, realNames: BOOL ¬ FALSE] ~ { info.forceInitCap ¬ TRUE; IF realNames THEN { forcingInitCap ¬ "ChangeInitCap"; ignoringInitCap ¬ "LeaveInitCap"; } ELSE { forcingInitCap ¬ "First cap like replaced"; ignoringInitCap ¬ "Don't change caps"; }; [info.initCapLabel,] ¬ EditToolBuilder.BuildPair[info.layout,InitCapButton, info.forceInitCap,forcingInitCap,ignoringInitCap,info]; }; doSubsAtom: LIST OF REF ~ EditToolPrivate.Register[$DoSubstitute,DoSubstituteOp]; DoSubstitute: Buttons.ButtonProc ~ { EditToolPrivate.DoButton[doSubsAtom]; }; DoSubstituteOp: TEditInput.CommandProc ~ { DoSubstituteCom[EditToolPrivate.mainToolInfo]; }; DoSubstituteCom: PROC [info: EditToolPrivate.Info, countOnly: BOOL ¬ FALSE] ~ { subsinfo: EditToolPrivate.SubsInfo ¬ NEW[EditToolPrivate.SubsInfoRec]; root: Node; first, selStart, selEnd: Node; firstText, lastText: Node; lastWhere: Node; pattern: EditToolPrivate.Pattern; start: INT; count: INT; pSel: TEditDocument.Selection; vwr: ViewerClasses.Viewer; data: TEditDocument.TEditDocumentData; insertion: TEditDocument.BeforeAfter; granularity: TEditDocument.SelectionGrain; source: Node ¬ EditToolBuilder.GetDataNode[info.sourceArg]; size: INT ¬ TextEdit.Size[source]; params: LIST OF REF ANY; MakeSel: PROC [where: Node, at, atEnd: INT] ~ { tSel.start.pos ¬ [where,at]; tSel.end.pos ¬ [where,MAX[0,atEnd-1]]; tSel.granularity ¬ char; tSel.viewer ¬ vwr; tSel.data ¬ data; tSel.insertion ¬ after; TEditSelection.MakeSelection[new: tSel]; }; CountOnly: TiogaFind.ApplyProc ~ { IF info.interrupt­ THEN { continue ¬ FALSE; RETURN }; continue ¬ bumpCount ¬ TRUE; from ¬ matchEnd; delta ¬ 0 }; DoSubs: TiogaFind.ApplyProc ~ { info.subs ¬ subs; RETURN DoOneSubs[info, root, node, matchStart, matchEnd, subsinfo, vwr]; }; DoOps: TiogaFind.ApplyProc ~ { len: INT ¬ matchEnd-matchStart; size: INT ¬ TextEdit.Size[node]; IF info.interrupt­ THEN { continue ¬ FALSE; RETURN }; MakeSel[node,matchStart,matchEnd]; IF node # lastWhere AND lastWhere # NIL THEN NodeAddrs.RemTextAddr[lastWhere,$After]; lastWhere ¬ node; NodeAddrs.PutTextAddr[node,$After,matchEnd]; TEditInput.Interpret[vwr, params]; delta ¬ NodeAddrs.GetTextAddr[node,$After].location-matchEnd; from ¬ matchEnd+delta; continue ¬ bumpCount ¬ TRUE; }; subsinfo.event ¬ TEditInput.CurrentEvent[]; subsinfo.substitute ¬ TRUE; TEditSelection.LockSel[primary, "DoSubstituteCom"]; EditToolPrivate.FixPSel[]; pSel ¬ TEditOps.GetSelData[]; IF (NOT countOnly AND NOT TEditInputOps.CheckReadonly[pSel]) OR (root ¬ TEditSelection.SelectionRoot[pSel])=NIL OR CheckForSubs[info,pSel]=FALSE OR (pattern ¬ EditToolPrivate.GetPattern[info])=NIL THEN { TEditSelection.UnlockSel[primary]; RETURN }; vwr ¬ pSel.viewer; SELECT info.subsRange FROM withinSel => { first ¬ pSel.start.pos.node; subsinfo.last ¬ pSel.end.pos.node; start ¬ pSel.start.pos.where; subsinfo.lastLen ¬ pSel.end.pos.where+1; }; afterSel => { first ¬ pSel.end.pos.node; subsinfo.last ¬ NIL; start ¬ pSel.end.pos.where+1; subsinfo.lastLen ¬ 0; }; entireDoc => { first ¬ TextNode.Root[pSel.start.pos.node]; subsinfo.last ¬ NIL; start ¬ 0; subsinfo.lastLen ¬ 0; }; ENDCASE => ERROR; data ¬ pSel.data; insertion ¬ pSel.insertion; granularity ¬ pSel.granularity; selStart ¬ pSel.start.pos.node; selEnd ¬ pSel.end.pos.node; tSel­ ¬ pSel­; [] ¬ TEditLocks.Lock[root, "DoSubstituteCom"]; IF (firstText ¬ selStart) # NIL THEN NodeAddrs.PutTextAddr[firstText,$Start,tSel.start.pos.where]; IF (lastText ¬ selEnd) # NIL THEN NodeAddrs.PutTextAddr[lastText,$End,tSel.end.pos.where+1]; info.interrupt­ ¬ FALSE; IF source # NIL AND NOT countOnly AND info.doReplace THEN { subsinfo.sourceFormat ¬ TextEdit.GetFormat[source]; IF NOT info.ignoreStyle THEN subsinfo.sourceStyle ¬ NodeStyleOps.StyleNameForNode[source]; subsinfo.sourceComment ¬ TextEdit.GetComment[source]; subsinfo.sourceNode ¬ source; }; subsinfo.sourceLen ¬ size; IF NOT countOnly AND NOT info.doReplace THEN { -- doing specified operations IF (params ¬ EditToolPrivate.GetOps[info])=NIL THEN { MessageWindow.Append["Specify operations to be performed.", TRUE]; MessageWindow.Blink[]; TEditSelection.UnlockDocAndPSel[root]; RETURN } } ELSE IF info.doReplace AND info.ignoreText AND NOT info.ignoreLooks THEN { subsinfo.targetLooks ¬ EditToolBuilder.GetDataLooks[info.targetArg,"\"Search for\" field"]; IF NOT countOnly THEN subsinfo.sourceLooks ¬ EditToolBuilder.GetDataLooks[info.sourceArg,"\"Replace by\" field"]; }; IF NOT countOnly THEN { TEditSelection.Deselect[]; -- clear selection }; IF NOT countOnly AND NOT info.doReplace THEN TEditSelection.LockSel[primary , "DoSubstituteCom"]; count ¬ TiogaFind.Apply[ proc: IF countOnly THEN CountOnly ELSE IF info.doReplace THEN DoSubs ELSE DoOps, loc1: [first, start], loc2: [subsinfo.last, subsinfo.lastLen], target: pattern.target, case: pattern.case, match: pattern.match, checkLooks: pattern.checkLooks, looksExact: pattern.looksExact, checkComment: pattern.checkComment, comment: pattern.comment, checkFormat: pattern.checkFormat, format: pattern.format, checkStyle: pattern.checkStyle, style: pattern.style, styleProc: NodeStyleOps.StyleNameForNode ]; IF NOT countOnly AND NOT info.doReplace THEN TEditSelection.UnlockSel[primary]; tSel.start.pos ¬ [selStart, IF firstText=NIL THEN Tioga.NodeItself ELSE NodeAddrs.GetTextAddr[firstText,$Start].location]; tSel.end.pos ¬ [selEnd, IF lastText=NIL THEN Tioga.NodeItself ELSE MAX[NodeAddrs.GetTextAddr[lastText,$End].location,1]-1]; IF selStart=selEnd THEN tSel.end.pos.where ¬ MAX[tSel.start.pos.where, tSel.end.pos.where]; IF firstText#NIL THEN NodeAddrs.RemTextAddr[firstText,$Start]; IF lastText#NIL THEN NodeAddrs.RemTextAddr[lastText,$End]; IF lastWhere#NIL THEN NodeAddrs.RemTextAddr[lastWhere,$After]; tSel.granularity ¬ granularity; tSel.viewer ¬ vwr; tSel.data ¬ data; tSel.insertion ¬ insertion; IF NOT countOnly THEN TEditSelection.MakeSelection[new: tSel]; -- restore selection TEditSelection.UnlockDocAndPSel[root]; MessageWindow.Append[ Rope.Concat[Convert.RopeFromInt[count], IF countOnly THEN IF count # 1 THEN " matches." ELSE " match." ELSE IF count # 1 THEN " substitutions." ELSE " substitution."], TRUE]; { cmdPtr: REF ANY ¬ Atom.GetProp[$CafeteriaTrayRegistryAtom, $EditToolAddToTray]; IF cmdPtr # NIL THEN { EditToolAddInterfaceProc: TYPE ~ PROC [operation: ATOM, opList: Rope.ROPE ¬ NIL]; -- same as EditToolCafeteria.EditToolAddInterfaceProc addProcPtr: REF EditToolAddInterfaceProc ¬ NARROW[cmdPtr, REF EditToolAddInterfaceProc]; addProcPtr[$DoSubstitute, IF NOT info.doReplace THEN EditToolBuilder.GetDataNode[info.opsArg].rope ELSE NIL]; } }; }; CapClass: TYPE ~ {nil, upper, lower}; GetCapClass: PROC [node: Node, index: INT] RETURNS [CapClass ¬ nil] ~ { x: Char.XCHAR ~ TextEdit.FetchChar[node, index]; IF Char.Set[x]=0 THEN SELECT Char.Narrow[x] FROM IN ['A..'Z] => RETURN[upper]; IN ['a..'z] => RETURN[lower]; ENDCASE; }; DoOneSubs: PROC [info: EditToolPrivate.Info, root: Node, dest: Node, destStart, destEnd: INT, subsinfo: EditToolPrivate.SubsInfo, viewer: ViewerClasses.Viewer] RETURNS [continue, bumpCount: BOOL ¬ FALSE, from, delta: INT ¬ 0] ~ { destLen: INT ~ destEnd-destStart; source: Node ~ subsinfo.sourceNode; sourceSize: INT ~ TextEdit.Size[source]; initLooks: Tioga.Looks ¬ Tioga.noLooks; event: Tioga.Event ~ subsinfo.event; IF info.interrupt­ THEN { continue ¬ FALSE; RETURN }; continue ¬ bumpCount ¬ TRUE; from ¬ destEnd; delta ¬ 0; IF NOT info.ignoreText THEN { replacedCap, resultCap: CapClass ¬ nil; replacedLooks: Tioga.Looks ¬ Tioga.noLooks; resultStart, resultLen: INT ¬ 0; IF destLen>0 THEN { IF info.ignoreLooks THEN replacedLooks ¬ TextEdit.FetchLooks[dest, destStart]; IF info.forceInitCap THEN replacedCap ¬ GetCapClass[dest, destStart]; }; [resultStart, resultLen] ¬ TiogaFind.Replace[dest: dest, destStart: destStart, destLen: destLen, source: source, pattern: NOT info.literal, subs: info.subs, event: event]; IF replacedCap#nil AND resultLen>0 THEN resultCap ¬ GetCapClass[dest, resultStart]; IF replacedCap#nil AND resultCap#nil AND replacedCap#resultCap THEN { TextEdit.ChangeCaps[root: NIL, dest: dest, start: resultStart, len: 1, how: IF replacedCap=upper THEN allCaps ELSE allLower, event: event] }; IF info.ignoreLooks THEN {-- just changing the text, so now restore the looks TextEdit.ChangeLooks[root: root, text: dest, remove: Tioga.allLooks, add: replacedLooks, start: resultStart, len: resultLen, event: event]; }; from ¬ resultStart+resultLen; delta ¬ resultLen-destLen; } ELSE IF NOT info.ignoreLooks THEN { -- looks only TextEdit.ChangeLooks[root: root, text: dest, remove: subsinfo.targetLooks, add: subsinfo.sourceLooks, start: destStart, len: destLen, event: event]; }; IF NOT info.ignoreComment THEN TextEdit.PutComment[dest, subsinfo.sourceComment, event]; IF NOT info.ignoreFormat THEN TextEdit.PutFormat[dest, subsinfo.sourceFormat, event]; IF NOT info.ignoreStyle AND NodeStyleOps.StyleNameForNode[dest] # subsinfo.sourceStyle THEN { subsinfo.styleRope ¬ IF subsinfo.sourceStyle=NIL THEN NIL ELSE Atom.GetPName[subsinfo.sourceStyle]; TextEdit.ChangeStyle[dest, subsinfo.styleRope, event]; }; }; doItAtom: LIST OF REF ~ EditToolPrivate.Register[$DoIt, DoItOp]; DoIt: Buttons.ButtonProc ~ { EditToolPrivate.DoButton[doItAtom] }; DoItOp: TEditInput.CommandProc ~ { DoItCom[EditToolPrivate.mainToolInfo] }; DoItCom: PROC [info: EditToolPrivate.Info] ~ { EditToolPrivate.FixPSel[]; IF info.doReplace THEN DoReplaceCom[info] ELSE EditToolPrivate.DoOpsCom[info]; }; tSel: PUBLIC TEditDocument.Selection ¬ NEW[TEditDocument.SelectionRec]; CheckForSubs: PROC [info: EditToolPrivate.Info, pSel: TEditDocument.Selection] RETURNS [ok: BOOL] ~ { IF info.ignoreText AND info.ignoreLooks AND info.ignoreFormat AND info.ignoreStyle AND info.ignoreComment THEN { MessageWindow.Append["Pick one or more of text/looks/format/style/comment to replace.", TRUE]; MessageWindow.Blink[]; RETURN [FALSE]; }; IF NOT EditToolPrivate.CheckPSel[pSel] THEN RETURN [FALSE]; RETURN [TRUE]; }; DoReplaceCom: PROC [info: EditToolPrivate.Info] ~ { subsinfo: EditToolPrivate.SubsInfo; pSel: TEditDocument.Selection; source: Node ¬ EditToolBuilder.GetDataNode[info.sourceArg]; where: Node; root: Node; at, atEnd, delta: INT; TEditSelection.LockSel[primary, "DoReplaceCom"]; EditToolPrivate.FixPSel[]; pSel ¬ TEditOps.GetSelData[]; IF NOT TEditInputOps.CheckReadonly[pSel] OR (root ¬ TEditSelection.SelectionRoot[pSel])=NIL OR CheckForSubs[info,pSel]=FALSE THEN { TEditSelection.UnlockSel[primary]; RETURN }; IF (where ¬ pSel.start.pos.node) # pSel.end.pos.node THEN { MessageWindow.Append["Selection to replace must be within a single node.", TRUE]; MessageWindow.Blink[]; TEditSelection.UnlockSel[primary]; RETURN }; at ¬ pSel.start.pos.where; atEnd ¬ IF pSel.granularity=point THEN at ELSE pSel.end.pos.where+1; subsinfo ¬ NEW[EditToolPrivate.SubsInfoRec]; subsinfo.event ¬ TEditInput.CurrentEvent[]; subsinfo.substitute ¬ FALSE; subsinfo.sourceLen ¬ TextEdit.Size[source]; IF source # NIL THEN { subsinfo.sourceFormat ¬ TextEdit.GetFormat[source]; subsinfo.sourceComment ¬ TextEdit.GetComment[source]; IF NOT info.ignoreStyle THEN subsinfo.sourceStyle ¬ NodeStyleOps.StyleNameForNode[source]; subsinfo.sourceNode ¬ source; }; IF info.ignoreText AND NOT info.ignoreLooks THEN { -- looks only subsinfo.targetLooks ¬ EditToolBuilder.GetDataLooks[info.targetArg,"\"Search for\" field"]; subsinfo.sourceLooks ¬ EditToolBuilder.GetDataLooks[info.sourceArg,"\"Replace by\" field"]; }; tSel­ ¬ pSel­; [] ¬ TEditLocks.Lock[root, "DoReplaceCom"]; TEditSelection.Deselect[]; -- remove the selection delta ¬ DoOneSubs[info, root, where, at, atEnd, subsinfo, tSel.viewer].delta; tSel.end.pos.where ¬ tSel.end.pos.where + delta; IF tSel.start.pos.node = tSel.end.pos.node AND tSel.start.pos.where > tSel.end.pos.where THEN { tSel.end.pos.where ¬ tSel.start.pos.where; tSel.granularity ¬ point; tSel.insertion ¬ before }; TEditSelection.MakeSelection[new: tSel]; TEditRefresh.ScrollToEndOfSel[tSel.viewer, FALSE]; TEditSelection.UnlockDocAndPSel[root]; }; GetSelInitLooks: PROC [pSel: TEditDocument.Selection] RETURNS [Tioga.Looks] ~ { node: Node ¬ pSel.start.pos.node; loc: INT ¬ pSel.start.pos.where; IF node=NIL OR loc=Tioga.NodeItself OR loc=TextEdit.Size[node] THEN RETURN [Tioga.noLooks]; RETURN [TextEdit.FetchLooks[node,loc]]; }; IsSelInitCap: PROC [pSel: TEditDocument.Selection] RETURNS [BOOL] ~ { node: Node ¬ pSel.start.pos.node; loc: INT ¬ pSel.start.pos.where; IF node=NIL OR loc=Tioga.NodeItself OR loc=TextEdit.Size[node] THEN RETURN [FALSE]; RETURN [TextEdit.FetchChar[node,loc] IN [Char.Widen['A]..Char.Widen['Z]]]; }; IsSelInitLower: PROC [pSel: TEditDocument.Selection] RETURNS [BOOL] ~ { node: Node ¬ pSel.start.pos.node; loc: INT ¬ pSel.start.pos.where; IF node=NIL OR loc=Tioga.NodeItself OR loc=TextEdit.Size[node] THEN RETURN [FALSE]; RETURN [TextEdit.FetchChar[node,loc] IN [Char.Widen['a]..Char.Widen['z]]]; }; doYesAtom: LIST OF REF ~ EditToolPrivate.Register[$DoYes,DoYesOp]; doYesBackAtom: LIST OF REF ~ EditToolPrivate.Register[$DoYesBack,DoYesBackOp]; DoYes: Buttons.ButtonProc ~ { EditToolPrivate.DoButton[doYesAtom, doYesBackAtom, mouseButton=red]; }; DoYesOp: TEditInput.CommandProc ~ { DoYesCom[EditToolPrivate.mainToolInfo] }; DoYesCom: PROC [info: EditToolPrivate.Info] ~ { DoItCom[info]; EditToolPrivate.Search[forwards,info]; }; DoYesBackOp: TEditInput.CommandProc ~ { DoYesBackCom[EditToolPrivate.mainToolInfo] }; DoYesBackCom: PROC [info: EditToolPrivate.Info] ~ { DoItCom[info]; EditToolPrivate.Search[backwards,info]; }; doNoAtom: LIST OF REF ~ EditToolPrivate.Register[$DoNo,DoNoOp]; doNoBackAtom: LIST OF REF ~ EditToolPrivate.Register[$DoNoBack,DoNoBackOp]; DoNo: Buttons.ButtonProc ~ { EditToolPrivate.DoButton[doNoAtom, doNoBackAtom, mouseButton=red]; }; DoNoOp: TEditInput.CommandProc ~ { DoNoCom[EditToolPrivate.mainToolInfo] }; DoNoCom: PROC [info: EditToolPrivate.Info] ~ { EditToolPrivate.FixPSel[]; EditToolPrivate.Search[forwards,info]; }; DoNoBackOp: TEditInput.CommandProc ~ { DoNoBackCom[EditToolPrivate.mainToolInfo]; }; DoNoBackCom: PROC [info: EditToolPrivate.Info] ~ { EditToolPrivate.FixPSel[]; EditToolPrivate.Search[backwards,info]; }; doCountAtom: LIST OF REF ~ EditToolPrivate.Register[$DoCount,DoCountOp]; DoCount: Buttons.ButtonProc ~ { EditToolPrivate.DoButton[doCountAtom]; }; DoCountOp: TEditInput.CommandProc ~ { DoCountCom[EditToolPrivate.mainToolInfo] }; DoCountCom: PROC [info: EditToolPrivate.Info] ~ { DoSubstituteCom[info,TRUE] }; withinSelRope: Rope.ROPE; afterSelRope: Rope.ROPE; entireDocRope: Rope.ROPE; withinSelAtom: LIST OF REF ~ EditToolPrivate.Register[$SubstituteInSel,SubsWithinOp]; afterSelAtom: LIST OF REF ~ EditToolPrivate.Register[$SubstituteAfterSel,SubsAfterOp]; entireDocAtom: LIST OF REF ~ EditToolPrivate.Register[$SubstituteInEntireDoc,SubsEntireDocOp]; BuildSubstituteEntry: PUBLIC PROC [info: EditToolPrivate.Info, realNames: BOOL ¬ FALSE] ~ { info.subsRange ¬ entireDoc; IF realNames THEN { withinSelRope ¬ "SubstituteInSel"; afterSelRope ¬ "SubstituteAfterSel"; entireDocRope ¬ "SubstituteInEntireDoc"; } ELSE { withinSelRope ¬ "Within Selection Only"; afterSelRope ¬ "After Selection Only"; entireDocRope ¬ "In Entire Document"; }; [info.subsRangeLabel,] ¬ EditToolBuilder.BuildTriple[info.layout, SubsRangeButton, ORD[info.subsRange], withinSelRope, afterSelRope, entireDocRope, info]; }; SubsRangeButton: Buttons.ButtonProc ~ { EditToolPrivate.CycleTriple[ORD[EditToolPrivate.mainToolInfo.subsRange], withinSelAtom, afterSelAtom, entireDocAtom]; }; SubsWithinOp: TEditInput.CommandProc ~ { SubsWithin[EditToolPrivate.mainToolInfo] }; SubsWithin: PROC [info: EditToolPrivate.Info] ~ { info.subsRange ¬ withinSel; Labels.Set[info.subsRangeLabel,withinSelRope]; }; SubsAfterOp: TEditInput.CommandProc ~ { SubsAfter[EditToolPrivate.mainToolInfo] }; SubsAfter: PROC [info: EditToolPrivate.Info] ~ { info.subsRange ¬ afterSel; Labels.Set[info.subsRangeLabel,afterSelRope]; }; SubsEntireDocOp: TEditInput.CommandProc ~ { SubsEntireDoc[EditToolPrivate.mainToolInfo] }; SubsEntireDoc: PROC [info: EditToolPrivate.Info] ~ { info.subsRange ¬ entireDoc; Labels.Set[info.subsRangeLabel,entireDocRope]; }; END.  EditToolSubsImpl.mesa Copyright Σ 1985, 1986, 1991, 1992, 1993 by Xerox Corporation. All rights reserved. Michael Plass, February 25, 1991 4:25 pm PST Russ Atkinson (RRA) June 18, 1985 5:07:32 pm PDT Alison Lee September 8, 1986 10:21:02 pm PDT Doug Wyatt, June 3, 1993 2:41 pm PDT update the selection display the number of substitutions made Attempt to register in EditTool Cafeteria tray if the registry operation is available. This is deferred to this late because, only properly specified commands will be recorded. Κέ•NewlineDelimiter –(cedarcode) style™codešœ™Kšœ ΟeœI™TKšœ,™,K™0K™,K™$K™—šΟk ˜ Kšœžœ˜Kšœžœ˜Kšœžœžœ˜'Kšœžœ˜Kšœžœg˜|Kšœ˜Kšœžœ˜Kšœžœ ˜Kšœžœ˜$Kšœ žœ)˜8Kšœ žœ˜&Kšœžœ žœ˜KšœžœK˜^Kšœ žœ(˜8Kšœžœ˜$Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜&KšœžœV˜jKšœ ˜ Kšœ žœ˜Kšœ˜K˜ Kšœžœ ˜K˜—šΟnœžœž˜KšžœΪ˜αKšžœ˜Kšœž˜K˜Kšœžœ˜Kšœžœ˜$K˜Kšœžœžœžœ4˜NKšœžœžœžœ>˜]šŸ œ˜$K˜MK˜—šŸ œ˜'K˜(K˜—šŸ œžœ!˜0Kšœ˜Kšœ0žœ˜7Kšœ˜—šŸœ˜,K˜-K˜—šŸœžœ!˜5Kšœ˜Kšœ/žœ˜5Kšœ˜—šŸœžœžœ!˜>K˜kK˜—šŸœžœžœ!˜>Kšœcžœ˜iKšœB˜BKšœ@˜@KšœR˜RKšœF˜FK˜—K˜šŸœžœ˜1Kšœ žœ#˜6K˜—šŸœžœ˜*Kšœžœ#˜/K˜—šŸœžœ˜)Kšœžœ#˜.K˜—šŸœžœ˜)Kšœžœ#˜.K˜—šŸœžœ˜,Kšœžœ#˜1K˜—K˜Kšœžœ˜Kšœžœ˜Kšœžœžœžœ:˜WKšœžœžœžœ4˜NšŸœ˜'K˜cK˜—K˜KšŸœJ˜XšŸ œžœ!˜3Kšœžœ˜K˜4K˜—K˜KšŸ œC˜NšŸœžœ!˜,Kšœžœ˜K˜2K˜—K˜š Ÿœžœžœ)žœžœ˜ZKšœžœ˜šžœ žœ˜Kšœ˜Kšœ$˜$K˜—šžœ˜Kšœ ˜ Kšœ%˜%K˜—šœO˜OK˜9—K˜—K˜Kšœžœ˜Kšœžœ˜Kšœžœžœžœ<˜YKšœžœžœžœ:˜XšŸ œ˜%˜FK˜$—K˜—K˜KšŸœK˜ZšŸ œžœ!˜4Kšœžœ˜K˜-K˜—K˜KšŸœJ˜XšŸ œžœ!˜3Kšœžœ˜K˜.K˜—K˜š Ÿœžœžœ)žœžœ˜XKšœžœ˜šžœ žœ˜Kšœ!˜!Kšœ!˜!—K˜šžœ˜Kšœ+˜+Kšœ&˜&—K˜šœK˜KK˜7—K˜—K˜Kšœ žœžœžœ:˜QšŸ œ˜$K˜%K˜—šŸœ˜*Kšœ.˜.Kšœ˜—šŸœžœ)žœžœ˜OKšœ%žœ˜FK˜ K˜K˜K˜K˜!Kšœžœ˜ Kšœžœ˜ K˜K˜K˜&K˜%K˜*K˜;Kšœžœ˜"Kš œžœžœžœžœ˜K˜šŸœžœžœ˜/K˜Kšœžœ ˜&K˜K˜K˜K˜K˜(K˜—K˜šŸ œ˜"Kšžœžœžœžœ˜5Kšœžœ˜K˜K˜—K˜šŸœ˜K˜KšžœB˜HK˜—K˜šŸœ˜Kšœžœ˜Kšœžœ˜ Kšžœžœžœžœ˜5K˜"Kšžœžœ žœž˜,K˜(K˜K˜,K˜"K˜=Kšœ.žœ˜3K˜—K˜K˜+Kšœžœ˜K˜K˜3K˜K˜Kšžœžœ žœžœ#˜˜ZK˜5K˜K˜—K˜K˜š žœžœ žœžœžœΟc˜Lšžœ)žœžœ˜7Kšœ<žœ˜BKšœ>žœ˜EK˜—K˜—š žœžœžœžœžœžœ˜JKšœ[˜[Kšžœžœ žœ\˜qK˜—šžœžœ žœ˜Kšœ ˜-K˜—Kš žœžœ žœžœžœ5˜a•StartOfExpansionη[finder: TextFind.Finder, first: TextNode.Ref, proc: TreeFind.ApplyProc, start: INT _ 0, last: TextNode.Ref _ NIL, lastLen: INT _ 2147483647, looksExact: BOOL _ FALSE, commentControl: TreeFind.CommentControl _ includeComments, checkFormat: BOOL _ FALSE, format: TextNode.FormatName, checkStyle: BOOL _ FALSE, style: NameSymbolTable.Name, styleProc: PROC [...]šœ˜Kš œžœ žœ žœžœžœžœ˜PKšœ>˜>KšœB˜BKšœ?˜?Kšœ=˜=Kšœ9˜9Kšœ5˜5Kšœ(˜(Kšœ˜—Kš žœžœ žœžœžœ#˜OK˜Kšœ™˜Kšžœ žœžœ˜&Kšžœ3˜7—˜Kšžœ žœžœ˜%Kšžœžœ5˜=—Kšžœžœžœ+˜[Kšžœ žœžœ)˜>Kšžœ žœžœ&˜:Kšžœ žœžœ)˜>K˜K˜K˜K˜K˜Kšžœžœ žœ* ˜SK˜K˜&K˜Kšœ(™(˜˜'Kš žœ žœžœ žœ žœ ˜>Kš žœžœ žœžœžœ˜G——K˜˜K™²Kšœžœžœ@˜Ošžœ ž˜šžœ˜Kš œžœžœ žœžœžœ 5˜‡Kšœ žœžœ žœ˜Xšœ˜Kš žœžœžœ/žœžœ˜S—K˜——K˜—K˜—K˜šœ žœ˜%K˜—šŸ œžœžœžœ˜GKšœžœ#˜0šžœžœžœž˜0Kšžœ žœ˜Kšžœ žœ˜Kšžœ˜—K˜K™—šŸ œžœJžœFžœžœžœžœ ˜ηKšœ žœ˜!Kšœ#˜#Kšœ žœ˜(Kšœ'˜'Kšœ$˜$Kšžœžœžœžœ˜5Kšœžœ˜7šžœžœžœ˜K˜'Kšœ+˜+Kšœžœ˜ šžœ žœ˜Kšžœžœ6˜NKšžœžœ,˜EK˜—Kšœ{žœ.˜¬Kšžœžœ žœ,˜Sšžœžœžœžœ˜EKš œžœ0žœžœ žœ˜‹K˜—šžœžœ 3˜MKšœŒ˜ŒK˜—Kšœ8˜8K˜—š žœžœžœžœ  ˜1Kšœ•˜•K˜—Kšžœžœžœ;˜YKšžœžœžœ9˜Všžœžœžœ=žœ˜^Kš œžœžœžœžœžœ%˜cKšœ6˜6K˜—K˜—K˜Kšœ žœžœžœ+˜@KšŸœ>˜BKšŸœE˜KšŸœžœ!˜.K˜Kšžœžœžœ ˜NK˜—K˜Kšœžœžœ˜GšŸ œžœ=žœžœ˜eKšžœžœžœ˜=šžœžœžœ˜4KšœXžœ˜^Kšœžœžœ˜&K˜—Kš žœžœ!žœžœžœ˜;Kšžœžœ˜K˜—K˜šŸ œžœ!˜3K˜#K˜K˜;K˜ K˜ Kšœžœ˜K˜K˜0K˜K˜Kšžœžœ"˜(Kšžœ-ž˜2Kšžœž˜ Kšžœ&žœ˜3K˜šžœ3žœ˜;KšœKžœ˜QKšœ:žœ˜AK˜—K˜Kšœžœžœžœ˜DK˜Kšœ žœ˜,K˜K˜+Kšœžœ˜K˜+šžœ žœžœ˜K˜3K˜5Kšžœžœžœ>˜ZK˜K˜—K˜š žœžœžœžœ  ˜@K˜[K˜[K˜—K˜K˜K˜+Kšœ ˜2K˜MK˜0šžœ)žœ,žœ˜`K˜*K˜K˜K˜—K˜(Kšœ+žœ˜2K˜&K˜—K˜šŸœžœ!žœ˜OK˜!Kšœžœ˜ Kšžœžœžœžœ˜>Kšžœžœ˜Kšžœ!˜'K˜K˜—šŸ œžœ!žœžœ˜EK˜!Kšœžœ˜ Kšžœžœžœžœžœžœžœ˜SKšžœžœ#˜JK˜—K˜šŸœžœ!žœžœ˜GK˜!Kšœžœ˜ Kšžœžœžœžœžœžœžœ˜SKšžœžœ#˜JK˜—K˜Kšœ žœžœžœ,˜BKšœžœžœžœ4˜NšŸœ˜K˜DK˜—KšŸœF˜MšŸœžœ!˜/Kšœ˜Kšœ&˜&Kšœ˜—KšŸ œJ˜UšŸ œžœ!˜3Kšœ˜Kšœ'˜'Kšœ˜—Kšœ žœžœžœ*˜?Kšœžœžœžœ2˜KšŸœ˜K˜BK˜—KšŸœE˜KšŸœžœ!˜.Kšœ˜Kšœ&˜&Kšœ˜—šŸ œ˜&K˜*K˜—šŸ œžœ!˜2Kšœ˜Kšœ'˜'Kšœ˜—Kšœ žœžœžœ0˜HšŸœ˜K˜&K˜—K˜KšŸ œH˜QKšŸ œžœ7žœ˜OKšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœžœžœ;˜UKšœžœžœžœ=˜VKšœžœžœžœD˜^š Ÿœžœžœ)žœžœ˜[K˜šžœ žœ˜Kšœ"˜"Kšœ$˜$Kšœ(˜(K˜—šžœ˜Kšœ(˜(Kšœ&˜&Kšœ%˜%K˜—KšœSžœD˜šK˜—K˜šŸœ˜'KšœžœV˜uK˜—K˜KšŸ œH˜TšŸ œžœ!˜1K˜K˜.K˜—K˜KšŸ œG˜RšŸ œžœ!˜0K˜K˜-K˜—K˜KšŸœK˜ZšŸ œžœ!˜4K˜K˜.K˜—K˜K˜—Kšžœ˜—…—SΤjΗ