DIRECTORY EditSpan USING [AddLooks, ChangeLooks, noLooks, RemoveLooks], EditSpanSupport USING [Apply], IO USING [GetCedarToken, GetIndex, RIS, SetIndex, STREAM, TokenKind], NodeAddrs USING [GetTextAddr, PutTextAddr, RemTextAddr], RefText USING [New], Rope USING [Equal, FromRefText, ROPE, Size, Substr], RopeReader USING [Create, Ref], RuntimeError USING [BoundsFault], TEditDocument USING [Selection], TEditInput USING [CommandProc, currentEvent, Register], TEditInputOps USING [CallWithLocks], TEditLocks USING [Lock, Unlock], TEditMesaOps USING [], TEditSelection USING [MakeSelection, pSel, SetSelLooks], TextEdit USING [Size], TextLooks USING [Looks, noLooks], TextNode USING [EndPos, Location, NodeItself, Offset, Ref, RefTextNode, Root, Span], UndoEvent USING [Ref]; CasabaFormattingImpl: CEDAR PROGRAM IMPORTS EditSpan, EditSpanSupport, IO, NodeAddrs, RefText, Rope, RopeReader, RuntimeError, TEditInput, TEditInputOps, TEditLocks, TEditSelection, TextEdit, TextNode = BEGIN ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; Keywords: LIST OF ROPE = LIST["AbstractProduction", "AbstractType", "BaseFunction", "BaseType", "Begin", "Build", "Builds", "CedarEnumType", "CedarFunction", "CedarType", "Control", "DamagedReps", "else", "End", "EnumeratedBaseType", "for", "From", "GenericToken", "if", "in", "Include", "let", "Module", "NonTerminal", "Returns", "SharedReps", "SimpleTokens", "SourceLength", "SourcePosition", "then", "TreeRecursiveFunction", "where"]; Keyword: PROC [r: ROPE] RETURNS[BOOLEAN] = BEGIN k: LIST OF ROPE _ Keywords; WHILE k # NIL DO IF Rope.Equal[k.first, r] THEN RETURN[TRUE]; k _ k.rest; ENDLOOP; RETURN[FALSE]; END; SetSpanCasabaLooks: PROC [span: TextNode.Span, event: UndoEvent.Ref] = { root: TextNode.Ref = TextNode.Root[span.start.node]; rdr: RopeReader.Ref _ RopeReader.Create[]; SetMesaLooks: PROC [node: TextNode.RefTextNode, start, len: TextNode.Offset] RETURNS [stop: BOOL] = { p, c, k: INT _ 0; IF node.comment AND start = 0 AND len = TextEdit.Size[node] THEN { -- skip the entire comment node -- stop _ FALSE } ELSE stop _ DoIt[node, start, len, rdr, event]; }; [] _ TEditLocks.Lock[root, "SetSpanMesaLooks"]; EditSpanSupport.Apply[span, SetMesaLooks]; TEditLocks.Unlock[root]; }; namifyTypes: BOOL _ FALSE; DoIt: PROC [node: TextNode.RefTextNode, start, len: TextNode.Offset, rdr: RopeReader.Ref, event: UndoEvent.Ref] RETURNS [stop: BOOL _ FALSE] = { root: TextNode.Ref = TextNode.Root[node]; pStart, pLen: TextNode.Offset _ 0; lastChar: CHAR _ '\000; token: REF TEXT _ RefText.New[40]; tokenKind: IO.TokenKind _ tokenERROR; allComments: BOOL _ TRUE; nameLooks: TextLooks.Looks _ TextLooks.noLooks; casabaLooks: TextLooks.Looks _ TextLooks.noLooks; stream: STREAM _ NIL; size: INT ~ Rope.Size[node.rope]; first: INT ~ MIN[start, size]; length: INT ~ MIN[len, size-start]; end: INT ~ start+length; state: {null, name, nameColon} _ null; stream _ IO.RIS[node.rope.Substr[0, end]]; IO.SetIndex[stream, first]; casabaLooks['i] _ casabaLooks['z] _ casabaLooks['n] _ TRUE; nameLooks['n] _ TRUE; IF end > first THEN EditSpan.RemoveLooks[root, [[node, first], [node, end-1]], casabaLooks, event]; UNTIL tokenKind = tokenEOF DO add, alpha, keyword: BOOL _ FALSE; addLooks, remLooks: TextLooks.Looks _ TextLooks.noLooks; tokStart, tokLen: INT _ 0; [tokenKind, token] _ IO.GetCedarToken[stream, token, FALSE ! RuntimeError.BoundsFault => { tokenKind _ tokenERROR; token.length _ 0; CONTINUE } ]; tokLen _ token.length; tokStart _ IO.GetIndex[stream]-tokLen; remLooks _ casabaLooks; SELECT tokenKind FROM tokenID => { IF Keyword[Rope.FromRefText[token]] THEN { add _ TRUE; addLooks['i] _ TRUE; remLooks['i] _ FALSE; addLooks['z] _ TRUE; remLooks['z] _ FALSE; state _ null; } ELSE { IF state = name THEN { pLen _ pLen + tokLen; } ELSE { pStart _ tokStart; pLen _ tokLen; }; state _ name; }; }; tokenSINGLE => { IF (state = name AND token[0] = ':) THEN state _ nameColon ELSE { IF state = name THEN pLen _ pLen + 1; }; }; ENDCASE => state _ null; IF add THEN { EditSpan.ChangeLooks[root, [[node,tokStart], [node,tokStart+tokLen-1]], remLooks, addLooks, event]; add _ FALSE; addLooks _ TextLooks.noLooks; remLooks _ casabaLooks; }; IF state = nameColon THEN { state _ null; IF pLen > 0 THEN { EditSpan.AddLooks[root, [[node, pStart], [node, pStart+pLen-1]], nameLooks, event] }; pLen _ 0; }; ENDLOOP; }; SetCasabaLooksOp: TEditInput.CommandProc = { DoSet: PROC [root: TextNode.Ref, tSel: TEditDocument.Selection] = { span: TextNode.Span _ [tSel.start.pos, tSel.end.pos]; firstText: TextNode.RefTextNode ~ tSel.start.pos.node; lastText: TextNode.RefTextNode ~ tSel.end.pos.node; IF firstText # NIL THEN NodeAddrs.PutTextAddr[firstText, $Start, tSel.start.pos.where]; IF lastText # 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] }; SetSpanCasabaLooks[span, TEditInput.currentEvent]; tSel.start.pos _ [firstText, IF firstText=NIL THEN TextNode.NodeItself ELSE NodeAddrs.GetTextAddr[firstText,$Start].location]; tSel.end.pos _ [lastText, 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]; quit _ TRUE; }; TEditInput.Register[$SetCasabaLooks, SetCasabaLooksOp, TRUE]; END. ,CasabaFormattingImpl.Mesa Copyright Σ 1988 by Xerox Corporation. All rights reserved. Shamelessly stolen from Tioga's TEditMesaOpsImpl James Rauen, July 8, 1988 3:55:38 pm PDT Last edited by: James Rauen July 10, 1988 11:11:00 am PDT Return TRUE if r is a Casaba keyword. do the entire node Κ—˜™Icode™