TEditInputImpl.mesa; Edited by Paxton on December 28, 1982 2:21 pm
Last Edited by: Maxwell, January 4, 1983 3:53 pm
Last Edited by: Plass, October 11, 1983 9:53 am
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 [NewZone],
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;
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:
BOOL ←
FALSE;
-- 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: 100, zone: TextNode.pZone];
editMessage: Rope.ROPE ← NIL;
MessageArray: TYPE = ARRAY BOOLEAN OF ARRAY BOOLEAN OF Rope.ROPE;
toPrimaryMessages: REF MessageArray ← NEW [MessageArray];
toSecondaryMessages: REF MessageArray ← NEW [MessageArray];
EditMessage:
PROC = {
msg: Rope.
ROPE ←
SELECT editState
FROM
tolimbo => "Select for delete",
toprimary =>
SELECT editObject
FROM
text => toPrimaryMessages[TEditSelection.pSel.pendingDelete][TEditSelection.sSel.pendingDelete],
looks => "Select looks to copy",
type => "Select format to copy",
ENDCASE => NIL,
tosecondary =>
SELECT editObject
FROM
text => toSecondaryMessages[TEditSelection.pSel.pendingDelete][TEditSelection.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.NewZone[quantized];
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: BOOL ← FALSE;
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: BOOL ← TRUE] =
BEGIN OPEN TEditInputOps;
NormaliseSelection:
PROC =
BEGIN
IF NOT TEditSelection.pSel.pendingDelete THEN RETURN;
TEditSelection.LockSel[primary, "InterpInput"];
{ ENABLE UNWIND => TEditSelection.UnlockSel[primary];
IF TEditSelection.pSel.pendingDelete THEN DoPendingDelete[];
IF NOT InsSel[] THEN TEditSelection.MakePointSelection[TEditSelection.pSel, TEditSelection.InsertionPoint[]];
}; TEditSelection.UnlockSel[primary];
END;
InsSel:
PROC
RETURNS [
BOOLEAN] =
INLINE {
RETURN[TEditSelection.pSel.granularity=point
AND TEditSelection.pSel.insertion=before
AND TEditSelection.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
NOT TEditSelection.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 TEditSelection.sSel.viewer#
NIL
THEN {
TEditInputOps.Copy[sel];
RecordRef[$GetSecondary] }};
Delete: CommandProc = {
TEditInputOps.Delete[TRUE] };
ExpandAbbrev: CommandProc = {
TEditInputOps.ExpandAbbreviation[] };
Move: CommandProc = {
IF TEditSelection.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 TEditSelection.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 TEditSelection.pSel.viewer=viewer
AND TEditSelection.pSel.granularity=point
AND TEditSelection.sSel.viewer=NIL THEN
ViewerOps.AddProp[viewer, $Abort, TextNode.pZone.NEW[BOOL ← FALSE]];
MessageWindow.Append["Cancelled",TRUE];
TEditSelection.MakeSelection[NIL,secondary];
TEditSelection.MakeSelection[IF CheckSelection[prevPSel] THEN prevPSel ELSE NIL, primary];
editState ← abort; editObject ← text;
mouseColor ← dead; -- stop tracking the mouse
RETURN [FALSE] };
GetSecondary: CommandProc = {
IF TEditSelection.sSel.viewer=NIL AND CheckSelection[TEditSelection.oldSel] THEN TEditSelection.FakeSecondary[TEditSelection.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]]] };
-- TEditSelection.oldSel is saved version of TEditSelection.sSel for use in Repeat
TEditSelection.oldSel.start.pos ← Check[TEditSelection.oldSel.start.pos];
TEditSelection.oldSel.end.pos ← Check[TEditSelection.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];
-- TEditSelection.fSel is saved feedback selection
TEditSelection.fSel.start.pos ← Check[TEditSelection.fSel.start.pos];
TEditSelection.fSel.end.pos ← Check[TEditSelection.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 = {
TEditSelection.pSel.pendingDelete ← TRUE; RETURN [FALSE] };
DoEdit: CommandProc = {
IF TEditSelection.pSel.viewer =
NIL
THEN {
IF TEditSelection.sSel.viewer # NIL THEN TEditSelection.MakeSelection[NIL,secondary]; -- get rid of secondary
recordAtom ← FALSE }
ELSE
IF editState = tolimbo
THEN {
recordAtom ← FALSE; RecordRef[$Delete]; TEditInputOps.Delete[TRUE] }
ELSE IF TEditSelection.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 TEditSelection.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 TEditSelection.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 TEditSelection.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 = {
TEditSelection.Find[viewer,forwards]; CloseEvent[]; RETURN [FALSE] };
FindAny: CommandProc = {
TEditSelection.Find[viewer,anywhere]; CloseEvent[]; RETURN [FALSE] };
FindPrev: CommandProc = {
TEditSelection.Find[viewer,backwards]; CloseEvent[]; RETURN [FALSE] };
FindNextWord: CommandProc = {
TEditSelection.Find[viewer,forwards,FALSE,TRUE]; CloseEvent[]; RETURN [FALSE] };
FindAnyWord: CommandProc = {
TEditSelection.Find[viewer,anywhere,FALSE,TRUE]; CloseEvent[]; RETURN [FALSE] };
FindPrevWord: CommandProc = {
TEditSelection.Find[viewer,backwards,FALSE,TRUE]; CloseEvent[]; RETURN [FALSE] };
FindNextDef: CommandProc = {
TEditSelection.Find[viewer,forwards,TRUE,TRUE]; CloseEvent[]; RETURN [FALSE] };
FindAnyDef: CommandProc = {
TEditSelection.Find[viewer,anywhere,TRUE,TRUE]; CloseEvent[]; RETURN [FALSE] };
FindPrevDef: CommandProc = {
TEditSelection.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 TEditSelection.MakeSelection[selection: primary, new: savedSelA] };
SaveSelectionA:
PUBLIC CommandProc = {
IF TEditSelection.pSel # NIL THEN TEditSelection.Copy[source: TEditSelection.pSel, dest: savedSelA] };
RestoreSelectionB:
PUBLIC CommandProc = {
IF CheckSelection[savedSelB] THEN TEditSelection.MakeSelection[selection: primary, new: savedSelB] };
SaveSelectionB:
PUBLIC CommandProc = {
IF TEditSelection.pSel # NIL THEN TEditSelection.Copy[source: TEditSelection.pSel, dest: savedSelB] };
PositionCommand: CommandProc = { CloseEvent[]; TEditSelection.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: TEditSelection.pSel, dest: prevPSel];
RETURN [FALSE] };
YellowMouse: CommandProc = {
IF mouseColor = dead THEN SIGNAL BadMouse;
mouseColor ← yellow;
TEditSelection.Copy[source: TEditSelection.pSel, dest: prevPSel];
RETURN [FALSE] };
BlueMouse: CommandProc = {
IF mouseColor = dead THEN SIGNAL BadMouse;
mouseColor ← blue;
TEditSelection.Copy[source: TEditSelection.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 TEditSelection.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 TEditSelection.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 TEditSelection.pSel.viewer = NIL THEN { AbortSecondary[]; RETURN };
TEditSelection.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 TEditSelection.pSel.viewer = NIL THEN { AbortSecondary[]; RETURN };
TEditSelection.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 TEditSelection.pSel.viewer = NIL THEN { AbortSecondary[]; RETURN };
TEditSelection.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:
BOOL ←
TRUE] = {
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.