DIRECTORY EditSpan, EditSpanSupport, IO, CedarScanner, MessageWindow, NodeAddrs, NodeProps, Rope, RopeEdit, RopeReader, TEditDocument, TEditInput, TEditInputOps, TEditLocks, TEditMesaOps, TEditSelection, TextEdit, TextLooks, TextNode, UndoEvent; TEditMesaOpsImpl: CEDAR PROGRAM IMPORTS EditSpan, EditSpanSupport, IO, CedarScanner, MessageWindow, NodeAddrs, NodeProps, Rope, RopeEdit, RopeReader, TEditInput, TEditInputOps, TEditLocks, TEditSelection, TextEdit, TextLooks, TextNode EXPORTS TEditMesaOps = BEGIN SetSpanMesaLooks: PUBLIC PROC [span: TextNode.Span, event: UndoEvent.Ref] RETURNS [procs, comments, keywords: INT] = { root: TextNode.Ref = TextNode.Root[span.start.node]; rdr: RopeReader.Ref _ RopeReader.Create[]; skipComments: BOOL = span.start.node # span.end.node; SetMesaLooks: PROC [node: TextNode.RefTextNode, start, len: TextNode.Offset] RETURNS [stop: BOOLEAN] = { p, c, k: INT; IF node.comment AND skipComments THEN { p _ c _ k _ 0; stop _ FALSE } ELSE [stop,p,c,k] _ DoIt[node, start, len, rdr, event]; procs _ procs+p; comments _ comments+c; keywords _ keywords+k }; procs _ comments _ keywords _ 0; [] _ TEditLocks.Lock[root, "SetSpanMesaLooks"]; EditSpanSupport.Apply[span,SetMesaLooks]; TEditLocks.Unlock[root] }; DoIt: PROC [node: TextNode.RefTextNode, start, len: TextNode.Offset, rdr: RopeReader.Ref, event: UndoEvent.Ref] RETURNS [stop: BOOLEAN, procs, comments, keywords: INT] = { root: TextNode.Ref = TextNode.Root[node]; pStart, pLen, size, i, first, end: TextNode.Offset _ 0; lastChar: CHAR; GetChar: PROC [data: REF, index: TextNode.Offset] RETURNS [char: CHAR] = { OPEN RopeReader; IF index >= end THEN { done _ TRUE; RETURN [0C] }; SetIndex[rdr,index]; char _ Get[rdr ! ReadOffEnd => { done _ TRUE; char _ 0C; CONTINUE }] }; CheckID: PROC [n: TextNode.RefTextNode, start, len: TextNode.Offset] RETURNS [alpha, allcaps: BOOLEAN] = INLINE { alpha _ allcaps _ TRUE; RopeReader.SetPosition[rdr,n.rope,start]; UNTIL (len _ len-1)<0 DO IF (lastChar _ RopeReader.Get[rdr]) NOT IN ['A..'Z] THEN allcaps _ FALSE; IF ~RopeEdit.AlphaNumericChar[lastChar] THEN { alpha _ FALSE; EXIT }; ENDLOOP }; IsProc: PROC [n: TextNode.RefTextNode, start, len: TextNode.Offset] RETURNS [BOOLEAN] = INLINE { IF ~(SELECT len FROM 4 => lastChar = 'C, 9 => lastChar = 'E, ENDCASE => FALSE) THEN RETURN [FALSE]; -- quick test eliminates most RopeReader.SetPosition[rdr,n.rope,start]; IF RopeReader.Get[rdr] # 'P THEN RETURN [FALSE]; IF RopeReader.Get[rdr] # 'R THEN RETURN [FALSE]; IF RopeReader.Get[rdr] # 'O THEN RETURN [FALSE]; IF RopeReader.Get[rdr] # 'C THEN RETURN [FALSE]; IF len = 4 THEN RETURN [TRUE]; IF len # 9 THEN RETURN [FALSE]; IF RopeReader.Get[rdr] # 'E THEN RETURN [FALSE]; IF RopeReader.Get[rdr] # 'D THEN RETURN [FALSE]; IF RopeReader.Get[rdr] # 'U THEN RETURN [FALSE]; IF RopeReader.Get[rdr] # 'R THEN RETURN [FALSE]; IF RopeReader.Get[rdr] # 'E THEN RETURN [FALSE]; RETURN [TRUE] }; done: BOOLEAN _ FALSE; allComments: BOOLEAN _ TRUE; lastLoc: TextNode.Location; nameLooks: TextLooks.Looks _ TextLooks.noLooks; mesaLooks: TextLooks.Looks _ TextLooks.noLooks; size _ RopeEdit.Size[node.rope]; start _ MIN[start, size]; len _ MIN[len, size-start]; end _ start+len; i _ first _ start; stop _ FALSE; procs _ comments _ keywords _ 0; RopeReader.SetPosition[rdr,node.rope,start]; lastLoc _ [node,start]; mesaLooks['k] _ mesaLooks['c] _ mesaLooks['n] _ TRUE; nameLooks['n] _ TRUE; UNTIL done DO add, alpha, allcaps, proc: BOOLEAN _ FALSE; addLooks, remLooks: TextLooks.Looks _ TextLooks.noLooks; token: CedarScanner.Token; TRUSTED {token _ CedarScanner.GetToken[[GetChar, rdr],i]}; i _ token.next; start _ token.start; len _ i-start; remLooks _ mesaLooks; SELECT token.kind FROM tokenCOMMENT => { IF ~TextLooks.FetchLooks[node.runs, start]['c] THEN { add _ TRUE; addLooks['c] _ TRUE; remLooks['c] _ FALSE } ELSE lastLoc.where _ start+len; -- don't change comment looks comments _ comments+1 }; tokenID => { allComments _ FALSE; [alpha, allcaps] _ CheckID[node,start,len]; IF allcaps THEN { proc _ IsProc[node,start,len]; add _ TRUE; addLooks['k] _ TRUE; remLooks['k] _ FALSE; keywords _ keywords+1 } ELSE IF alpha THEN { -- save since may be a proc name pStart _ start; pLen _ len }}; ENDCASE => allComments _ FALSE; IF add THEN { IF lastLoc.where < start THEN EditSpan.RemoveLooks[root,[lastLoc,[node,start-1]],mesaLooks,event]; lastLoc.where _ start+len; EditSpan.ChangeLooks[root,[[node,start],[node,start+len-1]],remLooks,addLooks,event]; add _ FALSE; addLooks _ TextLooks.noLooks; remLooks _ mesaLooks }; IF proc THEN { ReallyIsProc: PROC RETURNS [BOOL] = { rope: Rope.ROPE = node.rope; IF ~Rope.Fetch[rope,pStart] IN ['A..'Z] THEN RETURN[FALSE]; IF pStart+pLen >= Rope.Size[rope] THEN RETURN[FALSE]; IF Rope.Fetch[rope,pStart+pLen] # ': THEN RETURN[FALSE]; RETURN [TRUE] }; proc _ FALSE; IF pLen > 0 AND ReallyIsProc[] THEN { procs _ procs+1; EditSpan.AddLooks[root,[[node,pStart],[node,pStart+pLen-1]],nameLooks,event] }; pLen _ 0 }; ENDLOOP; IF lastLoc.where < end THEN EditSpan.RemoveLooks[root,[lastLoc,[node,end-1]],mesaLooks,event]; IF first=0 AND done THEN { -- doing entire node; check Comment property isComment: BOOL _ allComments AND comments > 0; IF isComment AND NOT node.comment THEN { -- change it NextCharIsBlank: PROC RETURNS [blank: BOOL] = { blank _ RopeEdit.BlankChar[RopeReader.Peek[rdr ! RopeReader.ReadOffEnd => { blank _ FALSE; CONTINUE }]] }; commentLooks: TextLooks.Looks _ TextLooks.noLooks; commentLooks['c] _ TRUE; RopeReader.SetPosition[rdr,node.rope,0]; WHILE RopeEdit.BlankChar[RopeReader.Get[rdr]] DO --skip blanks-- ENDLOOP; IF RopeReader.PeekBackwards[rdr] # '- THEN ERROR; IF RopeReader.Get[rdr] # '- THEN ERROR; WHILE NextCharIsBlank[] DO --skip blanks [] _ RopeReader.Get[rdr]; ENDLOOP; TextEdit.DeleteText[root, node, 0, RopeReader.GetIndex[rdr], event]; EditSpan.RemoveLooks[root,[[node,0],[node,TextNode.MaxLen]],commentLooks,event]; TextEdit.PutProp[node, "Comment", NodeProps.true, event] }}; }; SetMesaLooksOp: PUBLIC TEditInput.CommandProc = { procs, comments, keywords: INT; DoSet: PROC [root: TextEdit.Ref, tSel: TEditDocument.Selection] = { span: TextNode.Span _ [tSel.start.pos, tSel.end.pos]; selStart, selEnd: TextNode.Ref; firstText, lastText: TextNode.RefTextNode; IF (firstText _ TextNode.NarrowToTextNode[selStart _ tSel.start.pos.node]) # NIL THEN NodeAddrs.PutTextAddr[firstText,$Start,tSel.start.pos.where]; IF (lastText _ TextNode.NarrowToTextNode[selEnd _ tSel.end.pos.node]) # NIL THEN NodeAddrs.PutTextAddr[lastText,$End,tSel.end.pos.where+1]; IF tSel.granularity=point OR (tSel.granularity=char AND tSel.start.pos=tSel.end.pos) THEN { span.start.where _ 0; span.end.where _ TextNode.EndPos[span.end.node] }; [procs, comments, keywords] _ SetSpanMesaLooks[span, TEditInput.currentEvent]; 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 firstText#NIL THEN NodeAddrs.RemTextAddr[firstText,$Start]; IF lastText#NIL THEN NodeAddrs.RemTextAddr[lastText,$End]; TEditSelection.MakeSelection[new: tSel]; TEditSelection.SetSelLooks[TEditSelection.pSel] }; TEditInputOps.CallWithLocks[DoSet]; { OPEN IO; h: Handle _ CreateOutputStreamToRope[]; Put[h, int[keywords], IF keywords=1 THEN rope[" keyword, "] ELSE rope[" keywords, "]]; Put[h, int[comments], IF comments=1 THEN rope[" comment, "] ELSE rope[" comments, "]]; Put[h, int[procs], IF procs=1 THEN rope[" procedure name."] ELSE rope[" procedure names."]]; MessageWindow.Append[GetOutputStreamRope[h],TRUE] }}; TEditInput.Register[$SetMesaLooks, SetMesaLooksOp]; END... j-- TEditMesaOpsImpl.mesa Edited by Paxton on November 10, 1982 7:33 am Last Edited by: Maxwell, January 14, 1983 9:41 am -- must start with a cap alpha -- must be followed immediately by a colon -- scan selection looking for Mesa keywords and comments -- set the keywords look k -- set the comments look c -- set procedure names look n do the entire node Ê ˜JšÏcF™FJ™1šÏ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˜š Ïnœžœžœ-žœžœ˜vJ˜4J˜*Jšœžœ#˜5šŸ œžœ:˜LJšžœžœ˜Jšœ žœ˜ Jšžœžœžœžœ˜EJšžœ3˜7J˜@—J˜ J˜/J˜)J˜J˜—J˜J˜šŸœžœe˜oJšžœžœžœ˜;J˜)J˜7Jšœ žœ˜š Ÿœžœžœžœžœ˜KJšžœ ˜Jšžœžœ žœžœ˜2J˜Jšœ(žœ žœ˜G—šŸœžœ7˜DJšžœžœžœ˜,Jšœžœ˜J˜)šžœž˜Jš žœ"žœžœ žœ žœ˜IJšžœ&žœ žœžœ˜EJšžœ˜ ——š Ÿœžœ8žœžœžœ˜`šžœžœž˜J˜J˜Jš žœžœžœžœžœ˜D—J˜)Jšžœžœžœžœ˜0Jšžœžœžœžœ˜0Jšžœžœžœžœ˜0Jšžœžœžœžœ˜0Jšžœ žœžœžœ˜Jšžœ žœžœžœ˜Jšžœžœžœžœ˜0Jšžœžœžœžœ˜0Jšžœžœžœžœ˜0Jšžœžœžœžœ˜0Jšžœžœžœžœ˜0Jšžœžœ˜—Jšœžœžœ˜Jšœ žœžœ˜J˜J˜/J˜/J˜J˜ Jšœžœ˜Jšœžœ˜J˜J˜Jšœžœ˜ J˜ J˜,J˜Jšœ0žœ˜5Jšœžœ˜šžœž˜ Jšœžœžœ˜+J˜8Jšœ˜Jšžœ3˜:J˜J˜J˜J˜šžœ ž˜˜šžœ-žœ˜5Jšœžœžœžœ˜7—Jšžœ˜=J˜—˜ Jšœžœ˜J˜+šžœ žœ˜J˜Jšœžœžœžœ˜6J˜—šžœžœžœ ˜5J˜——Jšžœžœ˜—šžœžœ˜ šžœž˜J˜D—J˜J˜UJšœžœ˜ J˜J˜—šžœžœ˜šŸ œžœžœžœ˜%Jšœ žœ ˜Jš™Jš žœžœ žœžœžœ˜;Jš*™*Jšžœ žœžœžœ˜5Jšžœ#žœžœžœ˜8Jšžœžœ˜—Jšœžœ˜ šžœ žœžœ˜%J˜JšœO˜O—J˜ —Jšžœ˜—šžœž˜J˜B—šžœ žœžœ,˜GJšœ žœžœ˜/š žœ žœžœžœ ˜5šŸœžœžœ žœ˜/šœ0˜0Jšœ#žœžœ˜9——J˜2Jšœžœ˜Jšœ(˜(Jšžœ<žœ˜IJšžœ$žœžœ˜1Jšžœžœžœ˜'šžœž˜(Jšœžœ˜"—J˜DJšœP˜PJ˜<——J˜J˜—šœžœ˜1Jš8™8Jš™Jš™Jš™Jšœžœ˜šŸœžœ8˜CJšœ5˜5J˜J˜*šžœKžœž˜UJ˜=—šžœFžœž˜PJ˜:—šžœžœžœžœ˜[Jšœ™Jšœ˜Jšœ2˜2—JšœN˜N˜Jšžœ žœžœ˜)Jšžœ3˜7—˜Jšžœ žœžœ˜(Jšžœžœ5˜=—Jšžœ žœžœ)˜>Jšžœ žœžœ&˜:Jšœ(˜(Jšœ2˜2J˜—Jšœ#˜#J˜Jšœžœžœ˜ J˜'Jšœžœ žœžœ˜WJšœžœ žœžœ˜VJšœžœ žœžœ˜\Jšœ,žœ˜6J˜—J˜3J˜Jšžœ˜J˜—…—2'©