DIRECTORY EditToolPrivate, EditToolBuilder, Buttons, Convert, EditNotify, Inline, IO, UndoEvent, Labels, List, Menus, MessageWindow, NameSymbolTable, NodeAddrs, NodeProps, NodeStyle, Rope, RopeEdit, RopeReader, RunReader, TextEdit, TextFind, TextLooks, TextLooksSupport, TextNode, TEditDisplay, TEditDocument, TEditHistory, TEditInput, TEditInputOps, TEditLocks, TEditOps, TEditRefresh, TEditSelection, TEditTouchup, TreeFind, UserTerminal, ViewerOps, ViewerClasses, ViewerMenus; EditToolSubsImpl: CEDAR PROGRAM IMPORTS EditToolPrivate, EditToolBuilder, --Buttons,-- Convert, Labels, MessageWindow, NodeAddrs, NameSymbolTable, NodeProps, NodeStyle, Rope, RopeReader, TEditOps, TextEdit, TextFind, TextNode, TextLooks, TEditInput, TEditInputOps, TEditLocks, TEditRefresh, TEditSelection, TreeFind EXPORTS EditToolPrivate SHARES Rope = { OPEN ViewerClasses, EditToolBuilder, EditToolPrivate; ---------------------------- Offset: TYPE = TextNode.Offset; ---------------------------- sourceArgAtom: LIST OF REF = Register[$ReplaceBy,SourceArgOp]; clearSourceArgAtom: LIST OF REF = Register[$ClearReplaceBy,ClearSourceArgOp]; SourceButton: Buttons.ButtonProc = { DoButton[sourceArgAtom, clearSourceArgAtom, mouseButton=red] }; SourceArgOp: TEditInput.CommandProc = { SourceArg[mainToolInfo] }; SourceArg: PROC [info: Info] = { SavePSel; DataFieldButton[info.sourceArg,FALSE] }; ClearSourceArgOp: TEditInput.CommandProc = { ClearSourceArg[mainToolInfo] }; ClearSourceArg: PROC [info: Info] = { SavePSel; DataFieldButton[info.sourceArg,TRUE] }; BuildSourceEntry: PUBLIC PROC [info: Info] = { OPEN info; [,sourceArg] _ BuildDataFieldPair[layout, "Replacement:", SourceButton, info, 2] }; ---------------------------- replaceRope: Rope.ROPE = "Replace"; subsRope: Rope.ROPE = "Substitute"; BuildDoItEntries: PUBLIC PROC [info: Info] = { OPEN info; substituteButton _ BuildButton[layout, "Substitute", DoSubstitute, info, TRUE]; [] _ BuildButton[layout, "Yes", DoYes, info]; [] _ BuildButton[layout, "No", DoNo, info]; doitButton _ BuildButton[layout, "Replace", DoIt, info]; [] _ BuildButton[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 = "Do Replace"; specifiedOperation: Rope.ROPE = "Do Operations"; doOperationsAtom: LIST OF REF = Register[$DoOperations,DoOperationsOp]; doReplaceAtom: LIST OF REF = Register[$DoReplace,DoReplaceOp]; OperationButton: Buttons.ButtonProc = { ChangeState[mainToolInfo.doReplace,doReplaceAtom,doOperationsAtom] }; DoOperationsOp: TEditInput.CommandProc = { DoOperations[mainToolInfo] }; DoOperations: PROC [info: Info] = { OPEN info; doReplace _ FALSE; Labels.Set[operationLabel, specifiedOperation] }; DoReplaceOp: TEditInput.CommandProc = { DoRep[mainToolInfo] }; DoRep: PROC [info: Info] = { OPEN info; doReplace _ TRUE; Labels.Set[operationLabel, replaceOperation] }; BuildOperationEntry: PUBLIC PROC [info: Info] = { OPEN info; doReplace _ TRUE; [operationLabel,] _ BuildPair[layout,OperationButton, doReplace,replaceOperation,specifiedOperation,info] }; ---------------------------- ---------------------------- forcingInitCap: Rope.ROPE = "First cap like replaced"; ignoringInitCap: Rope.ROPE = "Don't change caps"; forceInitCapAtom: LIST OF REF = Register[$ChangeInitCap,ChangeInitCapOp]; ignoreInitCapAtom: LIST OF REF = Register[$LeaveInitCap,LeaveInitCapOp]; InitCapButton: Buttons.ButtonProc = { ChangeState[mainToolInfo.forceInitCap, forceInitCapAtom,ignoreInitCapAtom] }; ChangeInitCapOp: TEditInput.CommandProc = { ChangeInitCap[mainToolInfo] }; ChangeInitCap: PROC [info: Info] = { OPEN info; forceInitCap _ TRUE; Labels.Set[initCapLabel,forcingInitCap] }; LeaveInitCapOp: TEditInput.CommandProc = { LeaveInitCap[mainToolInfo] }; LeaveInitCap: PROC [info: Info] = { OPEN info; forceInitCap _ FALSE; Labels.Set[initCapLabel,ignoringInitCap] }; BuildInitCapEntry: PUBLIC PROC [info: Info] = { OPEN info; forceInitCap _ TRUE; [initCapLabel,] _ BuildPair[layout,InitCapButton, forceInitCap,forcingInitCap,ignoringInitCap,info] }; doSubsAtom: LIST OF REF = Register[$DoSubstitute,DoSubstituteOp]; DoSubstitute: Buttons.ButtonProc = { DoButton[doSubsAtom] }; DoSubstituteOp: TEditInput.CommandProc = { DoSubstituteCom[mainToolInfo] }; DoSubstituteCom: PROC [info: Info, countOnly: BOOLEAN _ FALSE] = { OPEN info; subsinfo: SubsInfo _ TextNode.pZone.NEW[SubsInfoRec]; root: TextNode.Ref; { OPEN subsinfo; first, selStart, selEnd: TextNode.Ref; firstText, lastText: TextNode.RefTextNode; lastWhere: TextNode.RefTextNode; pattern: TextNode.RefTextNode; commentControl: TreeFind.CommentControl; type: TextNode.TypeName; style: NameSymbolTable.Name; start: Offset; count: LONG INTEGER; pSel: TEditDocument.Selection; vwr: ViewerClasses.Viewer; data: TEditDocument.TEditDocumentData; insertion: TEditDocument.BeforeAfter; granularity: TEditDocument.SelectionGrain; lit: BOOLEAN; source: TextNode.RefTextNode _ GetDataNode[sourceArg]; size: Offset _ TextEdit.Size[source]; params: LIST OF REF ANY; MakeSel: PROC [where: TextNode.RefTextNode, at, atEnd:Offset] = { 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: PROC [where: TextNode.RefTextNode, at, atEnd, before, after: Offset] RETURNS [continue, bumpCount: BOOLEAN, from, delta: Offset] = { IF interrupt^ THEN { continue _ FALSE; RETURN }; continue _ bumpCount _ TRUE; from _ atEnd; delta _ 0 }; DoSubs: PROC [where: TextNode.RefTextNode, at, atEnd, before, after: Offset] RETURNS [continue, bumpCount: BOOLEAN, from, delta: Offset] = { varRope _ where.rope; varRuns _ where.runs; [continue, bumpCount, from, delta] _ DoOneSubs[info, root, where, at, atEnd, subsinfo, vwr] }; DoOps: PROC [where: TextNode.RefTextNode, at, atEnd, before, after: Offset] RETURNS [continue, bumpCount: BOOLEAN, from, delta: Offset] = { len: Offset _ atEnd-at; size: Offset _ TextEdit.Size[where]; IF interrupt^ THEN { continue _ FALSE; RETURN }; MakeSel[where,at,atEnd]; IF where # lastWhere AND lastWhere # NIL THEN NodeAddrs.RemTextAddr[lastWhere,$After]; lastWhere _ where; NodeAddrs.PutTextAddr[where,$After,atEnd]; TEditInput.Interpret[vwr, params]; delta _ NodeAddrs.GetTextAddr[where,$After].location-atEnd; from _ atEnd+delta; continue _ bumpCount _ TRUE }; event _ TEditInput.CurrentEvent[]; substitute _ TRUE; TEditSelection.LockSel[primary, "DoSubstituteCom"]; FixPSel[]; pSel _ TEditOps.GetSelData[]; IF (~countOnly AND ~TEditInputOps.CheckReadonly[pSel]) OR (root _ TEditSelection.SelectionRoot[pSel])=NIL OR CheckForSubs[info,pSel]=FALSE OR (pattern _ GetPatternNode[info])=NIL THEN { TEditSelection.UnlockSel[primary]; RETURN }; vwr _ pSel.viewer; [pattern,lit,searchLooks,type,style,commentControl] _ GetLooksAndPatternInfo[pattern,info]; SELECT subsRange FROM withinSel => { first _ pSel.start.pos.node; last _ pSel.end.pos.node; start _ pSel.start.pos.where; lastLen _ pSel.end.pos.where+1 }; afterSel => { first _ pSel.end.pos.node; last _ NIL; start _ pSel.end.pos.where+1; lastLen _ 0 }; entireDoc => { first _ TextNode.Root[pSel.start.pos.node]; last _ NIL; start _ 0; 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 _ TextNode.NarrowToTextNode[selStart]) # NIL THEN NodeAddrs.PutTextAddr[firstText,$Start,tSel.start.pos.where]; IF (lastText _ TextNode.NarrowToTextNode[selEnd]) # NIL THEN NodeAddrs.PutTextAddr[lastText,$End,tSel.end.pos.where+1]; interrupt^ _ FALSE; IF source # NIL AND ~countOnly AND doReplace THEN { sourceType _ source.typename; IF ~ignoreStyle THEN sourceStyle _ NodeStyle.StyleNameForNode[source]; sourceComment _ source.comment; sourceRope _ source.rope; sourceRuns _ source.runs }; sourceLen _ size; IF ~ignoreLooks OR ~ignoreText THEN -- create a description of the pattern finder _ TreeFind.Create[ pattern,lit,searchWhere=words,ignoreLooks,ignoreCase,searchWhere=nodes ! TextFind.MalformedPattern => { ReportPatternError[ec]; GOTO Quit }]; IF ~countOnly AND ~doReplace THEN { -- doing specified operations IF (params _ GetOps[info])=NIL THEN { OPEN MessageWindow; Append["Specify operations to be performed.", TRUE]; Blink[]; TEditSelection.UnlockDocAndPSel[root]; RETURN }} ELSE IF doReplace AND ignoreText AND ~ignoreLooks THEN { targetLooks _ GetDataLooks[targetArg,"\"Search for\" field"]; IF ~countOnly THEN sourceLooks _ GetDataLooks[sourceArg,"\"Replace by\" field"] }; IF ~countOnly THEN { TEditSelection.Deselect[]; -- clear selection IF doReplace AND ~literal THEN rdr _ RopeReader.Create[] }; IF ~countOnly AND ~doReplace THEN TEditSelection.LockSel[primary , "DoSubstituteCom"]; count _ TreeFind.Apply[finder,first, IF countOnly THEN CountOnly ELSE IF doReplace THEN DoSubs ELSE DoOps, start,last,lastLen,looksExact,commentControl,~ignoreType,type, ~ignoreStyle,style,NodeStyle.StyleNameForNode]; IF ~countOnly AND ~doReplace THEN TEditSelection.UnlockSel[primary]; tSel.start.pos _ [selStart, IF firstText=NIL THEN TextNode.NodeItself ELSE NodeAddrs.GetTextAddr[firstText,$Start].location]; tSel.end.pos _ [selEnd, IF lastText=NIL THEN TextNode.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 ~countOnly THEN TEditSelection.MakeSelection[new: tSel]; -- restore selection TEditSelection.UnlockDocAndPSel[root]; MessageWindow.Append[ Rope.Concat[Convert.ValueToRope[[signed[count,10]]], IF countOnly THEN IF count # 1 THEN " matches." ELSE " match." ELSE IF count # 1 THEN " substitutions." ELSE " substitution."], TRUE]; EXITS Quit => { TEditSelection.UnlockDocAndPSel[root]; RETURN }; }}; DoOneSubs: PROC [info: Info, root: TextNode.Ref, where: TextNode.RefTextNode, at, atEnd: Offset, subsinfo: SubsInfo, viewer: ViewerClasses.Viewer] RETURNS [continue, bumpCount: BOOLEAN, from, delta: Offset] = { OPEN info, subsinfo; len: Offset _ atEnd-at; size: Offset _ TextEdit.Size[where]; initCap: BOOLEAN _ forceInitCap AND at < size AND TextEdit.FetchChar[where,at] IN ['A..'Z]; initLower: BOOLEAN _ forceInitCap AND at < size AND TextEdit.FetchChar[where,at] IN ['a..'z]; initLooks: TextLooks.Looks; DoType: PROC = { IF ~ignoreType AND where.typename # sourceType THEN TextEdit.ChangeType[where,sourceType,event,root]; }; DoStyle: PROC = { IF ~ignoreStyle AND NodeStyle.StyleNameForNode[where] # sourceStyle THEN { styleRope _ NameSymbolTable.RopeFromName[sourceStyle]; TextEdit.ChangeStyle[where,styleRope,event,root] }; }; DoComment: PROC = { IF ~ignoreComment AND where.comment # sourceComment THEN TextEdit.PutProp[where, "Comment", IF sourceComment THEN NodeProps.true ELSE NodeProps.false, event, root]; }; IF interrupt^ THEN { continue _ FALSE; RETURN }; continue _ bumpCount _ TRUE; from _ atEnd; delta _ 0; SELECT TRUE FROM ignoreText AND ~ignoreLooks => { -- looks only IF searchWhere=anywhere AND substitute THEN { -- need to extend to include entire run [at,atEnd] _ Extend[info,TRUE,searchLooks,where,at,atEnd,last,lastLen]; len _ atEnd-at }; TextEdit.ChangeLooks[root,where,targetLooks,sourceLooks,at,len,event]; from _ at+len; DoType; DoStyle; DoComment; RETURN }; ignoreLooks AND ~ignoreText => initLooks _ IF at < size THEN TextEdit.FetchLooks[where,at] ELSE TextLooks.noLooks; ENDCASE; IF ~ignoreText OR ~ignoreLooks THEN { sLen: Offset _ sourceLen; IF ~literal THEN { -- treat source as pattern end, dest: Offset _ at+len; -- insert after the text to be deleted litstart: Offset _ 0; InsertLit: PROC [after: Offset] = { litlen: Offset _ after-litstart; IF litlen <= 0 THEN RETURN; [] _ TextEdit.ReplaceByText[root,where,dest,0, sourceRope,sourceRuns,litstart,litlen,event]; dest _ dest+litlen }; RopeReader.SetPosition[rdr,sourceRope,0]; DO -- read the source char: CHAR _ RopeReader.Get[rdr ! RopeReader.ReadOffEnd => EXIT]; SELECT char FROM '' => { -- treat next as literal loc: Offset _ RopeReader.GetIndex[rdr]; -- after the quote InsertLit[loc-1]; -- to take care of stuff up to the quote litstart _ loc; [] _ RopeReader.Get[rdr ! RopeReader.ReadOffEnd => EXIT] }; '< => { -- read name, insert value loc: Offset _ RopeReader.GetIndex[rdr]; -- after the < at, atEnd, after: Offset; addLooks: TextLooks.Looks; IF ~ignoreLooks THEN -- read looks from the < at the start of the name addLooks _ TextLooks.FetchLooks[sourceRuns, RopeReader.GetIndex[rdr]-1]; InsertLit[loc-1]; -- to take care of stuff up to the < DO -- read to > IF RopeReader.Get[rdr ! RopeReader.ReadOffEnd => EXIT] = '> THEN EXIT; ENDLOOP; after _ RopeReader.GetIndex[rdr]; -- after the > IF nameRope = NIL THEN nameRope _ TextNode.pZone.NEW[substr node Rope.RopeRep]; nameRope.size _ after-loc-1; nameRope.base _ sourceRope; nameRope.start _ loc; [at,atEnd] _ TextFind.NameLoc[finder,nameRope]; atEnd _ MIN[atEnd,Rope.Size[varRope]]; IF at < atEnd THEN { len: Offset _ atEnd-at; [] _ TextEdit.ReplaceByText[root,where,dest,0,varRope,varRuns,at,len,event]; IF ~ignoreLooks THEN { -- change the looks for the subpattern remLooks: TextLooks.Looks = TextFind.NameLooks[finder, nameRope]; TextEdit.ChangeLooks[root,where,remLooks,addLooks,dest,len,event] }; dest _ dest+len }; litstart _ after; LOOP }; ENDCASE; ENDLOOP; InsertLit[sourceLen]; sLen _ dest-end; -- the length of the replacement text TextEdit.DeleteText[root,where,at,len,event] -- delete last to keep selection addrs correct -- } ELSE [] _ TextEdit.ReplaceByText[root,where,at,len, sourceRope,sourceRuns,0,sourceLen,event]; IF initCap AND sourceLen > 0 AND TextEdit.FetchChar[where,at] IN ['a..'z] THEN TextEdit.ChangeCaps[root,where,at,1,allCaps,event] ELSE IF initLower AND sourceLen > 0 AND TextEdit.FetchChar[where,at] IN ['A..'Z] THEN TextEdit.ChangeCaps[root,where,at,1,allLower,event]; IF ignoreLooks THEN -- just changing the text, so now restore the looks TextEdit.SetLooks[root,where,initLooks,at,sLen,event]; from _ at+sLen; delta _ sLen-len }; DoType; DoStyle; DoComment }; ---------------------------- ---------------------------- doItAtom: LIST OF REF = Register[$DoIt,DoItOp]; DoIt: Buttons.ButtonProc = { DoButton[doItAtom] }; DoItOp: TEditInput.CommandProc = { DoItCom[mainToolInfo] }; DoItCom: PROC [info: Info] = { FixPSel[]; IF info.doReplace THEN DoReplaceCom[info] ELSE DoOpsCom[info] }; tSel: PUBLIC TEditDocument.Selection _ NEW[TEditDocument.SelectionRec]; CheckForSubs: PROC [info: Info, pSel: TEditDocument.Selection] RETURNS [ok: BOOLEAN] = { OPEN info; IF ignoreText AND ignoreLooks AND ignoreType AND ignoreStyle AND ignoreComment THEN { OPEN MessageWindow; Append["Pick one or more of text/looks/type/style/comment to replace.", TRUE]; Blink[]; RETURN [FALSE] }; IF ~CheckPSel[pSel] THEN RETURN [FALSE]; RETURN [TRUE] }; DoReplaceCom: PROC [info: Info] = { OPEN info; subsinfo: SubsInfo; pSel: TEditDocument.Selection; tdd: TEditDocument.TEditDocumentData = NARROW[sourceArg.data]; source: TextNode.RefTextNode _ GetDataNode[sourceArg]; where: TextNode.RefTextNode; root: TextNode.Ref; at, atEnd, delta: TextNode.Offset; TEditSelection.LockSel[primary, "DoReplaceCom"]; FixPSel[]; pSel _ TEditOps.GetSelData[]; IF ~TEditInputOps.CheckReadonly[pSel] OR (root _ TEditSelection.SelectionRoot[pSel])=NIL OR CheckForSubs[info,pSel]=FALSE THEN { TEditSelection.UnlockSel[primary]; RETURN }; IF (where _ TextNode.NarrowToTextNode[pSel.start.pos.node]) # pSel.end.pos.node THEN { OPEN MessageWindow; Append["Selection to replace must be within a single node.", TRUE]; Blink[]; TEditSelection.UnlockSel[primary]; RETURN }; at _ pSel.start.pos.where; atEnd _ pSel.end.pos.where+1; subsinfo _ TextNode.pZone.NEW[SubsInfoRec]; { OPEN subsinfo; event _ TEditInput.CurrentEvent[]; substitute _ FALSE; sourceLen _ TextEdit.Size[source]; IF source # NIL THEN { sourceType _ source.typename; IF ~ignoreStyle THEN sourceStyle _ NodeStyle.StyleNameForNode[source]; sourceComment _ source.comment; sourceRope _ source.rope; sourceRuns _ source.runs }; rdr _ RopeReader.Create[]; IF ignoreText AND ~ignoreLooks THEN { -- looks only targetLooks _ GetDataLooks[targetArg,"\"Search for\" field"]; sourceLooks _ GetDataLooks[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 [TextLooks.Looks] = { node: TextNode.RefTextNode _ TextNode.NarrowToTextNode[pSel.start.pos.node]; loc: Offset _ pSel.start.pos.where; IF node=NIL OR loc=TextNode.NodeItself OR loc=TextEdit.Size[node] THEN RETURN [TextLooks.noLooks]; RETURN [TextEdit.FetchLooks[node,loc]] }; IsSelInitCap: PROC [pSel: TEditDocument.Selection] RETURNS [BOOLEAN] = { node: TextNode.RefTextNode _ TextNode.NarrowToTextNode[pSel.start.pos.node]; loc: Offset _ pSel.start.pos.where; IF node=NIL OR loc=TextNode.NodeItself OR loc=TextEdit.Size[node] THEN RETURN [FALSE]; RETURN [TextEdit.FetchChar[node,loc] IN ['A..'Z]] }; IsSelInitLower: PROC [pSel: TEditDocument.Selection] RETURNS [BOOLEAN] = { node: TextNode.RefTextNode _ TextNode.NarrowToTextNode[pSel.start.pos.node]; loc: Offset _ pSel.start.pos.where; IF node=NIL OR loc=TextNode.NodeItself OR loc=TextEdit.Size[node] THEN RETURN [FALSE]; RETURN [TextEdit.FetchChar[node,loc] IN ['a..'z]] }; doYesAtom: LIST OF REF = Register[$DoYes,DoYesOp]; doYesBackAtom: LIST OF REF = Register[$DoYesBack,DoYesBackOp]; DoYes: Buttons.ButtonProc = { DoButton[doYesAtom, doYesBackAtom, mouseButton=red] }; DoYesOp: TEditInput.CommandProc = { DoYesCom[mainToolInfo] }; DoYesCom: PROC [info: Info] = { DoItCom[info]; Search[forwards,info] }; DoYesBackOp: TEditInput.CommandProc = { DoYesBackCom[mainToolInfo] }; DoYesBackCom: PROC [info: Info] = { DoItCom[info]; Search[backwards,info] }; doNoAtom: LIST OF REF = Register[$DoNo,DoNoOp]; doNoBackAtom: LIST OF REF = Register[$DoNoBack,DoNoBackOp]; DoNo: Buttons.ButtonProc = { DoButton[doNoAtom, doNoBackAtom, mouseButton=red] }; DoNoOp: TEditInput.CommandProc = { DoNoCom[mainToolInfo] }; DoNoCom: PROC [info: Info] = { FixPSel[]; Search[forwards,info] }; DoNoBackOp: TEditInput.CommandProc = { DoNoBackCom[mainToolInfo] }; DoNoBackCom: PROC [info: Info] = { FixPSel[]; Search[backwards,info] }; ---------------------------- doCountAtom: LIST OF REF = Register[$DoCount,DoCountOp]; DoCount: Buttons.ButtonProc = { DoButton[doCountAtom] }; DoCountOp: TEditInput.CommandProc = { DoCountCom[mainToolInfo] }; DoCountCom: PROC [info: Info] = { DoSubstituteCom[info,TRUE] }; ---------------------------- withinSelRope: Rope.ROPE = "Within Selection Only"; afterSelRope: Rope.ROPE = "After Selection Only"; entireDocRope: Rope.ROPE = "In Entire Document"; withinSelAtom: LIST OF REF = Register[$SubstituteInSel,SubsWithinOp]; afterSelAtom: LIST OF REF = Register[$SubstituteAfterSel,SubsAfterOp]; entireDocAtom: LIST OF REF = Register[$SubstituteInEntireDoc,SubsEntireDocOp]; BuildSubstituteEntry: PUBLIC PROC [info: Info] = { OPEN info; subsRange _ entireDoc; [subsRangeLabel,] _ BuildTriple[layout, SubsRangeButton, subsRange, withinSelRope, afterSelRope, entireDocRope, info] }; SubsRangeButton: Buttons.ButtonProc = { CycleTriple[mainToolInfo.subsRange, withinSelAtom, afterSelAtom, entireDocAtom] }; SubsWithinOp: TEditInput.CommandProc = { SubsWithin[mainToolInfo] }; SubsWithin: PROC [info: Info] = { OPEN info; subsRange _ withinSel; Labels.Set[subsRangeLabel,withinSelRope] }; SubsAfterOp: TEditInput.CommandProc = { SubsAfter[mainToolInfo] }; SubsAfter: PROC [info: Info] = { OPEN info; subsRange _ afterSel; Labels.Set[subsRangeLabel,afterSelRope] }; SubsEntireDocOp: TEditInput.CommandProc = { SubsEntireDoc[mainToolInfo] }; SubsEntireDoc: PROC [info: Info] = { OPEN info; subsRange _ entireDoc; Labels.Set[subsRangeLabel,entireDocRope] }; GetLooksAndPatternInfo: PUBLIC PROC [pattern: TextNode.RefTextNode, info: Info] RETURNS [pat: TextNode.RefTextNode, lit: BOOLEAN, searchLooks: TextLooks.Looks, type: TextNode.TypeName, style: NameSymbolTable.Name, commentControl: TreeFind.CommentControl] = { OPEN info; pat _ pattern; lit _ literal; searchLooks _ TextLooks.noLooks; IF ignoreText AND ~ignoreLooks THEN { -- make a phony search pattern and get the looks size: Offset = TextEdit.Size[pattern]; searchLooks _ IF size=0 THEN TextLooks.noLooks ELSE TextEdit.FetchLooks[pattern,0]; FOR i: Offset IN [1..size) DO IF TextEdit.FetchLooks[pattern,i]#searchLooks THEN { OPEN MessageWindow; Append["Search pattern does not have uniform looks.",TRUE]; Append[" Using looks from first char."]; Blink[]; EXIT }; ENDLOOP; lit _ FALSE; pat _ TextEdit.FromRope["#*"]; TextEdit.SetLooks[NIL,pat,searchLooks] }; type _ IF pattern # NIL THEN pat.typename ELSE TextNode.nullTypeName; style _ IF ignoreStyle THEN NameSymbolTable.nullName ELSE NodeStyle.StyleNameForNode[pattern]; commentControl _ IF ignoreComment THEN includeComments ELSE IF pattern # NIL AND pattern.comment THEN commentsOnly ELSE excludeComments; }; }... Â-- EditToolSubsImpl.mesa; Edited by Paxton on January 3, 1983 9:49 am -- Edited by McGregor on August 30, 1982 2:40 pm -- update the selection -- display the number of substitutions made ÊY˜JšÏcE™EJš0™0J˜šÏk ˜ 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˜ J˜ J˜J˜ J˜ J˜ J˜J˜ J˜ J˜ J˜ J˜J˜ J˜—Jšœž ˜J˜Jšžœ$ œå˜œJšžœ˜Jšžœ˜ J˜Jšœžœ1˜7J˜Jš˜J˜Jšœžœ˜J˜Jš˜Jšœžœžœžœ$˜>Jšœžœžœžœ.˜MJ˜˜$J˜?J˜—J˜BJ˜JšÏn œžœ;žœ˜SJ˜J˜LJ˜JšŸœžœ;žœ˜WJ˜šŸœžœžœžœ˜9J˜SJ˜—Jš˜J˜Jšœžœ ˜#Jšœžœ˜#J˜šŸœžœžœžœ˜9JšœIžœ˜OJ˜-J˜+J˜8J˜1J˜J˜—šœžœ˜1Jšœ(žœ˜8J˜—šœžœ˜*Jšœ1˜1J˜—šœžœ˜)Jšœ0˜0J˜—šœžœ˜)Jšœ0˜0J˜—šœžœ˜,Jšœ3˜3J˜—Jš˜Jšœžœ˜+Jšœžœ˜0J˜Jšœžœžœžœ*˜GJšœžœžœžœ$˜>J˜˜'J˜EJ˜—J˜HJ˜šŸ œžœžœ˜.Jšœ žœ˜J˜1J˜—J˜>J˜šŸœžœžœ˜'Jšœ žœ˜J˜/J˜—šŸœžœžœžœ˜J˜/—Jšžœ žœ žœ#˜DJ˜Jš™˜Jšžœ žœžœ˜)Jšžœ3˜7—˜Jšžœ žœžœ˜(Jšžœžœ5˜=—Jšžœžœžœ+˜[Jšžœ žœžœ)˜>Jšžœ žœžœ&˜:Jšžœ žœžœ)˜>J˜J˜J˜J˜J˜Jšžœ žœ*˜PJ˜Jšœ&˜&J˜Jš+™+˜˜4Jš žœ žœžœ žœ žœ ˜>Jš žœžœ žœžœžœ˜GJ˜——Jšžœ žœ&ž œ˜@J˜J˜—šŸ œžœQ˜`J˜1Jšžœžœžœ˜TJ˜J˜$šœ žœž˜#Jšœ žœžœ ˜7—šœ žœž˜%Jšœ žœžœ ˜7—J˜šŸœžœ˜šžœ žœž˜3J˜1—J˜—šŸœžœ˜šžœžœ1žœ˜JJ˜6J˜3—J˜—šŸ œžœ˜šžœžœž˜8˜"Jšžœžœžœ˜H——J˜—Jšžœ žœžœžœ˜0Jšœžœ˜5šžœžœž˜šœ žœ ˜.šžœžœ žœ'˜UJšœžœ*˜GJ˜—J˜FJ˜J˜Jšžœ˜ —šœ žœžœ ž˜J˜6J˜J˜J˜"J˜Jšœ0˜0J˜ J˜šžœ#˜%Jšžœ-ž˜2Jšžœž˜ Jšžœžœ#žœ˜3—J˜šžœNžœ˜VJšžœ˜Jšœ=žœ˜CJšœ,žœ˜5—J˜J˜J˜Jšœžœ˜+J˜Jšœžœ ˜J˜"Jšœ žœ˜J˜"šžœ žœžœ˜J˜Jšžœžœ2˜FJ˜J˜J˜—J˜J˜šžœ žœžœ ˜3J˜=J˜?J˜—J˜Jšœ+˜+Jšœ˜2˜J˜+—J˜0šžœ)žœ,žœ˜`J˜*J˜J˜—J˜(Jšœ+žœ˜2Jšœ&˜&J˜J˜J˜—šŸœžœ!žœ˜SJ˜LJ˜#šžœžœžœžœ˜AJšžœžœ˜ —Jšžœ#˜)J˜—šŸ œžœ!žœžœ˜HJ˜LJ˜#šžœžœžœžœ˜AJšžœžœžœ˜—Jšžœžœ ˜4J˜—šŸœžœ!žœžœ˜JJ˜LJ˜#šžœžœžœžœ˜AJšžœžœžœ˜—Jšžœžœ ˜4J˜—Jšœ žœžœžœ˜2Jšœžœžœžœ$˜>J˜˜J˜6J˜—J˜=J˜JšŸœžœ9˜GJ˜J˜EJ˜JšŸ œžœ:˜LJ˜Jšœ žœžœžœ˜/Jšœžœžœžœ"˜;J˜˜J˜4J˜—J˜;J˜JšŸœžœ5˜BJ˜J˜CJ˜JšŸ œžœ6˜GJ˜Jš˜Jšœ žœžœžœ ˜8J˜˜J˜J˜—J˜AJ˜JšŸ œžœ'žœ˜?J˜Jš˜Jšœžœ˜3Jšœžœ˜1Jšœžœ˜0J˜Jšœžœžœžœ+˜EJšœžœžœžœ-˜FJšœžœžœžœ4˜NJ˜šŸœžœžœžœ˜=J˜˜CJ˜4J˜——˜'J˜RJ˜—J˜DJ˜šŸ œžœžœ˜,J˜J˜+J˜—J˜BJ˜šŸ œžœžœ˜+J˜J˜*J˜—J˜JJ˜šŸ œžœžœ˜/J˜J˜+J˜—šŸœžœžœ,˜Ošžœ˜#Jšœžœ˜ J˜J˜J˜Jšœ-žœ˜7—J˜>šžœ žœžœ0˜VJ˜&šœžœžœ˜.Jšžœ ˜$—šžœ žœ ž˜šžœ,žœ˜4Jšžœ˜Jšœ5žœ˜;J˜)Jšœ žœ˜—Jšžœ˜—Jšœžœ˜ J˜Jšœžœ˜)—Jš œžœ žœžœžœ˜Ešœžœ žœ˜4Jšžœ%˜)—šœžœžœ˜6Jš žœžœ žœžœžœ ˜;Jšžœ˜—J˜J˜—J˜—…—WJke