-- TEditDocument.mesa; Edited by Paxton on December 28, 1982 2:07 pm
DIRECTORY
Rope USING [ROPE],
TextEdit USING [RefTextNode],
TextLooks USING [Looks, noLooks],
TextNode USING [Location, Ref],
ViewerClasses USING [Viewer];
TEditDocument: CEDAR DEFINITIONS = BEGIN
TEditDocumentData: TYPE = REF TEditDocumentDataRec;
TEditDocumentDataRec: TYPE = MACHINE DEPENDENT RECORD [ -- 9 words
text: TextEdit.RefTextNode,  -- the underlying text data
lineTable: LineTable,   -- displayed line information
clipLevel: ClipCount ← maxClip, -- controls level clipping for this viewer
unused: [0..4) ← 0,
scrollGlitch: BOOLFALSE,  -- if true then try to glitch when scroll
scrollSelectionId: SelectionId ← primary, -- scroll to make this visible
fixStart: BOOLFALSE,  -- fix it so it starts after CR or at start of node
readOnly: BOOLFALSE, -- user edits inhibited
movedOut: BOOLFALSE, -- have moved nodes out of document since last screen refresh
movedIn: BOOLFALSE, -- have moved nodes into document since last screen refresh
dirty: BOOLFALSE, -- haven't refreshed since last edit
invisible: BOOLFALSE, -- refresh won't happen because iconic or obscured or ...
tsInfo: TSInfo ← NIL,   -- special procs when in typescript mode
lockProcess: PROCESSNIL, -- process holding lock on this data structure
who: Rope.ROPE,   -- who locked the tdd
lock: [0..64) ← 0,   -- locking for put/get/paints etc.
interrupt: [0..64) ← 0, -- number of processes waiting for lock and asking for interrupt
display refresh will terminate if notices interrupt > 0
scroll: Scroll ← no,   -- controls scrolling after refresh
commentFilter: CommentFilter ← includeComments -- controls showing of comment nodes
];
SelectionId: TYPE = {primary, secondary, feedback};
ClipCount: TYPE = [0..32) ;
maxClip: ClipCount = 31; -- use 5 bits for this
CommentFilter: TYPE = { includeComments, excludeComments, onlyComments };
Scroll: TYPE = { no, endofdoc, endofsel };
LineTable: TYPE = REF LineTableRec;
LineTableRec: TYPE = RECORD [
lastLine: INTEGER ← 0,
lastY: INTEGER ← 0,
lines: SEQUENCE maxLines: INTEGER OF --Line-- LineRec
];
--Line: TYPE = REF LineRec;
LineRec: TYPE = MACHINE DEPENDENT RECORD [ -- 9 words
pos: TextNode.Location, -- first character in line
valid: BOOLTRUE, -- metrics valid for this line
end: LineBreak ← eon, -- reason for line break
nChars: [0..8192) ← 0, -- number of characters in line
yOffset: INTEGER ← 0, -- baseline from top of viewer
xOffset: INTEGER ← 0, -- line offset from left edge of viewer
width: INTEGER ← 0, -- width of displayed bits
ascent: [0..512) ← 0,  -- dy above baseline
descent: [0..128) ← 0  -- dy below baseline
];
LineBreak: TYPE = { eon, cr, wrap } ← eon;
ttyChars: CARDINAL = 128; -- size of input buffer for TS; overflow goes to rope
TSInfo: TYPE = REF TSInfoRec;
TSInfoRec: TYPE = RECORD [
iIncr: CONDITION, -- raised whenever add to input
looks: TextLooks.Looks ← TextLooks.noLooks, -- for PutChar
inputRope: Rope.ROPE, -- for overflow from input array
inputLoc: INT ← 0, -- index of next char to read from rope
input: PACKED ARRAY [0..ttyChars) OF CHARACTER,
iQp, oQp: [0..ttyChars) ← 0, -- read and write indexes for input buffer
intParam: INT, -- parameter from TIP
waitingInGetChar: BOOLFALSE,
abort: BOOLFALSE
];
Selection: TYPE = REF SelectionRec;
SelectionRec: TYPE = RECORD [
viewer: ViewerClasses.Viewer,
data: TEditDocumentData,
start: SelectionPoint,
end: SelectionPoint,
caretX, caretY: INTEGER,
granularity: SelectionGrain,
punctuation: PunctuationPosition, -- whether spaces are part of the selection
insertion: BeforeAfter,
looks: TextLooks.Looks ← TextLooks.noLooks, -- caret looks
pendingDelete: BOOLFALSE  -- Laurel-style pending deletion of selection
];
SelectionPoint: TYPE = RECORD [
pos: TextNode.Location,
line: INTEGER ← 0,
x: INTEGER ← 0,
y: INTEGER ← 0,
w: INTEGER ← 0,
h: INTEGER ← 0,
clipped: BOOLFALSE,
metricsValid: BOOLFALSE];
SelectionGrain: TYPE = {point, char, word, node, branch} ← char;
PunctuationPosition: TYPE = {none, leading, trailing} ← none;
BeforeAfter: TYPE = {before, after} ← before;
fatalTiogaError: ERROR ;
SpinAndLock: PROC [tdd: TEditDocumentData, who: Rope.ROPE, interrupt, defer: BOOLFALSE]
RETURNS [ok: BOOL];
if caller is not the original locking process, waits for other process to unlock first
if interrupt is true, increments tdd.interrupt to ask repaint of viewer to terminate
if defer is true and interrupt is true and tdd.interrupt > 0, returns false without locking.
Unlock: PROC [tdd: TEditDocumentData];
-- give up the lock
RecordViewerForRoot: PROC [viewer: ViewerClasses.Viewer, root: TextNode.Ref];
ForgetViewer: PROC [viewer: ViewerClasses.Viewer];
-- remove this from the root => viewer mapping
GetViewerForRoot: PROC [root: TextNode.Ref] RETURNS [viewer: ViewerClasses.Viewer];
END.