DIRECTORY TiogaOpsDefs, EditSpan, MessageWindow, NameSymbolTable, NodeStyle, Rope, RunReader, TEditDocument, TEditDocumentPrivate, TEditInput, TEditInputOps, TEditLocks, TEditMesaOps, TEditOps, TEditProfile, TEditRefresh, TEditScrolling, TEditSelection, TextEdit, TextFind, TextFindPrivate, TextLooks, TextLooksSupport, TextNode, TiogaOps, TiogaExtraOps, TiogaMenuOps, TreeFind; TiogaOps2Impl: CEDAR PROGRAM IMPORTS MessageWindow, NameSymbolTable, NodeStyle, Rope, RunReader, TEditDocumentPrivate, TEditInput, TEditInputOps, TEditOps, TEditProfile, TEditRefresh, TEditScrolling, TEditSelection, TextEdit, TextFind, TextLooksSupport, TextNode, TreeFind EXPORTS TiogaOpsDefs, TiogaOps, TiogaMenuOps = BEGIN OPEN TiogaOps, TiogaMenuOps, TiogaOpsDefs; Ref: TYPE = REF NodeBody; -- points to a Tioga node NodeBody: PUBLIC TYPE = TextNode.Body; Finder: TYPE = REF FinderRec; FinderRec: PUBLIC TYPE = TextFindPrivate.FinderRecord; LooksRope: PROC [looks: TextLooks.Looks] RETURNS [r: ROPE] = { FOR c: CHAR IN TextLooks.Look DO IF looks[c] THEN r _ Rope.Concat[r, Rope.FromChar[c]]; ENDLOOP }; RopeToLooks: PROC [r: ROPE] RETURNS [looks: TextLooks.Looks] = { Set: PROC [c: CHAR] RETURNS [quit: BOOL _ FALSE] = { looks[c] _ TRUE }; [] _ Rope.Map[base: r, action: Set]; }; CreateGeneralPattern: PUBLIC PROC [ target: Ref, -- node from which to get the pattern text: BOOL _ TRUE, -- if true, match target text looks: BOOL _ FALSE, -- if true, match target looks format: BOOL _ FALSE, -- if true, match target format style: BOOL _ FALSE, -- if true, match target style comment: BOOL _ FALSE, -- if true, match target comment property case: BOOL _ TRUE, -- if true, match case literal: BOOL _ FALSE, -- if true, treat target literally rather than as a pattern word: BOOL _ FALSE, -- if true, match words only subset: BOOL _ TRUE, -- if true, use subset for looks test, else use equality addBounds: BOOL _ FALSE] -- if true, add |'s to both ends of pattern RETURNS [pattern: Pattern] = { txt: TextNode.RefTextNode = TextNode.NarrowToTextNode[target]; patternTxt: TextNode.RefTextNode _ txt; pattern _ TextNode.pZone.NEW[PatternRec]; IF looks AND ~text THEN { -- make a phony search pattern and get the looks size: Offset = TextEdit.Size[txt]; lks: TextLooks.Looks = IF size=0 THEN TextLooks.noLooks ELSE TextEdit.FetchLooks[txt,0]; pattern.searchLooks _ LooksRope[lks]; FOR i: Offset IN [1..size) DO IF TextEdit.FetchLooks[txt,i]#lks THEN { OPEN MessageWindow; Append["Search pattern does not have uniform looks.",TRUE]; Append[" Using looks from first char."]; EXIT }; ENDLOOP; literal _ FALSE; patternTxt _ TextEdit.FromRope["#*"]; TextEdit.SetLooks[NIL, patternTxt, lks] }; pattern.text _ text; pattern.looks _ looks; pattern.word _ word; pattern.looksExact _ ~subset; pattern.commentControl _ IF ~comment OR txt=NIL THEN includeComments ELSE IF txt.comment THEN commentsOnly ELSE excludeComments; pattern.checkType _ format; pattern.type _ IF target=NIL OR target.typename=TextNode.nullTypeName THEN NIL ELSE NameSymbolTable.RopeFromName[target.typename]; pattern.checkStyle _ style; pattern.style _ IF ~style THEN NIL ELSE NameSymbolTable.RopeFromName[NodeStyle.StyleNameForNode[target]]; IF text OR looks THEN TRUSTED { -- create a description of the pattern pattern.finder _ LOOPHOLE[ TreeFind.Create[patternTxt, literal, word, ~looks, ~case, addBounds]]}; }; CreateSimplePattern: PUBLIC PROC [ target: ROPE, -- node from which to get the pattern case: BOOL _ TRUE, -- if true, match case literal: BOOL _ FALSE, -- if true, treat target literally rather than as a pattern word: BOOL _ FALSE, -- if true, match words only addBounds: BOOL _ FALSE] -- if true, add |'s to both ends of pattern RETURNS [pattern: Pattern] = { pattern _ TextNode.pZone.NEW[PatternRec]; pattern.text _ TRUE; pattern.looks _ FALSE; pattern.word _ word; pattern.commentControl _ includeComments; pattern.checkType _ FALSE; pattern.type _ NIL; pattern.checkStyle _ FALSE; pattern.style _ NIL; TRUSTED {pattern.finder _ LOOPHOLE[TreeFind.CreateFromRope[target, literal, word, ~case, addBounds]]}; }; FindCC: PROC [cc: CommentControl] RETURNS [TreeFind.CommentControl] = INLINE { RETURN [SELECT cc FROM includeComments => includeComments, excludeComments => excludeComments, commentsOnly => commentsOnly, ENDCASE => ERROR] }; SelectionSearch: PUBLIC PROC [ pattern: Pattern, whichDir: SearchDir _ forwards, interrupt: REF BOOL _ NIL, startBoundaryNode, endBoundaryNode: Ref _ NIL, startBoundaryOffset: Offset _ 0, endBoundaryOffset: Offset _ LAST[Offset]] RETURNS [found: BOOL] = { pSel: TEditDocument.Selection = TEditSelection.pSel; Found: PROC [tSel: TEditDocument.Selection] = { tSel.viewer _ pSel.viewer; tSel.data _ pSel.data; TEditOps.RememberCurrentPosition[pSel.viewer]; TEditSelection.SetSelLooks[tSel]; TEditSelection.MakeSelection[new: tSel]; TEditInput.CloseEvent[]; TEditRefresh.ScrollToEndOfSel[tSel.viewer, FALSE] }; Locations: PROC RETURNS [start, end: TextNode.Location] = { start _ pSel.start.pos; end _ pSel.end.pos }; found _ DoSearch[pattern, whichDir, interrupt, Found, Locations, startBoundaryNode, endBoundaryNode, startBoundaryOffset, endBoundaryOffset] }; DocLoc: PROC [loc: Location] RETURNS [TextNode.Location] = INLINE { RETURN [[loc.node, loc.where]] }; MyLoc: PROC [loc: TextNode.Location] RETURNS [Location] = INLINE { RETURN [[loc.node, loc.where]] }; NodeSearch: PUBLIC PROC [ pattern: Pattern, whichDir: SearchDir _ forwards, startLoc, endLoc: Location, interrupt: REF BOOL _ NIL, startBoundaryNode, endBoundaryNode: Ref _ NIL, startBoundaryOffset: Offset _ 0, endBoundaryOffset: Offset _ LAST[Offset]] RETURNS [found: BOOL, start, end: Location] = { Found: PROC [tSel: TEditDocument.Selection] = { start _ MyLoc[tSel.start.pos]; end _ MyLoc[tSel.end.pos] }; Locations: PROC RETURNS [start, end: TextNode.Location] = { start _ DocLoc[startLoc]; end _ DocLoc[endLoc] }; found _ DoSearch[pattern, whichDir, interrupt, Found, Locations, startBoundaryNode, endBoundaryNode, startBoundaryOffset, endBoundaryOffset] }; DoSearch: PROC [ pattern: Pattern, whichDir: SearchDir _ forwards, interrupt: REF BOOL _ NIL, foundProc: PROC [tSel: TEditDocument.Selection], locationProc: PROC RETURNS [start, end: TextNode.Location], startBoundaryNode, endBoundaryNode: Ref _ NIL, startBoundaryOffset: Offset _ 0, endBoundaryOffset: Offset _ LAST[Offset]] RETURNS [found: BOOL] = { at, atEnd, offset: TextNode.Offset; first: TextNode.Ref; where: TextNode.RefTextNode; startLoc, endLoc: TextNode.Location; DoLookForPattern: PROC [root: TextEdit.Ref, tSel: TEditDocument.Selection] = { Forwards: PROC = TRUSTED { IF (offset _ endLoc.where+1) >= TextEdit.Size[TextNode.NarrowToTextNode[first _ endLoc.node]] THEN { first _ TextNode.StepForward[first]; offset _ 0 }; [found,where,at,atEnd,,] _ TreeFind.Try[finder: LOOPHOLE[pattern.finder], first: first, start: offset, last: endBoundaryNode, lastLen: endBoundaryOffset, interrupt: interrupt, looksExact: pattern.looksExact, checkType: pattern.checkType, type: NameSymbolTable.MakeNameFromRope[pattern.type], commentControl: FindCC[pattern.commentControl], checkStyle: pattern.checkStyle, style: NameSymbolTable.MakeNameFromRope[pattern.style], styleProc: NodeStyle.StyleNameForNode] }; Backwards: PROC = TRUSTED { IF (offset _ startLoc.where)=0 THEN { first _ TextNode.StepBackward[startLoc.node]; offset _ TreeFind.MaxLen } ELSE first _ startLoc.node; [found,where,at,atEnd,,] _ TreeFind.TryBackwards[finder: LOOPHOLE[pattern.finder], first: first, len: offset, last: startBoundaryNode, lastStart: startBoundaryOffset, interrupt: interrupt, looksExact: pattern.looksExact, checkType: pattern.checkType, type: NameSymbolTable.MakeNameFromRope[pattern.type], commentControl: FindCC[pattern.commentControl], checkStyle: pattern.checkStyle, style: NameSymbolTable.MakeNameFromRope[pattern.style], styleProc: NodeStyle.StyleNameForNode] }; [startLoc, endLoc] _ locationProc[]; IF interrupt#NIL THEN interrupt^ _ FALSE; SELECT whichDir FROM forwards => Forwards[]; backwards => Backwards[]; anywhere => { Forwards[]; IF found THEN whichDir _ forwards ELSE { whichDir _ backwards; Backwards[] }}; ENDCASE => ERROR; IF ~found OR where=NIL THEN RETURN; IF pattern.looks AND ~pattern.text AND ~pattern.word THEN [at,atEnd] _ Extend[whichDir=forwards, pattern.looksExact, RopeToLooks[pattern.searchLooks], where, at, atEnd]; tSel.start.pos _ [where,at]; tSel.end.pos _ [where,MAX[0,atEnd-1]]; tSel.granularity _ IF ~pattern.looks AND ~pattern.text THEN node ELSE IF pattern.word THEN word ELSE char; tSel.insertion _ IF TEditProfile.selectionCaret=before THEN before ELSE after; foundProc[tSel]; }; TEditInputOps.CallWithLocks[DoLookForPattern, read] }; Extend: PROC [forward, looksExact: BOOLEAN, searchLooks: TextLooks.Looks, where: TextNode.RefTextNode, at, atEnd: TextNode.Offset, last: TextNode.Ref _ NIL, lastLen: TextNode.Offset _ TextNode.MaxLen] RETURNS [newAt, newAtEnd: TextNode.Offset] = { runrdr: RunReader.Ref _ RunReader.GetRunReader[]; { -- for EXITS looks: TextLooks.Looks; runLen: TextNode.Offset; runs: TextLooks.Runs _ where.runs; IF forward THEN { -- extend toward end of node size: TextNode.Offset _ TextEdit.Size[where]; IF atEnd=size OR size=0 THEN GOTO Done; lastLen _ IF where=last THEN MIN[size,lastLen] ELSE size; RunReader.SetPosition[runrdr,runs,atEnd]; WHILE atEnd < lastLen DO IF runs=NIL THEN { runLen _ size-atEnd; looks _ TextLooks.noLooks } ELSE [runLen,looks] _ RunReader.Get[runrdr]; IF ~looksExact THEN looks _ TextLooksSupport.LooksAND[looks,searchLooks]; IF searchLooks # looks THEN EXIT; atEnd _ atEnd+runLen; ENDLOOP; RunReader.FreeRunReader[runrdr]; RETURN [at,MIN[atEnd,lastLen]] }; IF at=0 THEN GOTO Done; RunReader.SetPosition[runrdr,runs,at]; WHILE at > 0 DO IF runs=NIL THEN { runLen _ at; looks _ TextLooks.noLooks } ELSE [runLen,looks] _ RunReader.Backwards[runrdr]; IF ~looksExact THEN looks _ TextLooksSupport.LooksAND[looks,searchLooks]; IF searchLooks # looks THEN EXIT; at _ at-runLen; ENDLOOP; RunReader.FreeRunReader[runrdr]; RETURN [at,atEnd]; EXITS Done => { RunReader.FreeRunReader[runrdr]; RETURN }}}; SelectMatchingBrackets: PUBLIC PROC [before, after: CHAR] RETURNS [found: BOOL] = { found _ TEditInputOps.DoSelectMatchingBrackets[before, after] }; NextPlaceholder: PUBLIC PROC [dir: Dir _ forward, gotoend: BOOL, startBoundaryNode, endBoundaryNode: Ref _ NIL, startBoundaryOffset: Offset _ 0, endBoundaryOffset: Offset _ LAST[Offset]] RETURNS [found, wenttoend: BOOL] = { [found, wenttoend] _ TEditInputOps.DoFindPlaceholders[ dir=forward, gotoend, startBoundaryNode, endBoundaryNode, startBoundaryOffset, endBoundaryOffset] }; NextViewer: PUBLIC PROC [dir: Dir _ forward] RETURNS [found: BOOL] = { found _ TEditInputOps.DoNextViewer[dir=forward] }; SearchWhere: PROC [whichDir: SearchDir] RETURNS [TEditSelection.FindWhere] = INLINE { RETURN [SELECT whichDir FROM forwards => forwards, backwards => backwards, anywhere => anywhere, ENDCASE => ERROR] }; Position: PUBLIC PROC [viewer: Viewer] = { TEditInput.InterpretAtom[viewer, $Position] }; Normalize: PUBLIC PROC [viewer: Viewer] = { TEditInput.InterpretAtom[viewer, $NormalizeToStart] }; PrevPlace: PUBLIC PROC [viewer: Viewer] = { TEditInput.InterpretAtom[viewer, $PrevPlace] }; Reselect: PUBLIC PROC [viewer: Viewer] = { TEditInput.InterpretAtom[viewer, $Reselect] }; Save: PUBLIC PROC [viewer: Viewer] = { TEditInput.InterpretAtom[viewer, $Save] }; Load: PUBLIC PROC [viewer: Viewer, fileName: ROPE _ NIL, fileNameProcViewer: Viewer _ NIL] = { [] _ TEditDocumentPrivate.DoLoadFile[viewer, fileName, FALSE, fileNameProcViewer] }; Open: PUBLIC PROC [fileName: ROPE _ NIL, fileNameProcViewer: Viewer _ NIL] RETURNS [Viewer] = { RETURN [TEditDocumentPrivate.DoOpenFile[fileName, fileNameProcViewer]] }; CloseAndOpen: PUBLIC PROC [ viewer: Viewer, fileName: ROPE _ NIL, fileNameProcViewer: Viewer _ NIL] RETURNS [Viewer] = { RETURN [TEditDocumentPrivate.DoLoadFile[ viewer, fileName, TRUE, fileNameProcViewer]] }; LoadImpl: PUBLIC PROC [viewer: Viewer, fileName: ROPE _ NIL] = { [] _ TEditDocumentPrivate.DoLoadImplFile[viewer, fileName] }; OpenImpl: PUBLIC PROC [fileName: ROPE _ NIL] RETURNS [Viewer] = { RETURN [TEditDocumentPrivate.DoOpenImplFile[fileName]] }; CloseAndOpenImpl: PUBLIC PROC [viewer: Viewer, fileName: ROPE _ NIL] RETURNS [Viewer] = { RETURN [TEditDocumentPrivate.DoCloseAndOpenImplFile[viewer, fileName]] }; LoadPreviousFile: PUBLIC PROC [parent: Viewer] = { TEditInput.InterpretAtom[parent, $LoadPrevious] }; OpenPreviousFile: PUBLIC PROC [parent: Viewer] = { TEditInput.InterpretAtom[parent, $OpenPrevious] }; CloseAndOpenPreviousFile: PUBLIC PROC [parent: Viewer] = { TEditInput.InterpretAtom[parent, $CloseAndOpenPrevious] }; DefaultMenus: PUBLIC PROC [viewer: Viewer, paint: BOOL _ FALSE] = { TEditDocumentPrivate.DefaultMenus[viewer, paint] }; Store: PUBLIC PROC [viewer: Viewer, fileName: ROPE _ NIL] = { TEditDocumentPrivate.DoStoreFile[viewer, fileName] }; New: PUBLIC PROC RETURNS [Viewer] = { RETURN [TEditDocumentPrivate.DoNewViewer[]] }; Empty: PUBLIC PROC [viewer: Viewer] = { TEditDocumentPrivate.EmptyViewer[viewer] }; CloseAndNewViewer: PUBLIC PROC [viewer: Viewer] RETURNS [Viewer] = { RETURN [TEditDocumentPrivate.DoCloseAndNewViewer[viewer]] }; Reset: PUBLIC PROC [viewer: Viewer] = { TEditInput.InterpretAtom[viewer, $Reset] }; Jump: PUBLIC PROC [viewer: Viewer, loc: Location] = { DocLoc: PROC [loc: Location] RETURNS [TextNode.Location] = INLINE { RETURN [[loc.node, loc.where]] }; [] _ TEditScrolling.ScrollToPosition[viewer, DocLoc[loc]] }; FirstLevelOnly: PUBLIC PROC [viewer: Viewer] = { [] _ TEditInput.FirstLevelOnly[viewer] }; MoreLevels: PUBLIC PROC [viewer: Viewer] = { [] _ TEditInput.MoreLevels[viewer] }; FewerLevels: PUBLIC PROC [viewer: Viewer] = { [] _ TEditInput.FewerLevels[viewer] }; AllLevels: PUBLIC PROC [viewer: Viewer] = { [] _ TEditInput.AllLevels[viewer] }; END. θTiogaOps2Impl.Mesa written by Bill Paxton. June 1982 last written by Paxton. December 30, 1982 11:13 am Last Edited by: Plass, October 12, 1983 10:31 am Search Places menu commands Files and text viewers Levels menu commands Κ@˜Jšœ™Jšœ!™!Jšœ2™2J™0šΟ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šœ˜—Jšœ'˜.Jšœœ&˜0J˜Jšœœœ Οc˜3Jšœ œœ˜&Iprocšœœœ ˜Kšœ œœ ˜6J˜Jšž™˜šΟn œœœœ˜>šœœœ˜ Kšœ œ&˜6Kš˜—K˜K˜—šŸ œœœœ˜@KšŸœœœœœœœ˜GK˜$K˜K˜—šŸœœœ˜#Jšœ ž%˜2Jšœœœž˜0Jšœœœž˜3Jšœœœž˜5Jšœœœž˜3Jšœ œœž)˜@Jšœœœž˜)Jšœ œœž;˜RJšœœœž˜0Jšœœœž8˜MJšœ œœž+˜DJšœ˜Jšœ>˜>Jšœ'˜'Jšœœ ˜)šœœœž0˜JJšœ"˜"Jšœœœœ˜XJšœ%˜%šœ œ ˜šœ œ˜(Jšœ˜Jšœ5œ˜;Jšœ)˜)Jšœ˜—Jšœ˜—Jšœ œ˜Jšœ%˜%Jšœœ˜*—Jšœ˜Jšœ˜Jšœ˜Jšœ˜š œœ œœœ˜DJšœœ œœ˜;—Jšœ˜š œœœœ'œœ˜SJšœ.˜.—Jšœ˜šœœœ˜"JšœB˜F—š œœœ œž&˜Fšœœ˜JšœG˜G——J˜J˜—šŸœœœ˜"Jšœœž%˜3Jšœœœž˜)Jšœ œœž;˜RJšœœœž˜0Jšœ œœž+˜DJšœ˜Jšœœ ˜)Jšœœ˜Jšœœ˜Jšœ˜Jšœ)˜)Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜JšœœD˜fJ˜J˜—šŸœœœœ˜Nšœœ˜Kšœ#˜#Kšœ#˜#Kšœ˜Kšœœ˜K˜——šŸœœœ˜Kšœ=œœœ˜LKšœ*œ˜.Kšœ=œ ˜JJšœ œ˜J˜4šœœ$˜/Jšœ˜Jšœ˜Jšœ.˜.J˜!Jšœ(˜(Jšœ˜Jšœ+œ˜4—šœ œœ$˜;Jšœ-˜-—šœ@˜@Jšœ#˜#Jšœ*˜*—J˜—šŸœœœœ˜CKšœ˜!K˜—šŸœœœœ˜BKšœ˜!K˜—šŸ œœœ˜Kšœ1˜1Kšœ'œœœ˜6Kšœ*œ˜.Kšœ=œ ˜JJšœ œ˜/šœœ$˜/Jšœ;˜;—šœ œœ$˜;Jšœ1˜1—šœ@˜@Jšœ#˜#Jšœ*˜*—J˜—šŸœœ˜Kšœ=œœ˜LKšœ œ!˜0Kšœœœ!˜;Kšœ*œ˜.Kšœ=œ ˜JKšœ œ˜Jšœ#˜#Jšœ˜Jšœ˜J˜$J˜šŸœœ8˜NšŸœœœ˜šœ˜Jšœ>œ˜DJšœ2˜2—šœ˜šœœ.˜KJšœ2˜2Jšœ˜Jšœ˜Jšœ˜Jšœ5˜5Jšœ/˜/Jšœ˜Jšœ7˜7Jšœ)˜)———J˜šŸ œœœ˜šœœ˜%Jšœ-˜-Jšœ˜—Jšœ˜šœ˜šœœ˜7Jšœ˜Jšœ8˜8Jšœ˜Jšœ˜Jšœ˜Jšœ5˜5Jšœ/˜/Jšœ˜Jšœ7˜7Jšœ)˜)———J˜J˜$Jšœ œœœ˜)šœ ˜J˜J˜šœ ˜ Jšœ ˜ šœœœ˜(Jšœ%˜%——Jšœœ˜—Jš œœœœœ˜#šœœœ˜9šœ&˜&JšœH˜H——Jšœ˜Jšœœ ˜&šœ˜Jšœœœ˜-Jšœœœœ˜)—Jšœœ$œœ˜NJšœ˜Jšœ˜—J˜Jšœ6˜6J˜—šŸœ˜ šœœ˜