TEditInputImpl.mesa
Paxton on December 28, 1982 2:21 pm
Maxwell, January 4, 1983 3:53 pm
Plass, April 15, 1983 2:03 pm
Russ Atkinson, July 25, 1983 7:02 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],
SafeStorage USING [GetSystemZone],
TEditDocument USING [TEditDocumentData, Selection, SelectionId, SelectionRec],
TEditHistory,
TEditImpl,
TEditInput,
TEditInputOps, -- USING Lots
TEditOps USING [RememberCurrentPosition],
TEditProfile USING [CategoryOfUser, userCategory],
TEditScrolling USING [ScrollToPosition],
TEditSelection USING
[CallWithSelAndDocAndTddLocks, Copy, Create, Extend, FakeSecondary, Find, InsertionPoint, LevelChange, LockSel, MakePointSelection, MakeSelection, oldSel, Position, fSel, pSel, SelectBranch, SelectChar, SelectNode, SelectWord, sSel, UnlockSel, Update],
TEditSplit USING [Split],
TextEdit USING [Size],
TextLooks USING [Look, allLooks, noLooks],
TextNode USING
[FirstChild, Location, NarrowToTextNode, NodeItself, Offset, pZone, Ref, RefTextNode, Root],
TiogaOps,
TIPUser USING [TIPScreenCoords],
ViewerClasses USING [NotifyProc, Viewer, ViewerRec],
ViewerOps USING [AddProp];
TEditInputImpl: CEDAR MONITOR
IMPORTS
Atom, NodeAddrs, RefTab, EditSpan, MessageWindow, Rope, SafeStorage, TEditInput, TEditInputOps, TEditOps, TEditProfile, TEditScrolling, TEditSelection, TEditSplit, TextEdit, TextNode, ViewerOps
EXPORTS TEditInput, TEditImpl, TiogaOps =
BEGIN OPEN TEditInput, TEditSelection;
mx, my: INTEGER; -- global Coord param for ops below
n: LONG INTEGER; -- global Numeric param for ops below
sel: TEditDocument.SelectionId ← primary;  -- global sel ID; can be set to "secondary" by $SelSecondary
changeLevel: TEditSelection.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;
editObject: EditObject ← text;
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: 101];
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 FROM
text => toPrimaryMessages[pSel.pendingDelete][sSel.pendingDelete],
looks => "Select looks to copy",
type => "Select format to copy",
ENDCASE => NIL,
tosecondary => SELECT editObject FROM
text => toSecondaryMessages[pSel.pendingDelete][sSel.pendingDelete],
looks => "Select destination for copy looks",
type => "Select destination for copy format",
ENDCASE => NIL,
toboth => SELECT editObject FROM
text => "Select for transpose",
looks => "Select for transpose looks",
type => "Select for transpose format",
ENDCASE => NIL,
ENDCASE => NIL;
IF msg = NIL OR msg = editMessage THEN RETURN;
MessageWindow.Append[msg,TRUE];
editMessage ← msg };
prevPSel: TEditDocument.Selection ← TextNode.pZone.NEW[TEditDocument.SelectionRec];
-- for EditAbort
qZone: ZONE ← SafeStorage.GetSystemZone[];
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] };
TEditNotifyProc: PUBLIC ViewerClasses.NotifyProc = BEGIN
InterpInput[self,input];
END;
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;
TEditInputOps.WaitForInsertToFinish[]; -- make sure previous characters have gone in
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 TEditInputOps;
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;
-- ***** Command Procs *****
ApplyCaretLook: CommandProc = {
TEditInputOps.ModifyCaretLook[NumberToLook[], add] };
ApplyLook: CommandProc = {
TEditInputOps.ModifyLook[NumberToLook[], add] };
ClearCaretLooks: CommandProc = {
TEditInputOps.ChangeCaretLooks[add: TextLooks.noLooks, remove: TextLooks.allLooks] };
ClearLooks: CommandProc = {
TEditInputOps.ChangeLooks[add: TextLooks.noLooks, remove: TextLooks.allLooks] };
BackSpace: CommandProc = {
TEditInputOps.BackSpace[n] };
BackWord: CommandProc = {
TEditInputOps.BackWord[n] };
DeleteNextChar: CommandProc = {
TEditInputOps.DeleteNextChar[n] };
DeleteNextWord: CommandProc = {
TEditInputOps.DeleteNextWord[n] };
GoToPreviousWord: CommandProc = {
TEditInputOps.GoToPreviousWord[n] };
GoToNextWord: CommandProc = {
TEditInputOps.GoToNextWord[n] };
GoToPreviousChar: CommandProc = {
TEditInputOps.GoToPreviousChar[n] };
GoToNextChar: CommandProc = {
TEditInputOps.GoToNextChar[n] };
GoToPreviousNode: CommandProc = {
TEditInputOps.GoToPreviousNode[n] };
GoToNextNode: CommandProc = {
TEditInputOps.GoToNextNode[n] };
Copy: CommandProc = { IF sSel.viewer#NIL THEN {
TEditInputOps.Copy[sel];
RecordRef[$GetSecondary] }};
Delete: CommandProc = {
TEditInputOps.Delete[TRUE] };
ExpandAbbrev: CommandProc = {
TEditInputOps.ExpandAbbreviation[] };
Move: CommandProc = { IF sSel.viewer#NIL THEN {
TEditInputOps.Move[sel];
RecordRef[$GetSecondary] }};
RemoveCaretLook: CommandProc = {
TEditInputOps.ModifyCaretLook[NumberToLook[], remove] };
RemoveLook: CommandProc = {
TEditInputOps.ModifyLook[NumberToLook[], remove] };
SetStyle: CommandProc = {
TEditInputOps.SetStyle[] };
Time: CommandProc = { TEditInputOps.InsertTime[] };
Split: CommandProc = { TEditSplit.Split[viewer]; RETURN[FALSE] };
Transpose: CommandProc = { IF sSel.viewer#NIL THEN {
TEditInputOps.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] };
EditText: CommandProc = {
editObject ← text; RETURN [FALSE] };
EditLooks: CommandProc = {
editObject ← looks; EditMessage[]; RETURN [FALSE] };
EditType: CommandProc = {
editObject ← type; EditMessage[]; RETURN [FALSE] };
EditReset: CommandProc = {
editState ← reset; editObject ← text; 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, TextNode.pZone.NEW[BOOLFALSE]];
MessageWindow.Append["Cancelled",TRUE];
MakeSelection[NIL,secondary];
MakeSelection[IF CheckSelection[prevPSel] THEN prevPSel ELSE NIL, primary];
editState ← abort; editObject ← text;
mouseColor ← dead; -- stop tracking the mouse
RETURN [FALSE] };
GetSecondary: CommandProc = {
IF sSel.viewer=NIL AND CheckSelection[oldSel] THEN FakeSecondary[oldSel];
RETURN [FALSE] };
UpdateSavedSelections: PROC [
node: TextNode.RefTextNode,
new: PROC [old: TextNode.Offset] RETURNS [TextNode.Offset]] = {
Check: PROC [loc: TextNode.Location] RETURNS [TextNode.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: TEditDocument.Selection] RETURNS [BOOLEAN] = {
root, first, last: TextNode.Ref;
t1, t2: TextNode.RefTextNode;
tdd: TEditDocument.TEditDocumentData;
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 TextNode.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 # TextNode.NodeItself THEN -- make sure start index is ok
IF (t1 ← TextNode.NarrowToTextNode[first])=NIL OR
sel.start.pos.where NOT IN [0..TextEdit.Size[t1]] THEN GOTO Failed;
IF sel.end.pos.where # TextNode.NodeItself THEN -- make sure end index is ok
IF (t2 ← TextNode.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]; TEditInputOps.Delete[TRUE] }
ELSE IF sSel.viewer = NIL THEN recordAtom ← FALSE
ELSE {
RecordEditObject: PROC = {
RecordRef[SELECT editObject FROM
text => $EditText,
looks => $EditLooks,
type => $EditType,
ENDCASE => ERROR] };
recordAtom ← TRUE;
SELECT editState FROM
reset, abort => recordAtom ← FALSE;
toprimary => {
RecordRef[$GetSecondary];
RecordRef[$ToPrimary];
RecordEditObject[];
SELECT editObject FROM
text => {
IF pSel.pendingDelete THEN RecordRef[$MakePDel];
TEditInputOps.Copy[primary] };
looks => TEditInputOps.CopyLooks[primary];
type => TEditInputOps.CopyType[primary];
ENDCASE => ERROR };
tosecondary => {
RecordRef[$GetSecondary];
RecordRef[$ToSecondary];
RecordEditObject[];
SELECT editObject FROM
text => {
IF pSel.pendingDelete THEN RecordRef[$MakePDel];
TEditInputOps.Copy[secondary] };
looks => TEditInputOps.CopyLooks[secondary];
type => TEditInputOps.CopyType[secondary];
ENDCASE => ERROR };
toboth => {
RecordRef[$GetSecondary];
RecordRef[$ToBoth];
RecordEditObject[];
SELECT editObject FROM
text => TEditInputOps.Transpose[];
looks => TEditInputOps.TransposeLooks[];
type => TEditInputOps.TransposeType[];
ENDCASE => ERROR };
ENDCASE => ERROR };
editState ← reset; editObject ← text;
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: TextNode.Location,
tdd: TEditDocument.TEditDocumentData, tSel: TEditDocument.Selection] = {
IF loc.node = NIL OR tdd.text # TextNode.Root[loc.node] THEN -- scroll to start of document
loc ← [TextNode.FirstChild[tdd.text],0];
TEditOps.RememberCurrentPosition[viewer];
TEditScrolling.ScrollToPosition[viewer, loc] };
NormalizeToStart: PUBLIC CommandProc = {
DoIt: PROC [tdd: TEditDocument.TEditDocumentData, tSel: TEditDocument.Selection] = {
NormalizeViewer[viewer, IF tSel.viewer=NIL THEN [NIL,0] ELSE tSel.start.pos, tdd, tSel] };
TEditSelection.CallWithSelAndDocAndTddLocks[viewer, primary, DoIt] };
NormalizeToCaret, Normalize: PUBLIC CommandProc = {
DoIt: PROC [tdd: TEditDocument.TEditDocumentData, tSel: TEditDocument.Selection] = {
NormalizeViewer[viewer,
IF tSel.viewer=NIL THEN [NIL,0] ELSE InsertionPoint[tSel], tdd, tSel] };
TEditSelection.CallWithSelAndDocAndTddLocks[viewer, primary, DoIt] };
NormalizeToEnd: PUBLIC CommandProc = {
DoIt: PROC [tdd: TEditDocument.TEditDocumentData, tSel: TEditDocument.Selection] = {
NormalizeViewer[viewer, IF tSel.viewer=NIL THEN [NIL,0] ELSE tSel.end.pos, tdd, tSel] };
TEditSelection.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: TEditDocument.Selection ← TEditSelection.Create[];
savedSelB: TEditDocument.Selection ← TEditSelection.Create[];
RestoreSelectionA: PUBLIC CommandProc = {
IF CheckSelection[savedSelA] THEN MakeSelection[selection: primary, new: savedSelA] };
SaveSelectionA: PUBLIC CommandProc = {
IF pSel # NIL THEN TEditSelection.Copy[source: pSel, dest: savedSelA] };
RestoreSelectionB: PUBLIC CommandProc = {
IF CheckSelection[savedSelB] THEN MakeSelection[selection: primary, new: savedSelB] };
SaveSelectionB: PUBLIC CommandProc = {
IF pSel # NIL THEN TEditSelection.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;
TEditSelection.Copy[source: pSel, dest: prevPSel];
RETURN [FALSE] };
YellowMouse: CommandProc = {
IF mouseColor = dead THEN SIGNAL BadMouse;
mouseColor ← yellow;
TEditSelection.Copy[source: pSel, dest: prevPSel];
RETURN [FALSE] };
BlueMouse: CommandProc = {
IF mouseColor = dead THEN SIGNAL BadMouse;
mouseColor ← blue;
TEditSelection.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: TEditDocument.TEditDocumentData ~ 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 };
TEditSelection.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: TEditDocument.TEditDocumentData ~ 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 };
TEditSelection.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: TEditDocument.TEditDocumentData ~ NARROW[viewer.data];
IF tdd = NIL THEN RETURN;
interpreterNesting ← 0;
IF editState=abort THEN RETURN;
IF mouseColor # blue THEN { [] ← BlueMouse[]; saveEnds ← TRUE };
TEditSelection.Extend[viewer,tdd,mx,my,sel,pDel,changeLevel,saveEnds];
IF sel=secondary THEN EditMessage[]
ELSE IF sel=primary THEN CloseEvent[] };
SelNode: CommandProc = {
tdd: TEditDocument.TEditDocumentData ~ 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: TEditDocument.TEditDocumentData ~ 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: TEditDocument.TEditDocumentData ~ 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: TEditProfile.CategoryOfUser] = {
IF TEditProfile.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 ← TextNode.pZone.CONS[proc,list]
ELSE FOR l: LIST OF CommandProc ← list, l.rest DO
IF l.rest=NIL THEN { l.rest ← TextNode.pZone.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[$EditText, EditText];
Register[$EditType, EditType];
Register[$EditLooks, EditLooks];
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;
NodeAddrs.AddNotifyProc[UpdateSavedSelections];
END.