-- EditSpan.mesa
-- written by Bill Paxton, June 1981
-- last edit by Bill Paxton, October 13, 1982 2:22 pm
DIRECTORY
TextLooks,
TextNode,
TextEdit,
UndoEvent;
EditSpan:
CEDAR DEFINITIONS
IMPORTS TextLooks =
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.