-- TiogaInputImpl.mesa; Edited by Paxton on June 13, 1983 9:07 am
Last Edited by: Maxwell, January 4, 1983 3:53 pm
Last Edited by: Plass, April 15, 1983 2:03 pm
DIRECTORY
Atom USING [GetPName],
NodeAddrs USING [AddNotifyProc],
EditSpan USING [CompareNodeOrder],
MessageWindow USING [Append, Blink, Clear],
RefTab USING [Create, Fetch, Ref, Store, Delete],
Rope USING [Concat, FromRefText, ROPE],
TiogaDocument USING [TiogaDocumentData, Selection, SelectionId, SelectionRec],
TiogaHistory,
TiogaImpl,
TiogaInput,
TiogaInputOps, -- USING Lots
TiogaOps USING [RememberCurrentPosition],
TiogaProfile USING [CategoryOfUser, userCategory],
TiogaScrolling USING [ScrollToPosition],
TiogaSelection USING [CallWithSelAndDocAndTddLocks, Copy, Create, Extend, FakeSecondary, Find, InsertionPoint, LevelChange, LockSel, MakePointSelection, MakeSelection, oldSel, Position, fSel, pSel, SelectBranch, SelectChar, SelectNode, SelectWord, sSel, UnlockSel, Update],
TiogaSplit USING [Split],
TextEdit USING [Size],
TiogaLooks USING [Look, allLooks, noLooks],
TiogaNode USING [Location, NodeItself, Offset, Ref, RefTextNode],
TiogaNodeOps USING [BranchChild, NarrowToTextNode, Root],
TiogaOps,
TIPUser USING [TIPScreenCoords],
ViewerClasses USING [NotifyProc, Viewer, ViewerRec],
ViewerOps USING [AddProp];
TiogaInputImpl: CEDAR MONITOR
IMPORTS Atom, EditSpan, MessageWindow, NodeAddrs, RefTab, Rope, TiogaInput, TiogaInputOps, TiogaOps, TiogaProfile, TiogaScrolling, TiogaSelection, TiogaSplit, TextEdit, TiogaNodeOps, ViewerOps
EXPORTS TiogaInput, TiogaImpl, TiogaOps =
BEGIN OPEN TiogaInput, TiogaSelection;
mx, my: INTEGER; -- global Coord param for ops below
n: LONG INTEGER; -- global Numeric param for ops below
sel: TiogaDocument.SelectionId ← primary;  -- global sel ID; can be set to "secondary" by $SelSecondary
changeLevel: TiogaSelection.LevelChange; -- change granularity when extend
pDel: BOOLFALSE;
-- global sel ID; can be set to TRUE by $SelPendDel, FALSE by $SelNotPendDel
EditObject: TYPE = {
text, -- operate on the text of the selection
looks, -- operate on the looks only
type -- operate on the type only
};
editState: PUBLIC EditState ← reset;
SelState: TYPE = {
reset,  -- not specified yet
primary,  -- making a primary selection
secondary };
selState: SelState ← reset;
PDelState: TYPE = {
reset,  -- not specified yet
pending, -- making a pending delete selection
not };
pdelState: PDelState ← reset;
commandTable: RefTab.Ref ← RefTab.Create[mod: 100];
editMessage: Rope.ROPENIL;
MessageArray: TYPE = ARRAY BOOLEAN OF ARRAY BOOLEAN OF Rope.ROPE;
toPrimaryMessages: REF MessageArray ← NEW [MessageArray];
toSecondaryMessages: REF MessageArray ← NEW [MessageArray];
EditMessage: PROC = {
msg: Rope.ROPESELECT editState FROM
tolimbo => "Select for delete",
toprimary => SELECT editObject.name FROM
$EditText => toPrimaryMessages[pSel.pendingDelete][sSel.pendingDelete],
ENDCASE => editObject.toprimary,
tosecondary => SELECT editObject.name FROM
$EditText => toSecondaryMessages[pSel.pendingDelete][sSel.pendingDelete],
ENDCASE => editObject.tosecondary,
toboth => editObject.toboth,
ENDCASE => NIL;
IF msg = NIL OR msg = editMessage THEN RETURN;
MessageWindow.Append[msg,TRUE];
editMessage ← msg };
prevPSel: TiogaDocument.Selection ← NEW[TiogaDocument.SelectionRec];
-- for EditAbort
Interpret: PUBLIC PROC [viewer: ViewerClasses.Viewer, params: LIST OF REF ANY] = {
InterpInput[viewer,params] };
InterpretAtom: PUBLIC PROC [viewer: ViewerClasses.Viewer, atom: ATOM] = {
InterpAtom[viewer,atom] };
TiogaNotifyProc: PUBLIC ViewerClasses.NotifyProc = BEGIN
InterpInput[self,input];
END;
interpAtom: ATOM; -- the atom currently being interpreted
InterpAtom: PROCEDURE [viewer: ViewerClasses.Viewer, atom: ATOM] = {
p: REF ANY = RefTab.Fetch[commandTable,atom].val;
IF p=NIL THEN MessageWindow.Append[
Rope.Concat["Unknown atom given to Tioga: ", Atom.GetPName[atom]], TRUE]
ELSE {
procList: LIST OF CommandProc = NARROW[p];
recordAtom: BOOLFALSE;
TiogaInputOps.WaitForInsertToFinish[]; -- make sure previous characters have gone in
interpAtom ← atom; -- in case proc needs to know
FOR list: LIST OF CommandProc ← procList, list.rest UNTIL list=NIL DO
record, quit: BOOL;
[record, quit] ← list.first[viewer];
IF record THEN recordAtom ← TRUE;
IF quit THEN EXIT;
ENDLOOP;
IF recordAtom THEN RecordRef[atom] }};
ResetInputStuff: PUBLIC PROC = { changeLevel ← same };
SaveCoords: PUBLIC PROC [x,y: INTEGER] = { mx ← x; my ← y };
InterpInput: PUBLIC PROCEDURE [viewer: ViewerClasses.Viewer, params: LIST OF REF ANY,
increaseNestingCount: BOOLTRUE] =
BEGIN OPEN TiogaInputOps;
NormaliseSelection: PROC = BEGIN
IF ~pSel.pendingDelete THEN RETURN;
LockSel[primary, "InterpInput"];
{ ENABLE UNWIND => UnlockSel[primary];
IF pSel.pendingDelete THEN DoPendingDelete[];
IF ~InsSel[] THEN MakePointSelection[pSel, InsertionPoint[]];
}; UnlockSel[primary];
END;
InsSel: PROC RETURNS [BOOLEAN] =
INLINE {RETURN[pSel.granularity=point AND pSel.insertion=before
AND sSel.viewer=NIL]};
BumpNesting: ENTRY PROC = INLINE {
IF (interpreterNesting ← interpreterNesting+1) <= 1 THEN {
interpreterNesting ← 1;
closeEvent ← FALSE }};
DecrementNesting: ENTRY PROC RETURNS [BOOL] = INLINE {
RETURN [(interpreterNesting ← interpreterNesting-1) <= 0] };
AllText: PROC [LIST OF REF ANY] RETURNS [BOOLEAN] = INLINE {
FOR input: LIST OF REF ANY ← params, input.rest UNTIL input=NIL DO
WITH input.first SELECT FROM
z: REF CHARACTER => NULL;
z: Rope.ROPE => NULL;
z: REF TEXT => NULL;
ENDCASE => RETURN [FALSE];
ENDLOOP;
RETURN [TRUE] };
ResetInputStuff;
IF interpreterNesting=0 AND ~pSel.pendingDelete AND AllText[params] THEN {
-- hand it off to buffered input routines
FOR input: LIST OF REF ANY ← params, input.rest UNTIL input=NIL DO
WITH input.first SELECT FROM
z: REF CHARACTER => {
NormaliseSelection[]; BufferedInsertChar[z^]; RecordChar[z^]};
z: Rope.ROPE => {
NormaliseSelection[]; BufferedInsertText[z]; RecordRef[z]};
z: REF TEXT => {
NormaliseSelection[]; BufferedInsertText[Rope.FromRefText[z]]; RecordRef[z]};
ENDCASE => ERROR;
ENDLOOP }
ELSE {
IF increaseNestingCount THEN BumpNesting[];
FOR input: LIST OF REF ANY ← params, input.rest UNTIL input=NIL DO
WITH input.first SELECT FROM
z: ATOM => InterpAtom[viewer,z ! BadMouse, DontDoIt => EXIT];
z: TIPUser.TIPScreenCoords => SaveCoords[z.mouseX, viewer.ch-z.mouseY];
z: REF CHARACTER => { InsertChar[z^]; RecordChar[z^] };
z: REF LONG INTEGER => { n ← z^; RecordInt[n] };
z: Rope.ROPE => { InsertRope[z]; RecordRef[z] };
z: REF TEXT => { InsertRope[Rope.FromRefText[z]]; RecordRef[z] };
ENDCASE => MessageWindow.Append["Unknown input given to Tioga.", TRUE];
ENDLOOP;
IF increaseNestingCount AND DecrementNesting[] AND closeEvent THEN CloseEventNow[];
};
END;
interpreterNesting: PUBLIC INTEGER ← 0;
NumberToLook: PROC RETURNS [l: CHARACTER] = INLINE BEGIN
-- maps global value in n to => ['a..'z];
RETURN['a+n];
END;
editObject, textEditObject: EditObjectInfo;
EditObjectInfo: TYPE = REF SecondarySelectionCommandRecord;
SecondarySelectionCommandRecord: TYPE = RECORD [
name: ATOM, -- this is the name that goes in the TIP table; like EditText, EditLooks, ...
proc: PROC [dir: EditDirection], -- this is the procedure that will be called to do the work
toprimary, tosecondary, toboth: Rope.ROPE -- these are messages to be displayed in the MessageWindow
];
secondarySelectionCommandTable: RefTab.Ref ← RefTab.Create[mod: 8];
RegisterSecondarySelectionCommand: PUBLIC PROC [
name: ATOM, -- this is the name that goes in the TIP table; like EditText, EditLooks, ...
proc: PROC [dir: EditDirection], -- this is the procedure that will be called to do the work
toprimary, tosecondary, toboth: Rope.ROPE -- these are messages to be displayed in the MessageWindow
] = {
r: REF SecondarySelectionCommandRecord;
r ← NEW[SecondarySelectionCommandRecord ← [name, proc, toprimary, tosecondary, toboth]];
Register[name, SecondarySelectionCommand];
[] ← RefTab.Store[secondarySelectionCommandTable, name, r];
IF name=$EditText THEN textEditObject ← r };
UnRegisterSecondarySelectionCommand: PUBLIC PROC [name: ATOM] = {
[] ← RefTab.Delete[secondarySelectionCommandTable, name];
UnRegister[name, SecondarySelectionCommand] };
SecondarySelectionCommand: CommandProc = {
p: REF = RefTab.Fetch[secondarySelectionCommandTable,interpAtom].val;
r: REF SecondarySelectionCommandRecord = NARROW[p];
IF r=NIL THEN ERROR;
editObject ← r;
EditMessage[];
RETURN [FALSE] };
-- ***** Command Procs *****
ApplyCaretLook: CommandProc = {
TiogaInputOps.ModifyCaretLook[NumberToLook[], add] };
ApplyLook: CommandProc = {
TiogaInputOps.ModifyLook[NumberToLook[], add] };
ClearCaretLooks: CommandProc = {
TiogaInputOps.ChangeCaretLooks[add: TiogaLooks.noLooks, remove: TiogaLooks.allLooks] };
ClearLooks: CommandProc = {
TiogaInputOps.ChangeLooks[add: TiogaLooks.noLooks, remove: TiogaLooks.allLooks] };
BackSpace: CommandProc = {
TiogaInputOps.BackSpace[n] };
BackWord: CommandProc = {
TiogaInputOps.BackWord[n] };
DeleteNextChar: CommandProc = {
TiogaInputOps.DeleteNextChar[n] };
DeleteNextWord: CommandProc = {
TiogaInputOps.DeleteNextWord[n] };
GoToPreviousWord: CommandProc = {
TiogaInputOps.GoToPreviousWord[n] };
GoToNextWord: CommandProc = {
TiogaInputOps.GoToNextWord[n] };
GoToPreviousChar: CommandProc = {
TiogaInputOps.GoToPreviousChar[n] };
GoToNextChar: CommandProc = {
TiogaInputOps.GoToNextChar[n] };
GoToPreviousNode: CommandProc = {
TiogaInputOps.GoToPreviousNode[n] };
GoToNextNode: CommandProc = {
TiogaInputOps.GoToNextNode[n] };
Copy: CommandProc = { IF sSel.viewer#NIL THEN {
TiogaInputOps.Copy[sel];
RecordRef[$GetSecondary] }};
Delete: CommandProc = {
TiogaInputOps.Delete[TRUE] };
ExpandAbbrev: CommandProc = {
TiogaInputOps.ExpandAbbreviation[] };
Move: CommandProc = { IF sSel.viewer#NIL THEN {
TiogaInputOps.Move[sel];
RecordRef[$GetSecondary] }};
RemoveCaretLook: CommandProc = {
TiogaInputOps.ModifyCaretLook[NumberToLook[], remove] };
RemoveLook: CommandProc = {
TiogaInputOps.ModifyLook[NumberToLook[], remove] };
SetStyle: CommandProc = {
TiogaInputOps.SetStyle[] };
Time: CommandProc = { TiogaInputOps.InsertTime[] };
Split: CommandProc = { TiogaSplit.Split[viewer]; RETURN[FALSE] };
Transpose: CommandProc = { IF sSel.viewer#NIL THEN {
TiogaInputOps.Transpose[sel];
RecordRef[$GetSecondary] }};
ToBoth: CommandProc = {
IF editState=reset OR editState=tolimbo THEN { editState ← toboth; EditMessage[] };
RETURN [FALSE] };
ToLimbo: CommandProc = { IF editState=reset THEN editState ← tolimbo; RETURN [FALSE] };
ToPrimary: CommandProc = {
IF editState=reset OR editState=tolimbo THEN editState ← toprimary;
RETURN [FALSE] };
ToSecondary: CommandProc = {
IF editState=reset OR editState=tolimbo THEN { editState ← tosecondary; EditMessage[] };
RETURN [FALSE] };
EditReset: CommandProc = {
editState ← reset; editObject ← textEditObject; selState ← reset; pdelState ← reset; RETURN [FALSE] };
EditAbort: CommandProc = {
IF viewer#NIL AND pSel.viewer=viewer AND pSel.granularity=point
AND sSel.viewer=NIL THEN
ViewerOps.AddProp[viewer, $Abort, NEW[BOOLFALSE]];
MessageWindow.Append["Cancelled",TRUE];
MakeSelection[NIL,secondary];
MakeSelection[IF CheckSelection[prevPSel] THEN prevPSel ELSE NIL, primary];
editState ← abort; editObject ← textEditObject;
mouseColor ← dead; -- stop tracking the mouse
RETURN [FALSE] };
EditText: PROC [dir: EditDirection] = {
SELECT dir FROM
toprimary => TiogaInputOps.Copy[primary];
tosecondary => TiogaInputOps.Copy[secondary];
toboth => TiogaInputOps.Transpose[];
ENDCASE => ERROR };
EditLooks: PROC [dir: EditDirection] = {
SELECT dir FROM
toprimary => TiogaInputOps.CopyLooks[primary];
tosecondary => TiogaInputOps.CopyLooks[secondary];
toboth => TiogaInputOps.TransposeLooks[];
ENDCASE => ERROR };
EditFormat: PROC [dir: EditDirection] = {
SELECT dir FROM
toprimary => TiogaInputOps.CopyFormat[primary];
tosecondary => TiogaInputOps.CopyFormat[secondary];
toboth => TiogaInputOps.TransposeFormat[];
ENDCASE => ERROR };
GetSecondary: CommandProc = {
IF sSel.viewer=NIL AND CheckSelection[oldSel] THEN FakeSecondary[oldSel];
RETURN [FALSE] };
UpdateSavedSelections: PROC [
node: TiogaNode.RefTextNode,
new: PROC [old: TiogaNode.Offset] RETURNS [TiogaNode.Offset]] = {
Check: PROC [loc: TiogaNode.Location] RETURNS [TiogaNode.Location] = {
IF loc.node # node THEN RETURN [loc];
RETURN [[loc.node, new[loc.where]]] };
-- oldSel is saved version of sSel for use in Repeat
oldSel.start.pos ← Check[oldSel.start.pos];
oldSel.end.pos ← Check[oldSel.end.pos];
-- savedSelA is saved by SaveSelectionA and restored by RestoreSelectionA
savedSelA.start.pos ← Check[savedSelA.start.pos];
savedSelA.end.pos ← Check[savedSelA.end.pos];
-- savedSelB is saved by SaveSelectionB and restored by RestoreSelectionB
savedSelB.start.pos ← Check[savedSelB.start.pos];
savedSelB.end.pos ← Check[savedSelB.end.pos];
-- fSel is saved feedback selection
fSel.start.pos ← Check[fSel.start.pos];
fSel.end.pos ← Check[fSel.end.pos];
};
CheckSelection: PUBLIC PROC [sel: TiogaDocument.Selection] RETURNS [BOOLEAN] = {
root, first, last: TiogaNode.Ref;
t1, t2: TiogaNode.RefTextNode;
tdd: TiogaDocument.TiogaDocumentData;
IF sel=NIL THEN RETURN [FALSE];
IF sel.viewer=NIL OR sel.viewer.destroyed THEN GOTO Failed;
IF (first ← sel.start.pos.node)=NIL OR (last ← sel.end.pos.node)=NIL THEN GOTO Failed;
IF (tdd ← NARROW[sel.viewer.data])=NIL THEN GOTO Failed;
IF (root ← tdd.text)=NIL THEN GOTO Failed;
IF TiogaNodeOps.Root[first] # root THEN GOTO Failed; -- make sure still in the tree
IF first # last THEN -- make sure nodes in same tree and right order
IF EditSpan.CompareNodeOrder[first,last] # before THEN GOTO Failed;
IF sel.start.pos.where # TiogaNode.NodeItself THEN -- make sure start index is ok
IF (t1 ← TiogaNodeOps.NarrowToTextNode[first])=NIL OR
sel.start.pos.where NOT IN [0..TextEdit.Size[t1]] THEN GOTO Failed;
IF sel.end.pos.where # TiogaNode.NodeItself THEN -- make sure end index is ok
IF (t2 ← TiogaNodeOps.NarrowToTextNode[last])=NIL OR
sel.end.pos.where NOT IN [0..TextEdit.Size[t2]] THEN GOTO Failed;
IF t1 # NIL AND t1 = t2 THEN -- make sure start is not after end
IF sel.start.pos.where > sel.end.pos.where THEN GOTO Failed;
RETURN [TRUE];
EXITS Failed => { sel.viewer ← NIL; RETURN [FALSE] };
};
MakePDel: CommandProc = {
pSel.pendingDelete ← TRUE; RETURN [FALSE] };
DoEdit: CommandProc = {
IF pSel.viewer = NIL THEN {
IF sSel.viewer # NIL THEN MakeSelection[NIL,secondary]; -- get rid of secondary
recordAtom ← FALSE }
ELSE IF editState = tolimbo THEN {
recordAtom ← FALSE; RecordRef[$Delete]; TiogaInputOps.Delete[TRUE] }
ELSE IF sSel.viewer = NIL THEN recordAtom ← FALSE
ELSE {
recordAtom ← TRUE;
SELECT editState FROM
reset, abort => recordAtom ← FALSE;
toprimary => {
RecordRef[$GetSecondary];
RecordRef[$ToPrimary];
RecordRef[editObject.name];
IF editObject.name = $EditText AND pSel.pendingDelete THEN RecordRef[$MakePDel];
editObject.proc[toprimary] };
tosecondary => {
RecordRef[$GetSecondary];
RecordRef[$ToSecondary];
RecordRef[editObject.name];
IF editObject.name = $EditText AND pSel.pendingDelete THEN RecordRef[$MakePDel];
editObject.proc[tosecondary] };
toboth => {
RecordRef[$GetSecondary];
RecordRef[$ToBoth];
RecordRef[editObject.name];
editObject.proc[toboth] };
ENDCASE => ERROR };
editState ← reset; editObject ← textEditObject;
pdelState ← reset; pDel ← FALSE; selState ← reset; sel ← primary;
mouseColor ← red; -- put these back to normal
IF editMessage # NIL THEN MessageWindow.Clear[];
editMessage ← NIL };
NormalizeViewer: PROC [
viewer: ViewerClasses.Viewer, loc: TiogaNode.Location,
tdd: TiogaDocument.TiogaDocumentData, tSel: TiogaDocument.Selection] = {
IF loc.node = NIL OR tdd.text # TiogaNodeOps.Root[loc.node] THEN -- scroll to start of document
loc ← [TiogaNodeOps.BranchChild[tdd.text],0];
TiogaOps.RememberCurrentPosition[viewer];
TiogaScrolling.ScrollToPosition[viewer, loc] };
NormalizeToStart: PUBLIC CommandProc = {
DoIt: PROC [tdd: TiogaDocument.TiogaDocumentData, tSel: TiogaDocument.Selection] = {
NormalizeViewer[viewer, IF tSel.viewer=NIL THEN [NIL,0] ELSE tSel.start.pos, tdd, tSel] };
TiogaSelection.CallWithSelAndDocAndTddLocks[viewer, primary, DoIt] };
NormalizeToCaret, Normalize: PUBLIC CommandProc = {
DoIt: PROC [tdd: TiogaDocument.TiogaDocumentData, tSel: TiogaDocument.Selection] = {
NormalizeViewer[viewer,
IF tSel.viewer=NIL THEN [NIL,0] ELSE InsertionPoint[tSel], tdd, tSel] };
TiogaSelection.CallWithSelAndDocAndTddLocks[viewer, primary, DoIt] };
NormalizeToEnd: PUBLIC CommandProc = {
DoIt: PROC [tdd: TiogaDocument.TiogaDocumentData, tSel: TiogaDocument.Selection] = {
NormalizeViewer[viewer, IF tSel.viewer=NIL THEN [NIL,0] ELSE tSel.end.pos, tdd, tSel] };
TiogaSelection.CallWithSelAndDocAndTddLocks[viewer, primary, DoIt] };
FindNext: CommandProc = {
Find[viewer,forwards]; CloseEvent[]; RETURN [FALSE] };
FindAny: CommandProc = {
Find[viewer,anywhere]; CloseEvent[]; RETURN [FALSE] };
FindPrev: CommandProc = {
Find[viewer,backwards]; CloseEvent[]; RETURN [FALSE] };
FindNextWord: CommandProc = {
Find[viewer,forwards,FALSE,TRUE]; CloseEvent[]; RETURN [FALSE] };
FindAnyWord: CommandProc = {
Find[viewer,anywhere,FALSE,TRUE]; CloseEvent[]; RETURN [FALSE] };
FindPrevWord: CommandProc = {
Find[viewer,backwards,FALSE,TRUE]; CloseEvent[]; RETURN [FALSE] };
FindNextDef: CommandProc = {
Find[viewer,forwards,TRUE,TRUE]; CloseEvent[]; RETURN [FALSE] };
FindAnyDef: CommandProc = {
Find[viewer,anywhere,TRUE,TRUE]; CloseEvent[]; RETURN [FALSE] };
FindPrevDef: CommandProc = {
Find[viewer,backwards,TRUE,TRUE]; CloseEvent[]; RETURN [FALSE] };
savedSelA: TiogaDocument.Selection ← TiogaSelection.Create[];
savedSelB: TiogaDocument.Selection ← TiogaSelection.Create[];
RestoreSelectionA: PUBLIC CommandProc = {
IF CheckSelection[savedSelA] THEN MakeSelection[selection: primary, new: savedSelA] };
SaveSelectionA: PUBLIC CommandProc = {
IF pSel # NIL THEN TiogaSelection.Copy[source: pSel, dest: savedSelA] };
RestoreSelectionB: PUBLIC CommandProc = {
IF CheckSelection[savedSelB] THEN MakeSelection[selection: primary, new: savedSelB] };
SaveSelectionB: PUBLIC CommandProc = {
IF pSel # NIL THEN TiogaSelection.Copy[source: pSel, dest: savedSelB] };
PositionCommand: CommandProc = { CloseEvent[]; Position[viewer]; RETURN [FALSE] };
MouseColor: TYPE = { red, yellow, blue, dead };
mouseColor: MouseColor ← red;
BadMouse: PUBLIC SIGNAL = CODE;
RedMouse: CommandProc = {
IF mouseColor = dead THEN SIGNAL BadMouse;
mouseColor ← red;
TiogaSelection.Copy[source: pSel, dest: prevPSel];
RETURN [FALSE] };
YellowMouse: CommandProc = {
IF mouseColor = dead THEN SIGNAL BadMouse;
mouseColor ← yellow;
TiogaSelection.Copy[source: pSel, dest: prevPSel];
RETURN [FALSE] };
BlueMouse: CommandProc = {
IF mouseColor = dead THEN SIGNAL BadMouse;
mouseColor ← blue;
TiogaSelection.Copy[source: pSel, dest: prevPSel];
RETURN [FALSE] };
RedDown: CommandProc = {
IF mouseColor # red THEN SIGNAL BadMouse; RETURN [FALSE] };
YellowDown: CommandProc = {
IF mouseColor # yellow THEN SIGNAL BadMouse; RETURN [FALSE] };
BlueDown: CommandProc = {
IF mouseColor # blue THEN SIGNAL BadMouse; RETURN [FALSE] };
AbortSecondary: PROC = {
MessageWindow.Append["Make a primary selection first.",TRUE];
MessageWindow.Blink[];
editState ← abort; mouseColor ← dead };
SelBranch: CommandProc = {
tdd: TiogaDocument.TiogaDocumentData ~ NARROW[viewer.data];
IF tdd = NIL THEN RETURN;
interpreterNesting ← 0;
IF editState=abort THEN RETURN;
IF sel=secondary AND pSel.viewer = NIL THEN { AbortSecondary[]; RETURN };
TiogaSelection.SelectBranch[viewer, tdd, mx, my, sel, pDel];
IF editState=tolimbo OR sel=secondary THEN EditMessage[];
IF sel=primary THEN CloseEvent[];
RETURN [FALSE] };
SelChar: CommandProc = {
tdd: TiogaDocument.TiogaDocumentData ~ NARROW[viewer.data];
IF tdd = NIL THEN RETURN;
interpreterNesting ← 0;
IF editState=abort THEN RETURN;
IF sel=secondary AND pSel.viewer = NIL THEN { AbortSecondary[]; RETURN };
TiogaSelection.SelectChar[viewer, tdd, mx, my, sel, pDel];
IF editState=tolimbo OR sel=secondary THEN EditMessage[];
IF sel=primary THEN CloseEvent[];
RETURN [FALSE] };
SelExpand: CommandProc = {
changeLevel ← expand; IF sel=primary THEN CloseEvent[]; RETURN [FALSE] };
SelExtend: CommandProc = { Extend[viewer, FALSE]; RETURN [FALSE] };
SelStartExtend: CommandProc = { Extend[viewer, TRUE]; RETURN [FALSE] };
Extend: PROC [viewer: ViewerClasses.Viewer, saveEnds: BOOL] = {
tdd: TiogaDocument.TiogaDocumentData ~ NARROW[viewer.data];
IF tdd = NIL THEN RETURN;
interpreterNesting ← 0;
IF editState=abort THEN RETURN;
IF mouseColor # blue THEN { [] ← BlueMouse[]; saveEnds ← TRUE };
TiogaSelection.Extend[viewer,tdd,mx,my,sel,pDel,changeLevel,saveEnds];
IF sel=secondary THEN EditMessage[]
ELSE IF sel=primary THEN CloseEvent[] };
SelNode: CommandProc = {
tdd: TiogaDocument.TiogaDocumentData ~ NARROW[viewer.data];
IF tdd = NIL THEN RETURN;
interpreterNesting ← 0;
IF editState=abort THEN RETURN;
IF sel=secondary AND pSel.viewer = NIL THEN { AbortSecondary[]; RETURN };
SelectNode[viewer, tdd, mx, my, sel, pDel];
IF editState=tolimbo OR sel=secondary THEN EditMessage[];
IF sel=primary THEN CloseEvent[];
RETURN [FALSE] };
SelNotPendDel: CommandProc = {
IF pdelState=reset THEN {
pdelState ← not; pDel ← FALSE;
IF sel=primary THEN CloseEvent[] };
RETURN [FALSE] };
SelPendDel: CommandProc = {
IF pdelState=reset THEN {
pdelState ← pending; pDel ← TRUE;
IF sel=primary THEN CloseEvent[] };
RETURN [FALSE] };
ForceSelPendDel: CommandProc = { -- force pending delete
pdelState ← reset; [] ← SelPendDel[]; RETURN [FALSE] };
ForceSelNotPendDel: CommandProc = { -- force not pending delete
pdelState ← reset; [] ← SelNotPendDel[]; RETURN [FALSE] };
SelSamePendDel: CommandProc = {
IF sel=primary THEN CloseEvent[]; RETURN [FALSE] };
SelPrimary: CommandProc = {
IF selState=reset THEN { selState ← primary; sel ← primary; CloseEvent[] };
RETURN [FALSE] };
SelReduce: CommandProc = {
changeLevel ← reduce; IF sel=primary THEN CloseEvent[]; RETURN [FALSE] };
SelSame: CommandProc = { -- this is no longer needed. delete it after release new TIP tables
};
SelSameEnd: CommandProc = { -- get rid of this when change Tioga.Tip
RETURN [FALSE] };
SelSecondary: CommandProc = {
IF selState=reset THEN { selState ← secondary; sel ← secondary };
RETURN [FALSE] };
SelUpdate: CommandProc = {
tdd: TiogaDocument.TiogaDocumentData ~ NARROW[viewer.data];
IF tdd = NIL THEN RETURN;
IF editState=abort THEN RETURN;
IF sel=secondary AND pSel.viewer = NIL THEN { AbortSecondary[]; RETURN };
Update[viewer, tdd, mx, my, sel, pDel];
IF sel=secondary THEN EditMessage[];
IF sel=primary THEN CloseEvent[];
RETURN [FALSE] };
SelWord: CommandProc = {
tdd: TiogaDocument.TiogaDocumentData ~ NARROW[viewer.data];
IF tdd = NIL THEN RETURN;
interpreterNesting ← 0;
IF editState=abort THEN RETURN;
IF sel=secondary AND pSel.viewer = NIL THEN { AbortSecondary[]; RETURN };
SelectWord[viewer, tdd, mx, my, sel, pDel];
IF editState=tolimbo OR sel=secondary THEN EditMessage[];
IF sel=primary THEN CloseEvent[];
RETURN [FALSE] };
IntermediateUser: CommandProc = {
CheckUser[intermediate]; RETURN [FALSE] };
AdvancedUser: CommandProc = {
CheckUser[advanced]; RETURN [FALSE] };
ExpertUser: CommandProc = {
CheckUser[expert]; RETURN [FALSE] };
DontDoIt: PUBLIC SIGNAL = CODE; -- raised if user category is too low
CheckUser: PROC [category: TiogaProfile.CategoryOfUser] = {
IF TiogaProfile.userCategory < category THEN SIGNAL DontDoIt };
Register: PUBLIC ENTRY PROC [name: ATOM, proc: CommandProc, before: BOOLTRUE] = {
ENABLE UNWIND => NULL;
p: REF ANY = RefTab.Fetch[commandTable,name].val;
list: LIST OF CommandProc ← NARROW[p];
IF before OR list=NIL THEN list ← CONS[proc,list]
ELSE FOR l: LIST OF CommandProc ← list, l.rest DO
IF l.rest=NIL THEN { l.rest ← LIST[proc]; EXIT };
ENDLOOP;
[] ← RefTab.Store[commandTable,name,list] };
UnRegister: PUBLIC ENTRY PROC [name: ATOM, proc: CommandProc] = {
ENABLE UNWIND => NULL;
p: REF ANY = RefTab.Fetch[commandTable,name].val;
procList: LIST OF CommandProc ← NARROW[p];
IF procList=NIL THEN NULL
ELSE IF procList.first = proc THEN procList ← procList.rest
ELSE {
prev: LIST OF CommandProc ← procList;
FOR list: LIST OF CommandProc ← procList.rest, list.rest UNTIL list=NIL DO
IF list.first=proc THEN { prev.rest ← list.rest; RETURN };
prev ← list;
ENDLOOP };
IF procList=NIL THEN [] ← RefTab.Delete[commandTable,name]
ELSE IF procList # p THEN [] ← RefTab.Store[commandTable,name,procList] };
IsRegistered: PUBLIC ENTRY PROC [name: ATOM, proc: CommandProc] RETURNS [BOOLEAN] = {
ENABLE UNWIND => NULL;
p: REF ANY = RefTab.Fetch[commandTable,name].val;
procList: LIST OF CommandProc ← NARROW[p];
FOR l: LIST OF CommandProc ← procList, l.rest UNTIL l=NIL DO
IF l.first=proc THEN RETURN[TRUE]; ENDLOOP;
RETURN [FALSE] };
RegisterCommandAtoms: PROC = {
Register[$ApplyCaretLook, ApplyCaretLook];
Register[$ApplyLook, ApplyLook];
Register[$ClearCaretLooks, ClearCaretLooks];
Register[$ClearLooks, ClearLooks];
Register[$BackSpace, BackSpace];
Register[$BackWord, BackWord];
Register[$DeleteNextChar, DeleteNextChar];
Register[$DeleteNextWord, DeleteNextWord];
Register[$GoToPreviousWord, GoToPreviousWord];
Register[$GoToNextWord, GoToNextWord];
Register[$GoToPreviousChar, GoToPreviousChar];
Register[$GoToNextChar, GoToNextChar];
Register[$GoToPreviousNode, GoToPreviousNode];
Register[$GoToNextNode, GoToNextNode];
Register[$Copy, Copy];
Register[$Delete, Delete];
Register[$DoEdit, DoEdit];
Register[$ExpandAbbrev, ExpandAbbrev];
Register[$Move, Move];
Register[$NormalizeToStart, NormalizeToStart];
Register[$NormalizeToCaret, NormalizeToCaret];
Register[$NormalizeToEnd, NormalizeToEnd];
Register[$RemoveCaretLook, RemoveCaretLook];
Register[$RemoveLook, RemoveLook];
Register[$SetStyle, SetStyle];
Register[$Time, Time];
Register[$RedSplit, Split]; Register[$YellowSplit, Split]; Register[$BlueSplit, Split];
Register[$Transpose, Transpose];
Register[$ToBoth, ToBoth];
Register[$ToLimbo, ToLimbo];
Register[$ToPrimary, ToPrimary];
Register[$ToSecondary, ToSecondary];
Register[$EditReset, EditReset];
Register[$EditAbort, EditAbort];
Register[$GetSecondary, GetSecondary];
Register[$MakePDel, MakePDel];
Register[$FindNext, FindNext];
Register[$FindAny, FindAny];
Register[$FindPrev, FindPrev];
Register[$FindNextDef, FindNextDef];
Register[$FindAnyDef, FindAnyDef];
Register[$FindPrevDef, FindPrevDef];
Register[$FindNextWord, FindNextWord];
Register[$FindAnyWord, FindAnyWord];
Register[$FindPrevWord, FindPrevWord];
Register[$PushSelection, SaveSelectionA];
Register[$PopSelection, RestoreSelectionA];
Register[$SaveSelection, SaveSelectionA];
Register[$RestoreSelection, RestoreSelectionA];
Register[$SaveSelectionA, SaveSelectionA];
Register[$RestoreSelectionA, RestoreSelectionA];
Register[$SaveSelectionB, SaveSelectionB];
Register[$RestoreSelectionB, RestoreSelectionB];
Register[$Position, PositionCommand];
Register[$RedMouse, RedMouse];
Register[$YellowMouse, YellowMouse];
Register[$BlueMouse, BlueMouse];
Register[$RedDown, RedDown];
Register[$YellowDown, YellowDown];
Register[$BlueDown, BlueDown];
Register[$SelBranch, SelBranch];
Register[$SelChar, SelChar];
Register[$SelExpand, SelExpand];
Register[$SelExtend, SelExtend];
Register[$SelStartExtend, SelStartExtend];
Register[$SelNode, SelNode];
Register[$SelNotPendDel, SelNotPendDel];
Register[$SelPendDel, SelPendDel];
Register[$ForceSelPendDel, ForceSelPendDel];
Register[$ForceSelNotPendDel, ForceSelNotPendDel];
Register[$SelSamePendDel, SelSamePendDel];
Register[$SelPrimary, SelPrimary];
Register[$SelReduce, SelReduce];
Register[$SelSame, SelSame];
Register[$SelSameEnd, SelSameEnd];
Register[$SelSecondary, SelSecondary];
Register[$SelUpdate, SelUpdate];
Register[$SelWord, SelWord];
Register[$IntermediateUser, IntermediateUser];
Register[$AdvancedUser, AdvancedUser];
Register[$ExpertUser, ExpertUser];
};
toPrimaryMessages[FALSE][FALSE] ← "Select for copy to caret";
toPrimaryMessages[FALSE][TRUE] ← "Select for move to caret";
toPrimaryMessages[TRUE][FALSE] ← "Select replacement";
toPrimaryMessages[TRUE][TRUE] ← "Select for move onto";
toSecondaryMessages[FALSE][FALSE] ← "Select destination for copy";
toSecondaryMessages[FALSE][TRUE] ← "Select for replacement";
toSecondaryMessages[TRUE][FALSE] ← "Select destination for move";
toSecondaryMessages[TRUE][TRUE] ← "Select destination for move onto";
RegisterCommandAtoms;
RegisterSecondarySelectionCommand[$EditText, EditText,
NIL, NIL, "Select for transpose"];
RegisterSecondarySelectionCommand[$EditLooks, EditLooks,
"Select looks to copy", "Select destination for copy looks", "Select for transpose looks"];
RegisterSecondarySelectionCommand[$EditType, EditFormat,
"Select format to copy", "Select destination for copy format", "Select for transpose format"];
RegisterSecondarySelectionCommand[$EditFormat, EditFormat,
"Select format to copy", "Select destination for copy format", "Select for transpose format"];
NodeAddrs.AddNotifyProc[UpdateSavedSelections];
END.