DIRECTORY AbbrevExpand USING [Expand, Load], Ascii USING [Lower], Atom USING [GetPName, MakeAtom], Basics USING [BITAND], EditSpan USING [ChangeCaps], FS USING [Error], MessageWindow USING [Append, Blink], NodeProps USING [false, true], NodeStyleOps USING [ReloadStyle, StyleNameForNode], NodeStyleWorks USING [ForEachAttachedStyle], Rope USING [Concat, Fetch, FromProc, IsEmpty, ROPE, Size, Substr], RopeEdit USING [AlphaNumericChar, Substr], RopeReader USING [FreeRopeReader, Get, GetIndex, GetRopeReader, Ref, SetPosition], TextEdit USING [CapChange, ChangeFormat, ChangeStyle, FetchChar, FetchLooks, GetCharPropList, GetRope, Offset, PropList, PutCharPropList, PutProp, ReplaceByChar], TextNode USING [Location, NarrowToTextNode, NodeItself, Offset, Ref, RefTextNode, Root, StepForward], TEditDocument USING [BeforeAfter, Selection, SelectionId, SelectionPoint], TEditInput USING [currentEvent, Interpret], TEditInputOps USING [BackSpace, CallWithBothLocked, CallWithLocks, CheckReadonly, Delete, EditFailed, FindPlaceholders, InsertChar, InsertRope], TEditLocks USING [Lock, Unlock], TEditSelection USING [Alloc, Copy, Free, CaretAfterSelection, Deselect, InsertionPoint, LockSel, MakePointSelection, MakeSelection, oldSel, pSel, SelectionRoot, sSel, UnlockSel], TEditTouchup USING [fullUpdate], ViewerClasses USING [Viewer], ViewerOps USING [PaintViewer]; TEditMiscOps2Impl: CEDAR PROGRAM IMPORTS Atom, AbbrevExpand, Ascii, FS, EditSpan, Basics, MessageWindow, NodeProps, NodeStyleOps, NodeStyleWorks, Rope, RopeEdit, RopeReader, TextEdit, TextNode, TEditInput, TEditInputOps, TEditLocks, TEditSelection, TEditTouchup, ViewerOps EXPORTS TEditInputOps = BEGIN Capitalise: PUBLIC PROCEDURE [flavor: TextEdit.CapChange] = { DoCapitalise: PROC [root: TextNode.Ref, tSel: TEditDocument.Selection] = { TEditSelection.Deselect[]; EditSpan.ChangeCaps[root, [tSel.start.pos, tSel.end.pos], flavor, TEditInput.currentEvent]; tSel.pendingDelete _ FALSE; TEditSelection.MakeSelection[tSel,primary] }; TEditInputOps.CallWithLocks[DoCapitalise] }; ControlChar: PROC [make: BOOLEAN] = { DoControlChar: PROC [root: TextNode.Ref, tSel: TEditDocument.Selection] = { caret: TextNode.Location _ TEditSelection.InsertionPoint[tSel]; node: TextNode.RefTextNode; where: TextNode.Offset; char: CHAR; IF caret.where=TextNode.NodeItself OR caret.where=0 THEN GOTO Bad; IF (node _ TextNode.NarrowToTextNode[caret.node]) = NIL THEN GOTO Bad; where _ caret.where-1; char _ TextEdit.FetchChar[node,where].char; IF ~make AND char > 37C THEN GOTO Bad; char _ IF ~make THEN LOOPHOLE[char-1,CARDINAL]+'A ELSE LOOPHOLE[Basics.BITAND[char-0C,37B],CHAR]; TEditSelection.Deselect[]; [] _ TextEdit.ReplaceByChar[ root: root, dest:node, char:char, start:where, len:1, inherit:FALSE, looks:TextEdit.FetchLooks[node,where], event:TEditInput.currentEvent]; TEditSelection.MakePointSelection[tSel, caret]; EXITS Bad => TEditInputOps.EditFailed[] }; TEditInputOps.CallWithLocks[DoControlChar] }; MakeControlCharacter: PUBLIC PROC = { ControlChar[TRUE] }; UnMakeControlCharacter: PUBLIC PROC = { ControlChar[FALSE] }; UnMakeOctalCharacter: PUBLIC PROC = { DoUnMakeOctalCharacter: PROC [root: TextNode.Ref, tSel: TEditDocument.Selection] = { InsertOctal: PROC [c: CARDINAL] ~ { TEditInputOps.InsertChar[c/64 + '0]; TEditInputOps.InsertChar[(c/8) MOD 8 + '0]; TEditInputOps.InsertChar[c MOD 8 + '0]; }; caret: TextNode.Location ~ TEditSelection.InsertionPoint[tSel]; node: TextNode.RefTextNode ~ caret.node; charSet: CARDINAL; char: CHAR; charProps: TextEdit.PropList; IF caret.where=TextNode.NodeItself OR caret.where=0 THEN GOTO Bad; IF node = NIL THEN GOTO Bad; [charSet, char] _ TextEdit.FetchChar[node, caret.where-1]; charProps _ TextEdit.GetCharPropList[node, caret.where-1]; TEditInputOps.BackSpace[1]; IF charSet = 0 THEN InsertOctal[ORD[char]] ELSE { TEditInputOps.InsertChar['(]; InsertOctal[charSet]; TEditInputOps.InsertChar['|]; InsertOctal[ORD[char]]; TEditInputOps.InsertChar[')]; }; IF charProps # NIL THEN { TextEdit.PutCharPropList[node: node, index: caret.where-1, nChars: IF charSet = 0 THEN 3 ELSE 9, propList: charProps, event: TEditInput.currentEvent] }; EXITS Bad => TEditInputOps.EditFailed[] }; TEditInputOps.CallWithLocks[DoUnMakeOctalCharacter] }; MakeOctalCharacter: PUBLIC PROC = { DoMakeOctalCharacter: PROC [root: TextNode.Ref, tSel: TEditDocument.Selection] = { caret: TextNode.Location _ TEditSelection.InsertionPoint[tSel]; node: TextNode.RefTextNode ~ caret.node; GetOctal: PROC [offset: INT] RETURNS [d: CARDINAL _ 0] ~ { c: CHAR; s: [0..256); FOR i: INT IN [0..3) DO [s, c] _ TextEdit.FetchChar[node, offset+i]; IF s#0 OR c NOT IN ['0..'7] THEN RETURN [NAT.LAST]; d _ d*8 + (c-'0); ENDLOOP; }; len: INT _ 0; charCode: CARDINAL _ 0; charSet: CARDINAL _ 0; IF caret.where=TextNode.NodeItself OR caret.where<3 THEN GOTO Bad; IF node = NIL THEN GOTO Bad; IF TextEdit.FetchChar[node, caret.where-1] = [charSet: 0, char: ')] THEN { IF caret.where<9 THEN GOTO Bad; IF TextEdit.FetchChar[node, caret.where-5] # [charSet: 0, char: '|] THEN GOTO Bad; IF TextEdit.FetchChar[node, caret.where-9] # [charSet: 0, char: '(] THEN GOTO Bad; charCode _ GetOctal[caret.where-4]; charSet _ GetOctal[caret.where-8]; len _ 9; } ELSE { charCode _ GetOctal[caret.where-3]; len _ 3; }; IF charCode > 255 OR charSet >= 255 THEN GOTO Bad; TEditSelection.Deselect[]; { charProps: TextEdit.PropList ~ TextEdit.GetCharPropList[node, caret.where-len]; [] _ TextEdit.ReplaceByChar[ root: root, dest: node, char: VAL[charCode], start: caret.where-len, len: len, inherit: FALSE, looks: TextEdit.FetchLooks[node, caret.where-len], charSet: charSet, event: TEditInput.currentEvent]; IF charProps # NIL THEN TextEdit.PutCharPropList[node: node, index: caret.where-len, nChars: 1, propList: charProps, event: TEditInput.currentEvent] }; caret.where _ caret.where-len+1; TEditSelection.MakePointSelection[tSel, caret]; EXITS Bad => TEditInputOps.EditFailed[] }; TEditInputOps.CallWithLocks[DoMakeOctalCharacter] }; GetWord: PROC RETURNS [word: Rope.ROPE] = { tSel: TEditDocument.Selection; start: TextEdit.Offset; pos: TextNode.Location; node: TextNode.RefTextNode; nChars: CARDINAL _ 0; TEditSelection.CaretAfterSelection; pos _ TEditSelection.InsertionPoint[]; IF (node _ TextNode.NarrowToTextNode[pos.node])=NIL THEN RETURN [NIL]; IF pos.where = TextNode.NodeItself THEN RETURN [NIL]; start _ pos.where-1; WHILE start>=0 DO set: NAT; c: CHAR; [set, c] _ TextEdit.FetchChar[node, start]; IF set#0 OR NOT RopeEdit.AlphaNumericChar[c] THEN EXIT; start _ start - 1; nChars _ nChars + 1; ENDLOOP; IF nChars = 0 THEN RETURN [NIL]; start _ pos.where-nChars; word _ RopeEdit.Substr[node.rope, start, nChars]; tSel _ TEditSelection.Alloc[]; TEditSelection.Copy[source: TEditSelection.pSel, dest: tSel]; tSel.start.pos _ [node,start]; tSel.end.pos _ [node,start+nChars-1]; tSel.granularity _ char; TEditSelection.MakeSelection[tSel, primary]; TEditSelection.Free[tSel]; TEditInputOps.Delete[]; }; SetStyle: PUBLIC PROC = { DoSetStyle: PROC [root: TextNode.Ref, tSel: TEditDocument.Selection] = { name: Rope.ROPE _ GetWord[]; IF name=NIL THEN { TEditInputOps.EditFailed[]; RETURN }; SetStyleName[name] }; TEditInputOps.CallWithLocks[DoSetStyle] }; ForceLower: PROC [r: Rope.ROPE] RETURNS [Rope.ROPE] = { Force: PROC RETURNS [c: CHAR] = { c _ Ascii.Lower[Rope.Fetch[r,i]]; i _ i+1 }; i: INT _ 0; RETURN [Rope.FromProc[Rope.Size[r], Force]] }; SetStyleName: PUBLIC PROC [name: Rope.ROPE, node: TextNode.Ref _ NIL] = { root: TextNode.Ref; IF node=NIL THEN node _ IF TEditSelection.pSel.insertion=before THEN TEditSelection.pSel.start.pos.node ELSE TEditSelection.pSel.end.pos.node; root _ TextNode.Root[node]; [] _ TEditLocks.Lock[root, "SetStyleName"]; TextEdit.ChangeStyle[node, ForceLower[name], TEditInput.currentEvent, root ! UNWIND => TEditLocks.Unlock[root]]; TEditLocks.Unlock[root]; }; ReloadStyle: PUBLIC PROC = { styleName: ATOM _ NodeStyleOps.StyleNameForNode[TEditSelection.InsertionPoint[].node]; IF NOT NodeStyleOps.ReloadStyle[styleName] THEN CannotReload[styleName] ELSE ViewerOps.PaintViewer[TEditSelection.pSel.viewer, client, FALSE, TEditTouchup.fullUpdate]; }; ReloadStyleName: PUBLIC PROC [name: Rope.ROPE] = { styleName: ATOM; IF name.IsEmpty THEN RETURN; styleName _ Atom.MakeAtom[name]; IF NOT NodeStyleOps.ReloadStyle[styleName] THEN CannotReload[styleName]; }; CannotReload: PROC [styleName: ATOM] = { MessageWindow.Append["Failed in attempt to load style named ", TRUE]; MessageWindow.Append[Atom.GetPName[styleName]]; MessageWindow.Blink[] }; SetFormat: PUBLIC PROC = { DoSetFormat: PROC [root: TextNode.Ref, tSel: TEditDocument.Selection] = { name: Rope.ROPE _ GetWord[]; IF name=NIL THEN { TEditInputOps.EditFailed[]; RETURN }; SetFormatName[name] }; TEditInputOps.CallWithLocks[DoSetFormat] }; GetFormat: PUBLIC PROC = { DoGetFormat: PROC [root: TextNode.Ref, tSel: TEditDocument.Selection] = { name: Rope.ROPE; format: ATOM _ TEditSelection.InsertionPoint[].node.formatName; name _ IF format=NIL THEN "default" ELSE Atom.GetPName[format]; TEditInputOps.InsertRope[name] }; TEditInputOps.CallWithLocks[DoGetFormat] }; TransposeFormat: PUBLIC PROC [target: TEditDocument.SelectionId _ primary] = { targetSel: TEditDocument.Selection _ IF target=primary THEN TEditSelection.pSel ELSE TEditSelection.sSel; srcSel: TEditDocument.Selection _ IF target=primary THEN TEditSelection.sSel ELSE TEditSelection.pSel; DoTransFormat: PROC [sourceRoot, destRoot: TextNode.Ref, tSel, srcSel, targetSel: TEditDocument.Selection] = { targetFormat, srcFormat: ATOM; targetNode, srcNode: TextNode.Ref; srcNode _ IF srcSel.insertion=before THEN srcSel.start.pos.node ELSE srcSel.end.pos.node; srcFormat _ srcNode.formatName; targetNode _ IF targetSel.insertion=before THEN targetSel.start.pos.node ELSE targetSel.end.pos.node; targetFormat _ targetNode.formatName; TEditSelection.Copy[source: targetSel, dest: TEditSelection.oldSel]; -- save for Repeat's FOR node: TextNode.Ref _ targetSel.start.pos.node, TextNode.StepForward[node] DO TextEdit.ChangeFormat[node, srcFormat, TEditInput.currentEvent, destRoot]; IF node = targetSel.end.pos.node THEN EXIT; ENDLOOP; FOR node: TextNode.Ref _ srcSel.start.pos.node, TextNode.StepForward[node] DO TextEdit.ChangeFormat[node, targetFormat, TEditInput.currentEvent, sourceRoot]; IF node = srcSel.end.pos.node THEN EXIT; ENDLOOP; TEditSelection.MakeSelection[IF target=primary THEN targetSel ELSE srcSel, primary] }; TEditInputOps.CallWithBothLocked[DoTransFormat, targetSel, srcSel, write] }; CopyFormat: PUBLIC PROCEDURE [target: TEditDocument.SelectionId _ primary] = { targetSel: TEditDocument.Selection _ IF target=primary THEN TEditSelection.pSel ELSE TEditSelection.sSel; srcSel: TEditDocument.Selection _ IF target=primary THEN TEditSelection.sSel ELSE TEditSelection.pSel; DoCopyFormat: PROC [sourceRoot, destRoot: TextNode.Ref, tSel, srcSel, targetSel: TEditDocument.Selection] = { srcNode: TextNode.Ref _ IF srcSel.insertion=before THEN srcSel.start.pos.node ELSE srcSel.end.pos.node; format: ATOM _ srcNode.formatName; TEditSelection.Copy[source: srcSel, dest: TEditSelection.oldSel]; -- save for Repeat's FOR node: TextNode.Ref _ targetSel.start.pos.node, TextNode.StepForward[node] DO TextEdit.ChangeFormat[node, format, TEditInput.currentEvent, destRoot]; IF node = targetSel.end.pos.node THEN EXIT; ENDLOOP; TEditSelection.MakeSelection[IF target=primary THEN targetSel ELSE srcSel, primary] }; TEditInputOps.CallWithBothLocked[DoCopyFormat, targetSel, srcSel, read] }; SetFormatName: PUBLIC PROC [name: Rope.ROPE, node: TextNode.Ref _ NIL] = { root: TextNode.Ref; lockSel: BOOL = (node=NIL); format: ATOM _ IF name.IsEmpty THEN NIL ELSE Atom.MakeAtom[ForceLower[name]]; IF lockSel THEN { TEditSelection.LockSel[primary, "SetFormatName"]; IF ~TEditInputOps.CheckReadonly[TEditSelection.pSel] OR (root _ TEditSelection.SelectionRoot[TEditSelection.pSel])=NIL THEN { TEditSelection.UnlockSel[primary]; RETURN }; node _ TEditSelection.InsertionPoint[].node } ELSE root _ TextNode.Root[node]; { ENABLE UNWIND => IF lockSel THEN TEditSelection.UnlockSel[primary]; [] _ TEditLocks.Lock[root, "SetFormatName"]; TextEdit.ChangeFormat[node, format, TEditInput.currentEvent, root]; TEditLocks.Unlock[root]; IF lockSel THEN TEditSelection.UnlockSel[primary] } }; SetSelFormatName: PROC [name: Rope.ROPE, sel: TEditDocument.Selection] = { DoSetSelFormatName: PROC [root: TextNode.Ref, tSel: TEditDocument.Selection] = { format: ATOM _ IF name.IsEmpty THEN NIL ELSE Atom.MakeAtom[ForceLower[name]]; FOR node: TextNode.Ref _ tSel.start.pos.node, TextNode.StepForward[node] DO TextEdit.ChangeFormat[node, format, TEditInput.currentEvent, root]; IF node = tSel.end.pos.node THEN EXIT; ENDLOOP }; TEditInputOps.CallWithLocks[DoSetSelFormatName] }; SetCommentProp: PUBLIC PROC [flag: BOOLEAN] = { DoSetCommentProp: PROC [root: TextNode.Ref, tSel: TEditDocument.Selection] = { FOR node: TextNode.Ref _ tSel.start.pos.node, TextNode.StepForward[node] DO n: TextNode.RefTextNode _ TextNode.NarrowToTextNode[node]; IF n # NIL THEN TextEdit.PutProp[n, $Comment, IF flag THEN NodeProps.true ELSE NodeProps.false, TEditInput.currentEvent]; IF node = tSel.end.pos.node THEN EXIT; ENDLOOP }; TEditInputOps.CallWithLocks[DoSetCommentProp] }; abbrevFailedProc: PROC RETURNS [BOOL] _ NIL; RegisterAbbrevFailedProc: PUBLIC PROC [proc: PROC RETURNS [BOOL]] = { abbrevFailedProc _ proc }; ExpandAbbreviation: PUBLIC PROC = { DoExpand: PROC [root: TextNode.Ref, tSel: TEditDocument.Selection] = { pos: TextNode.Location; node: TextNode.RefTextNode; offset: TextEdit.Offset; done, keyDeterminesDict: BOOLEAN _ FALSE; clearedMessageWindow: BOOLEAN _ FALSE; keyStart, keyLen, resultLen: TextEdit.Offset; rdr: RopeReader.Ref; commands: LIST OF REF ANY; styleName: ATOM; Try: PROC [name: ATOM] RETURNS [stop: BOOLEAN] = { dict: Rope.ROPE = Atom.GetPName[name]; [done,keyDeterminesDict,keyStart,keyLen,resultLen,commands] _ AbbrevExpand.Expand[node,offset,dict,TEditInput.currentEvent]; IF ~done AND ~keyDeterminesDict THEN NodeStyleWorks.ForEachAttachedStyle[name,Try]; RETURN [done] }; TEditSelection.CaretAfterSelection; pos _ TEditSelection.InsertionPoint[]; node _ TextNode.NarrowToTextNode[pos.node]; offset _ pos.where; styleName _ NodeStyleOps.StyleNameForNode[node]; TEditSelection.Deselect[]; IF ~Try[styleName] THEN { TEditSelection.MakeSelection[tSel, primary]; IF abbrevFailedProc # NIL AND abbrevFailedProc[] THEN RETURN; MessageWindow.Append[Rope.Substr[TextEdit.GetRope[node], keyStart, keyLen], ~clearedMessageWindow]; MessageWindow.Append["? Unknown abbreviation."]; RETURN }; tSel.end.pos.node _ tSel.start.pos.node _ node; tSel.start.pos.where _ keyStart; tSel.pendingDelete _ FALSE; IF resultLen = 0 THEN { -- make a caret tSel.end.pos.where _ keyStart; tSel.insertion _ before; tSel.granularity _ point } ELSE { tSel.end.pos.where _ keyStart+resultLen-1; tSel.insertion _ after; tSel.granularity _ char }; TEditSelection.MakeSelection[tSel, primary]; rdr _ RopeReader.GetRopeReader[]; RopeReader.SetPosition[rdr, TextEdit.GetRope[node], keyStart]; FOR i: INT IN [0..resultLen) DO -- check for placeholder IF RopeReader.Get[rdr] = 1C THEN { -- found one TEditSelection.MakePointSelection[tSel,[node,keyStart+i]]; TEditInputOps.FindPlaceholders[TRUE]; EXIT }; ENDLOOP; RopeReader.FreeRopeReader[rdr]; IF commands # NIL THEN TEditInput.Interpret[TEditSelection.pSel.viewer, commands] }; TEditInputOps.CallWithLocks[DoExpand] }; LoadAbbreviations: PUBLIC PROC [dictName: Rope.ROPE] = { count: LONG INTEGER _ 0; fileName: Rope.ROPE; IF Rope.Size[dictName]=0 THEN RETURN; fileName _ Rope.Concat[dictName,".Abbreviations"]; count _ AbbrevExpand.Load[fileName, dictName ! FS.Error => {CONTINUE}]; IF count = 0 THEN { -- something went wrong MessageWindow.Append["The file named <", TRUE]; MessageWindow.Append[fileName]; MessageWindow.Append["> was not found or was not an abbreviation dictionary"] } }; END. ‚TEditMiscOps2Impl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Paxton on December 28, 1982 2:23 pm Maxwell, January 6, 1983 11:34 am Russ Atkinson, July 26, 1983 11:45 am Paul Rovner, August 10, 1983 4:41 pm Michael Plass, March 27, 1985 4:58:13 pm PST Rick Beach, March 28, 1985 9:59:13 am PST Transpose the formats of the primary and secondary selections Κθ˜codešœ™Kšœ Οmœ1™š žœžœžœžœ ˜8šžœžœ  ˜/K˜:Kšœžœ˜%Kšžœ˜K˜—Kšžœ˜—K˜K˜Kšžœ žœžœ<˜RK˜—K˜K˜&K˜—K˜šŸœžœžœžœ˜8Kšœžœžœ˜Kšœžœ˜Kšžœžœžœ˜%K˜2˜#Kšœ žœ žœ˜#—šžœ žœ ˜+K˜Kšœ)žœ˜/K˜K˜NK˜—K˜—K˜Kšžœ˜—K˜—…—>fNΠ