DIRECTORY Convert USING [Error, IntFromRope], MessageWindow USING [Append, Blink], NodeProps USING [GetProp], Rope USING [Concat, ROPE, Size], TextEdit USING [RefTextNode], TextNode USING [EndPos, FirstChild, Location, LocWithin, Offset, Ref, RefTextNode], TEditDocument USING [Selection, SelectionId, TEditDocumentData], TEditInput USING [CloseEvent], TEditLocks USING [LockDocAndTdd, LockRef, UnlockDocAndTdd], TEditOps USING [GetSelContents, RememberCurrentPosition], TEditProfile USING [selectionCaret], TEditRefresh USING [ScrollToEndOfSel], TEditSelection USING [Alloc, Copy, Free, FindWhere, LockSel, MakeSelection, sSel, fSel, pSel, SetSelLooks, UnlockSel], Terminal, TextFind USING [MalformedPattern], TreeFind USING [CreateFromRope, Finder, Try, TryBackwards], ViewerClasses USING [Viewer]; TEditSelectionOpsImpl: CEDAR PROGRAM IMPORTS Convert, MessageWindow, NodeProps, Rope, TEditInput, TEditLocks, TEditOps, TEditProfile, TEditRefresh, TEditSelection, Terminal, TextFind, TextNode, TreeFind EXPORTS TEditSelection = BEGIN OPEN TEditDocument, TEditSelection; CallWithSelAndDocAndTddLocks: PUBLIC PROC [ viewer: ViewerClasses.Viewer, id: SelectionId _ primary, proc: PROC [tdd: TEditDocument.TEditDocumentData, tSel: Selection]] = { Cleanup: PROC = { TEditSelection.UnlockSel[id]; IF lockRef # NIL THEN TEditLocks.UnlockDocAndTdd[tdd]; IF tSel # NIL THEN Free[tSel] }; tSel: Selection; lockRef: TEditLocks.LockRef; tdd: TEditDocument.TEditDocumentData ~ NARROW[viewer.data]; IF tdd # NIL THEN {ENABLE UNWIND => Cleanup[]; TEditSelection.LockSel[id, "CallWithSelAndDocAndTddLocks"]; lockRef _ TEditLocks.LockDocAndTdd[tdd, "CallWithSelAndDocAndTddLocks", read]; IF lockRef#NIL THEN { sel: Selection = SELECT id FROM primary => pSel, secondary => sSel, feedback => fSel, ENDCASE => ERROR; tSel _ Alloc[]; TEditSelection.Copy[source: sel, dest: tSel]; proc[tdd, tSel] }; Cleanup } }; Position: PUBLIC PROCEDURE [viewer: ViewerClasses.Viewer] = BEGIN count: INT _ -1; sel: Rope.ROPE _ TEditOps.GetSelContents[]; count _ Convert.IntFromRope[sel ! Convert.Error => CONTINUE]; IF count>=0 THEN BEGIN DoPosition: PROC [tdd: TEditDocument.TEditDocumentData, 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 _ TextNode.LocWithin[tdd.text, count, 1, TRUE]; -- skip comment nodes tSel.end.pos.where _ MIN[tSel.end.pos.where+3, TextNode.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 TEditProfile.selectionCaret=before THEN before ELSE after; TEditOps.RememberCurrentPosition[viewer]; TEditSelection.SetSelLooks[tSel]; TEditSelection.MakeSelection[new: tSel, selection: feedback]; TEditRefresh.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 = TEditOps.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]; Terminal.BlinkBWDisplay[Terminal.Current[]]; 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: TextNode.RefTextNode; first: TextNode.Ref; start, at, atEnd: TextNode.Offset; DoFindIt: PROC [tdd: TEditDocument.TEditDocumentData, 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 _ TextNode.FirstChild[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 TEditProfile.selectionCaret=before THEN before ELSE after; tSel.insertion _ after; tSel.pendingDelete _ FALSE; TEditOps.RememberCurrentPosition[viewer]; TEditSelection.SetSelLooks[tSel]; TEditSelection.MakeSelection[new: tSel, selection: id]; TEditInput.CloseEvent[]; TEditRefresh.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. ¬TEditSelectionOpsImpl.mesa Paxton on June 6, 1983 1:47 pm Maxwell, January 6, 1983 11:38 am Plass, April 15, 1983 3:29 pm Russ Atkinson, September 26, 1983 4:09 pm Κ˜šΟc™Jš™J™!J™J™)J™—šΟk ˜ Jšœžœ˜#Jšœžœ˜$Jšœ žœ ˜Jšœžœ žœ˜ Jšœ žœ˜Jšœ žœE˜SJšœžœ-˜@Jšœ žœ˜Jšœ žœ+˜;Jšœ žœ+˜9Jšœ žœ˜$Jšœ žœ˜&šœž˜Jšœa˜a—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šœ3žœ˜=J˜šžœ žœž˜šŸ œžœ<˜LJšœ žœ8˜GJšžœ žœ$˜H˜Jšœ'žœ˜C—Jšœžœ;˜SJšœžœ+˜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˜—…—N ϊ