-- 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: BOOLEANFALSE, saveForPaste: BOOLEANTRUE, 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: BOOLEANTRUE];
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: BOOLEANFALSE,
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: BOOLEANFALSE,
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: BOOLEANFALSE, saveForPaste: BOOLEANTRUE, 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: BOOLEANFALSE, 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: BOOLFALSE];
InsertTextNode: PROC [root, old: Ref, where: Place ← after, inherit: BOOLEANFALSE, event: Event ← NIL]
RETURNS [new: RefTextNode];
-- empty text node is inserted in tree
InsertOtherNode: PROC [root, old: Ref, where: Place ← after, inherit: BOOLEANFALSE, 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.