DIRECTORY Convert USING [Parse, Value], MessageWindow USING [Append, Blink], NodeProps USING [GetProp], Rope USING [Concat, ROPE, Size], TiogaNode USING [Location, Offset, Ref, RefTextNode], TiogaNodeOps USING [BranchChild, EndPos, LocWithin], TiogaDocument USING [Selection, SelectionId, TiogaDocumentData], TiogaInput USING [CloseEvent], TiogaLocks USING [LockDocAndTdd, LockRef, UnlockDocAndTdd], TiogaOps USING [GetSelContents, RememberCurrentPosition], TiogaProfile USING [selectionCaret], TiogaRefresh USING [ScrollToEndOfSel], TiogaSelection USING [Alloc, Copy, Free, FindWhere, LockSel, MakeSelection, sSel, fSel, pSel, SetSelLooks, UnlockSel], TextFind USING [MalformedPattern], TreeFind USING [CreateFromRope, Finder, Try, TryBackwards], UserTerminal USING [BlinkDisplay], ViewerClasses USING [Viewer]; TiogaSelectionOpsImpl: CEDAR PROGRAM IMPORTS Convert, MessageWindow, NodeProps, Rope, TextFind, TiogaNodeOps, TiogaInput, TiogaLocks, TiogaOps, TiogaProfile, TiogaRefresh, TiogaSelection, UserTerminal, TreeFind EXPORTS TiogaSelection = BEGIN OPEN TiogaDocument, TiogaSelection; CallWithSelAndDocAndTddLocks: PUBLIC PROC [ viewer: ViewerClasses.Viewer, id: SelectionId _ primary, proc: PROC [tdd: TiogaDocument.TiogaDocumentData, tSel: Selection]] = { Cleanup: PROC = { TiogaSelection.UnlockSel[id]; IF lockRef # NIL THEN TiogaLocks.UnlockDocAndTdd[tdd]; IF tSel # NIL THEN Free[tSel] }; tSel: Selection; lockRef: TiogaLocks.LockRef; tdd: TiogaDocument.TiogaDocumentData ~ NARROW[viewer.data]; IF tdd # NIL THEN {ENABLE UNWIND => Cleanup[]; TiogaSelection.LockSel[id, "CallWithSelAndDocAndTddLocks"]; lockRef _ TiogaLocks.LockDocAndTdd[tdd, "CallWithSelAndDocAndTddLocks", read]; IF lockRef#NIL THEN { sel: Selection = SELECT id FROM primary => pSel, secondary => sSel, feedback => fSel, ENDCASE => ERROR; tSel _ Alloc[]; TiogaSelection.Copy[source: sel, dest: tSel]; proc[tdd, tSel] }; Cleanup } }; Position: PUBLIC PROCEDURE [viewer: ViewerClasses.Viewer] = BEGIN count: INT _ -1; sel: Rope.ROPE _ TiogaOps.GetSelContents[]; IntFromRope: PROC [r: Rope.ROPE] RETURNS [i: INT] = BEGIN v: Convert.Value _ Convert.Parse[[rope[r]]].value; RETURN[NARROW[v, Convert.Value[signed]].signed]; END; count _ IntFromRope[sel ! ANY => CONTINUE]; IF count>=0 THEN BEGIN DoPosition: PROC [tdd: TiogaDocument.TiogaDocumentData, tSel: Selection] = { tiogaFile: BOOL _ (NodeProps.GetProp[tdd.text, $FromTiogaFile] = $Yes); IF ~tiogaFile THEN count _ count+1; -- hack to compensate for leading CR tSel.start.pos _ tSel.end.pos _ TiogaNodeOps.LocWithin[tdd.text, count, 1, TRUE]; -- skip comment nodes tSel.end.pos.where _ MIN[tSel.end.pos.where+3, TiogaNodeOps.EndPos[tSel.end.pos.node]]; tSel.start.pos.where _ MIN[tSel.end.pos.where, tSel.start.pos.where]; IF tSel.start.pos.where=tSel.end.pos.where AND tSel.start.pos.where > 0 THEN tSel.start.pos.where _ tSel.start.pos.where-1; tSel.granularity _ char; tSel.viewer _ viewer; tSel.data _ tdd; tSel.pendingDelete _ FALSE; tSel.insertion _ IF TiogaProfile.selectionCaret=before THEN before ELSE after; TiogaOps.RememberCurrentPosition[viewer]; TiogaSelection.SetSelLooks[tSel]; TiogaSelection.MakeSelection[new: tSel, selection: feedback]; TiogaRefresh.ScrollToEndOfSel[viewer, FALSE, feedback]; -- sets bit to cause scroll after refresh }; CallWithSelAndDocAndTddLocks[viewer, feedback, DoPosition]; END ELSE { OPEN MessageWindow; Append["Select character count for position.", TRUE]; Blink[] }; END; Find: PUBLIC PROC [viewer: ViewerClasses.Viewer, findWhere: FindWhere _ anywhere, def, word: BOOLEAN _ FALSE, id: SelectionId _ primary, case: BOOL _ TRUE -- case => case of characters is significant -- ] = BEGIN rope: Rope.ROPE = TiogaOps.GetSelContents[]; IF Rope.Size[rope]=0 THEN { OPEN MessageWindow; Append["Select target for search.", TRUE]; Blink[] }; FindRope[viewer, rope, findWhere, def, word, id, case]; END; FindRope: PUBLIC PROC [ viewer: ViewerClasses.Viewer, rope: Rope.ROPE, findWhere: FindWhere _ anywhere, def, word: BOOLEAN _ FALSE, id: SelectionId _ primary, case: BOOL _ TRUE -- case => case of characters is significant -- ] = BEGIN IF ~DoFind[viewer, rope, findWhere, def, word, id, case] THEN { MessageWindow.Append["Not found.", TRUE]; TRUSTED {UserTerminal.BlinkDisplay[]}; RETURN } END; DoFind: PUBLIC PROC [ viewer: ViewerClasses.Viewer, rope: Rope.ROPE, findWhere: FindWhere _ anywhere, def, word: BOOLEAN _ FALSE, id: SelectionId _ primary, case: BOOL _ TRUE -- case => case of characters is significant -- ] RETURNS [found: BOOL] = BEGIN finder: TreeFind.Finder; where: TiogaNode.RefTextNode; first: TiogaNode.Ref; start, at, atEnd: TiogaNode.Offset; DoFindIt: PROC [tdd: TiogaDocument.TiogaDocumentData, tSel: Selection] = { visible: BOOL _ SelectionVisibleInViewer[]; Forward: PROC = { IF visible THEN { first _ tSel.end.pos.node; start _ tSel.end.pos.where+1 } ELSE { first _ tdd.lineTable.lines[0].pos.node; start _ tdd.lineTable.lines[0].pos.where }; [found,where,at,atEnd,,] _ TreeFind.Try[finder,first,start] }; Backward: PROC = { IF visible THEN { first _ tSel.start.pos.node; start _ tSel.start.pos.where } ELSE { first _ tdd.lineTable.lines[0].pos.node; start _ tdd.lineTable.lines[0].pos.where }; [found,where,at,atEnd,,] _ TreeFind.TryBackwards[finder,first,start] }; FromStart: PROC = { first _ TiogaNodeOps.BranchChild[tdd.text]; start _ 0; [found,where,at,atEnd,,] _ TreeFind.Try[finder,first,start] }; SelectionVisibleInViewer: PROC RETURNS [BOOLEAN] = { RETURN [tSel.viewer=viewer AND tSel.end.line IN [0..tdd.lineTable.lastLine]] }; SELECT findWhere FROM forwards => Forward[]; backwards => Backward[]; anywhere => { Forward[]; IF ~found THEN FromStart[] }; ENDCASE => ERROR; IF ~found THEN RETURN; IF def THEN atEnd _ atEnd-1; -- skip the trailing : tSel.start.pos _ [where,at]; tSel.end.pos _ [where,MAX[0,atEnd-1]]; tSel.granularity _ IF word THEN word ELSE char; tSel.viewer _ viewer; tSel.data _ tdd; tSel.insertion _ IF TiogaProfile.selectionCaret=before THEN before ELSE after; tSel.insertion _ after; tSel.pendingDelete _ FALSE; TiogaOps.RememberCurrentPosition[viewer]; TiogaSelection.SetSelLooks[tSel]; TiogaSelection.MakeSelection[new: tSel, selection: id]; TiogaInput.CloseEvent[]; TiogaRefresh.ScrollToEndOfSel[viewer, FALSE, id]; }; found _ FALSE; IF Rope.Size[rope] = 0 THEN RETURN; IF def THEN rope _ Rope.Concat[rope,":"]; finder _ TreeFind.CreateFromRope[pattern: rope, literal: TRUE, ignoreCase: ~case, word: word ! TextFind.MalformedPattern => { MessageWindow.Append["Pattern too long",TRUE]; MessageWindow.Blink[]; GOTO Bad }]; CallWithSelAndDocAndTddLocks[viewer, id, DoFindIt]; EXITS Bad => NULL; END; END. 2-- TiogaSelectionOpsImpl.mesa Edited by Paxton on June 17, 1983 1:46 pm Last Edited by: Maxwell, January 6, 1983 11:38 am Last Edited by: Plass, April 15, 1983 3:29 pm -- we'd like to use Convert.IntFromRope here, but the resultant -- fatal compiler errors in pass 5 wasted one afternoon already... Κ?˜JšΟcG™GJ™1J™-šΟk ˜ Jšœžœ˜Jšœžœ˜$Jšœ žœ ˜Jšœžœ žœ˜ Jšœ žœ&˜5Jšœ žœ"˜4Jšœžœ-˜@Jšœ žœ˜Jšœ žœ+˜;Jšœ žœ+˜9Jšœ žœ˜$Jšœ žœ˜&Jšœžœb˜vJšœ žœ˜"Jšœ žœ-˜;Jšœ žœ˜"Jšœžœ ˜J˜—Jšœž ˜$J˜Jšžœ¦˜­Jšžœž˜J˜Jšžœ˜#J˜šΟnœž œ˜+Jšœ˜J˜Jšœžœ=˜GšŸœžœ˜Jšœ˜Jšžœ žœžœ!˜6Jšžœžœžœ˜ —Jšœ˜Jšœ˜Jšœ'žœ˜;š žœžœžœžœžœ˜.Jšœ;˜;IcodešœN˜Nšžœ žœžœ˜šœžœž˜Jšœ6žœžœ˜G—Jšœ˜Jšœ-˜-Kšœ˜—Jšœ˜Jšœ˜—Jšœ˜J˜—šŸœžœž œ"ž˜AJšœžœ˜Jšœ žœ˜+J˜Jš?™?JšB™Bš Ÿ œžœ žœžœžœž˜9J˜2Jšžœžœ#˜0Jšžœ˜J˜—Jšœžœžœ˜+J˜šžœ žœž˜šŸ œžœ<˜LJšœ žœ8˜GJšžœ žœ$˜H˜Jšœ+žœ˜G—Jšœžœ?˜WJšœžœ+˜Ešžœ)žœž˜LJšœ.˜.—Jšœ˜J˜J˜Jšœžœ˜Jšœžœ$žœžœ˜NJ˜)Jšœ!˜!Jšœ=˜=šœ&žœ ˜7Jš)˜)—J˜—Jšœ;˜;Jšž˜J˜—šžœžœ˜Jšœ/žœ˜5J˜ J˜—Jšžœ˜J˜—šŸœžœžœ˜0Jšœ ˜ Jšœ žœž˜J˜Jšœžœžœ,œž˜KJšœ žœ˜,šžœžœžœ˜/Jšœ$žœ˜*J˜ —Jšœ7˜7Jšžœ˜J˜—šŸœžœžœ˜J˜Jšœ žœ˜Jšœ ˜ Jšœ žœž˜J˜Jšœžœžœ,œž˜Kšžœ7žœ˜?Jšœ#žœ˜)Jšžœ˜&Jšžœžœ˜ J˜——šŸœžœžœ˜J˜Jšœ žœ˜Jšœ ˜ Jšœ žœž˜J˜Jšœžœžœ,œ˜CJšžœ žœž˜J˜J˜J˜J˜J˜#J˜šœ žœ<˜JKšœ žœ˜+J˜šŸœžœ˜šžœ žœ˜Jšœ˜Jšœ˜—šžœ˜J˜(J˜+—Jšœ>˜>—J˜šŸœžœ˜šžœ žœ˜Jšœ˜Jšœ˜—šžœ˜J˜(J˜+—JšœG˜GJ˜—šŸ œžœ˜J˜+J˜ Jšœ>˜>—J˜šŸœžœžœžœ˜4Jšžœžœžœ ˜O—J˜šžœ ž˜Jšœ˜Jšœ˜Jšœžœžœ˜6Jšžœžœ˜—Jšžœžœžœ˜Jšžœžœ˜3J˜Jšœžœ ˜&Jšœžœžœžœ˜/J˜J˜Jšœžœ$žœžœ˜NJ˜Jšœžœ˜J˜)Jšœ!˜!Jšœ7˜7J˜Jšœ&žœ˜1J˜—J˜Jšœžœ˜Jšžœžœžœ˜#Jšžœžœ˜)šœ9žœ!˜^J˜Jšœ(žœ˜.J˜Jšžœ˜ —J˜Jšœ3˜3J˜Jšžœžœ˜J˜Jšžœ˜J˜—Jšžœ˜J˜—…—"q