<<-- EditSpan.mesa>> <<-- written by Bill Paxton, June 1981>> <<-- last edit by Bill Paxton, October 13, 1982 2:22 pm>> <<-- last edit by Russ Atkinson, July 22, 1983 9:50 am>> DIRECTORY TextLooks, TextNode, TextEdit, UndoEvent; EditSpan: CEDAR DEFINITIONS = BEGIN Ref: TYPE = TextNode.Ref; RefTextNode: TYPE = TextNode.RefTextNode; RefOtherNode: TYPE = TextNode.RefOtherNode; Offset: TYPE = TextNode.Offset; MaxLen: Offset = LAST[Offset]; Location: TYPE = TextNode.Location; Span: TYPE = TextNode.Span; Event: TYPE = UndoEvent.Ref; <<-- Miscellaneous>> CannotDoEdit: ERROR; afterMoved1, afterMoved2: Location; <<-- hints for repaint set by Move, MoveOnto, and Transpose>> <<-- gives pointers to locs after the moved spans>> <<-- **** Operations to add or delete looks ****>> Looks: TYPE = TextLooks.Looks; noLooks: Looks = TextLooks.noLooks; allLooks: Looks = TextLooks.allLooks; ChangeLooks: PROC [root: Ref, span: Span, remove, add: Looks, event: Event _ NIL]; <<-- first remove then add in the given span>> AddLooks: PROC [root: Ref, span: Span, add: Looks, event: Event _ NIL] = INLINE { ChangeLooks[root, span, noLooks, add, event] }; RemoveLooks: PROC [root: Ref, span: Span, remove: Looks, event: Event _ NIL] = INLINE { ChangeLooks[root, span, remove, noLooks, event] }; SetLooks: PROC [root: Ref, span: Span, new: Looks, event: Event _ NIL] = INLINE { ChangeLooks[root, span, allLooks, new, event] }; ClearLooks: PROC [root: Ref, span: Span, event: Event _ NIL] = INLINE { ChangeLooks[root, span, allLooks, noLooks, event] }; <<-- ***** Editing operations on spans>> Replace: PROC [destRoot, sourceRoot: Ref, dest, source: Span, words: BOOLEAN _ FALSE, saveForPaste: BOOLEAN _ TRUE, event: Event _ NIL] RETURNS [result: Span]; <<-- replace dest span by copy of source span>> <<-- if words flag is true, does ReplaceWords instead of ReplaceText>> <<-- result is the new copy of source>> Delete: PROC [root: Ref, del: Span, event: Event _ NIL, saveForPaste: BOOLEAN _ TRUE]; SaveForPaste: PROC [span: Span, event: Event _ NIL]; SavedForPaste: PROC RETURNS [span: Span]; <<-- result is last thing deleted or explicitly saved for Paste>> Place: TYPE = { before, after, sibling, child }; <<-- these are modifiers for the destination of a Move or Copy or Insert>> <<-- only apply when destination is an entire node (i.e., dest.where = NodeItself)>> <<-- place = before means insert as sibling before dest>> <<-- place = after means insert as sibling after dest; inherit children of dest>> <<-- place = sibling means insert as sibling after dest; don't inherit children of dest>> <<-- place = child means insert as first child of dest>> Copy: PROC [destRoot, sourceRoot: Ref, dest: Location, source: Span, words: BOOLEAN _ FALSE, where: Place _ after, nesting: INTEGER _ 0, event: Event _ NIL] RETURNS [result: Span]; <<-- result is the new copy of source>> Move: PROC [destRoot, sourceRoot: Ref, dest: Location, source: Span, words: BOOLEAN _ FALSE, where: Place _ after, nesting: INTEGER _ 0, event: Event _ NIL] RETURNS [result: Span]; <<-- dest cannot be within source or get error BadMove>> <<-- result is moved span>> <<-- nesting is relative to dest>> <<-- e.g., where=after and nesting=1 makes source be child of dest>> MoveOnto: PROC [destRoot, sourceRoot: Ref, dest, source: Span, words: BOOLEAN _ FALSE, saveForPaste: BOOLEAN _ TRUE, event: Event _ NIL] RETURNS [result: Span]; <<-- like Replace, but moves source instead of copying it>> <<-- result is moved span>> Transpose: PROC [alphaRoot, betaRoot: Ref, alpha, beta: Span, words: BOOLEAN _ FALSE, event: Event _ NIL] RETURNS [newAlpha, newBeta: Span]; <<-- alpha and beta must not overlap or get error BadTranspose>> <<-- newAlpha is new location of alpha span; ditto for newBeta>> <<-- ***** New nodes; split & merge>> Insert: PROC [root, old: Ref, where: Place _ after, event: Event _ NIL] RETURNS [new: Ref]; <<-- empty copy of old node is inserted in tree in position determined by "where">> Inherit: PROC [old, new: Ref, allprops: BOOL _ FALSE]; InsertTextNode: PROC [root, old: Ref, where: Place _ after, inherit: BOOLEAN _ FALSE, event: Event _ NIL] RETURNS [new: RefTextNode]; <<-- empty text node is inserted in tree>> InsertOtherNode: PROC [root, old: Ref, where: Place _ after, inherit: BOOLEAN _ FALSE, event: Event _ NIL] RETURNS [new: RefOtherNode]; <<-- empty "other" kind of node is inserted in tree>> Split: PROC [root: Ref, loc: Location, event: Event _ NIL] RETURNS [new: Ref]; <<-- inserts copy of loc.node is inserted directly before loc.node (as sibling)>> <<-- new adopts children of old (if any)>> <<-- if loc.where # NodeItself and loc.node is a text node, then>> <<-- text after loc.where moves to new node>> <<-- text before loc.where stays in old node>> <<-- returns the new node>> Merge: PROC [root, node: Ref, event: Event _ NIL] RETURNS [loc: Location]; <<-- copies text of node to end of previous node>> <<-- then deletes node>> <<-- ***** Nesting>> Nest: PROC [root: Ref, span: Span, event: Event _ NIL] RETURNS [new: Span] = INLINE { <<-- moves span to a deeper nesting level in tree>> <<-- moves all nodes of span, even if don't have entire node selected >> new _ ChangeNesting[root,span,1,event] }; UnNest: PROC [root: Ref, span: Span, event: Event _ NIL] RETURNS [new: Span] = INLINE { <<-- moves span to a shallower nesting level in tree>> new _ ChangeNesting[root,span,-1,event] }; ChangeNesting: PROC [root: Ref, span: Span, change: INTEGER, event: Event _ NIL] RETURNS [new: Span]; <<-- ***** Cap's and Lowercase>> AllCaps: PROC [root: Ref, span: Span, event: Event _ NIL] = INLINE { ChangeCaps[root,span,allCaps,event] }; <<-- force specified span to all uppercase>> AllLower: PROC [root: Ref, span: Span, event: Event _ NIL] = INLINE { ChangeCaps[root,span,allLower,event] }; <<-- force specified span to all lowercase>> InitialCaps: PROC [root: Ref, span: Span, event: Event _ NIL] = INLINE { ChangeCaps[root,span,initCaps,event] }; <<-- force first letter of words uppercase>> CapChange: TYPE = TextEdit.CapChange; ChangeCaps: PROC [root: Ref, span: Span, how: CapChange _ allCaps, event: Event _ NIL]; <<-- ***** Miscellaneous>> NodeOrder: TYPE = { before, same, after, disjoint }; CompareNodeOrder: PROC [node1, node2: Ref] RETURNS [order: NodeOrder]; <<-- determines relative order in tree of the nodes>> <<-- returns "same" if node1 = node2>> <<-- returns "before" if node1 comes before node2>> <<-- returns "after" if node1 comes after node2>> <<-- returns "disjoint" if nodes are not from the same tree>> <<-- ***** Initialization>> Start: PROC; -- for initialization only END.