TEditInputImpl.mesa
Copyright © 1985, 1986 by Xerox Corporation. All rights reserved.
Paxton on December 28, 1982 2:21 pm
Maxwell, January 4, 1983 3:53 pm
Plass, March 29, 1985 3:39:18 pm PST
Russ Atkinson, July 25, 1983 7:02 pm
Doug Wyatt, September 2, 1986 4:13:20 pm PDT
DIRECTORY
Atom USING [GetPName],
EditSpan USING [CompareNodeOrder],
MessageWindow USING [Append, Blink, Clear],
NodeAddrs USING [AddNotifyProc],
RefTab USING [Create, Delete, Fetch, Ref, Store],
Rope USING [Concat, FromRefText, ROPE],
TEditDocument USING [Selection, SelectionId, SelectionRec, TEditDocumentData],
TEditInput USING [CloseEvent, closeEvent, CloseEventNow, CommandProc, EditState, RecordChar, RecordInt, RecordRef],
TEditInputOps USING [BackSpace, BackWord, BufferedInsertChar, BufferedInsertText, ChangeCaretLooks, ChangeLooks, Copy, CopyLooks, CopyFormat, Delete, DeleteNextChar, DeleteNextWord, DoPendingDelete, ExpandAbbreviation, GoToNextChar, GoToNextNode, GoToNextWord, GoToPreviousChar, GoToPreviousNode, GoToPreviousWord, InsertChar, InsertRope, InsertTime, ModifyCaretLook, ModifyLook, Move, SetStyle, Transpose, TransposeLooks, TransposeFormat, WaitForInsertToFinish],
TEditOps USING [RememberCurrentPosition],
TEditPrivate USING [],
TEditProfile USING [CategoryOfUser, userCategory],
TEditScrolling USING [ScrollToPosition],
TEditSelection USING [CallWithSelAndDocAndTddLocks, Copy, Create, Extend, FakeSecondary, Find, fSel, InsertionPoint, LevelChange, LockSel, MakePointSelection, MakeSelection, oldSel, pSel, SelectBranch, SelectChar, SelectNode, SelectWord, ShowPosition, sSel, UnlockSel, Update],
TEditSplit USING [Split],
TextEdit USING [Size],
TextLooks USING [allLooks, Look, noLooks],
TextNode USING [FirstChild, Location, Node, NodeItself, Root],
TiogaOps USING [],
TIPUser USING [TIPScreenCoords],
ViewerClasses USING [NotifyProc, Viewer],
ViewerOps USING [AddProp];
TEditInputImpl:
CEDAR
MONITOR
IMPORTS Atom, NodeAddrs, RefTab, EditSpan, MessageWindow, Rope, TEditInput, TEditInputOps, TEditOps, TEditProfile, TEditScrolling, TEditSelection, TEditSplit, TextEdit, TextNode, ViewerOps
EXPORTS TEditInput, TEditPrivate, 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:
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
format -- operate on the format 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;
interrupt: PUBLIC REF BOOL ← NEW[BOOL ← FALSE];
commandTable: RefTab.Ref ← RefTab.Create[mod: 101];
editMessage: Rope.ROPE ← NIL;
MessageArray: TYPE = ARRAY BOOL OF ARRAY BOOL 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[pSel.pendingDelete][sSel.pendingDelete],
looks => "Select looks to copy",
format => "Select format to copy",
ENDCASE => NIL,
tosecondary =>
SELECT editObject
FROM
text => toSecondaryMessages[pSel.pendingDelete][sSel.pendingDelete],
looks => "Select destination for copy looks",
format => "Select destination for copy format",
ENDCASE => NIL,
toboth =>
SELECT editObject
FROM
text => "Select for transpose",
looks => "Select for transpose looks",
format => "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 ←
NEW[TEditDocument.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] };
TEditNotifyProc:
PUBLIC ViewerClasses.NotifyProc =
BEGIN
InterpInput[self,input];
END;
InterpAtom:
PROC [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
PROC [viewer: ViewerClasses.Viewer, params:
LIST
OF
REF
ANY,
increaseNestingCount: BOOL ← TRUE] =
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 [
BOOL] =
{
RETURN[pSel.granularity=point
AND pSel.insertion=before
AND sSel.viewer=NIL]};
BumpNesting:
ENTRY
PROC = {
IF (interpreterNesting ← interpreterNesting+1) <= 1
THEN {
interpreterNesting ← 1;
closeEvent ← FALSE }};
DecrementNesting:
ENTRY
PROC
RETURNS [
BOOL] = {
RETURN [(interpreterNesting ← interpreterNesting-1) <= 0] };
AllText:
PROC [
LIST
OF
REF
ANY]
RETURNS [
BOOL] = {
FOR input:
LIST
OF
REF
ANY ← params, input.rest
UNTIL input=
NIL
DO
WITH input.first
SELECT
FROM
z: REF CHAR => 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
CHAR => {
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 CHAR => { 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:
CHAR] =
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] };
EditFormat: CommandProc = {
editObject ← format; EditMessage[]; RETURN [FALSE] };
EditReset: CommandProc = {
editState ← reset; editObject ← text; selState ← reset; pdelState ← reset; RETURN [FALSE] };
EditAbort: CommandProc = {
interrupt^ ← TRUE;
IF viewer#
NIL
AND pSel.viewer=viewer
AND pSel.granularity=point
AND sSel.viewer=NIL THEN
ViewerOps.AddProp[viewer, $Abort, NEW[BOOL ← FALSE]];
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.Node,
new: PROC [old: INT] RETURNS [INT]] = {
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 [
BOOL] = {
root, first, last: TextNode.Node;
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 first=NIL OR sel.start.pos.where NOT IN [0..TextEdit.Size[first]] THEN GOTO Failed;
IF sel.end.pos.where # TextNode.NodeItself
THEN
-- make sure end index is ok
IF last=NIL OR sel.end.pos.where NOT IN [0..TextEdit.Size[last]] THEN GOTO Failed;
IF first = last
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,
format => $EditFormat,
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];
format => TEditInputOps.CopyFormat[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];
format => TEditInputOps.CopyFormat[secondary];
ENDCASE => ERROR };
toboth => {
RecordRef[$GetSecondary];
RecordRef[$ToBoth];
RecordEditObject[];
SELECT editObject FROM
text => TEditInputOps.Transpose[];
looks => TEditInputOps.TransposeLooks[];
format => TEditInputOps.TransposeFormat[];
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: viewer, findWhere: forwards];
CloseEvent[]; RETURN [FALSE] };
FindAny: CommandProc = {
Find[viewer: viewer, findWhere: anywhere];
CloseEvent[]; RETURN [FALSE] };
FindPrev: CommandProc = {
Find[viewer: viewer, findWhere: backwards];
CloseEvent[]; RETURN [FALSE] };
FindNextWord: CommandProc = {
Find[viewer: viewer, findWhere: forwards, def: FALSE, word: TRUE];
CloseEvent[]; RETURN [FALSE] };
FindAnyWord: CommandProc = {
Find[viewer: viewer, findWhere: anywhere, def: FALSE, word: TRUE];
CloseEvent[]; RETURN [FALSE] };
FindPrevWord: CommandProc = {
Find[viewer: viewer, findWhere: backwards, def: FALSE, word: TRUE];
CloseEvent[]; RETURN [FALSE] };
FindNextDef: CommandProc = {
Find[viewer: viewer, findWhere: forwards, def: TRUE, word: TRUE];
CloseEvent[]; RETURN [FALSE] };
FindAnyDef: CommandProc = {
Find[viewer: viewer, findWhere: anywhere, def: TRUE, word: TRUE];
CloseEvent[]; RETURN [FALSE] };
FindPrevDef: CommandProc = {
Find[viewer: viewer, findWhere: backwards, def: TRUE, word: TRUE];
CloseEvent[]; RETURN [FALSE] };
FindNextCaseless: CommandProc = {
Find[viewer: viewer, findWhere: forwards, case: FALSE];
CloseEvent[]; RETURN [FALSE] };
FindAnyCaseless: CommandProc = {
Find[viewer: viewer, findWhere: anywhere, case: FALSE];
CloseEvent[]; RETURN [FALSE] };
FindPrevCaseless: CommandProc = {
Find[viewer: viewer, findWhere: backwards, case: FALSE];
CloseEvent[]; RETURN [FALSE] };
FindNextWordCaseless: CommandProc = {
Find[viewer: viewer, findWhere: forwards, def: FALSE, word: TRUE, case: FALSE];
CloseEvent[]; RETURN [FALSE] };
FindAnyWordCaseless: CommandProc = {
Find[viewer: viewer, findWhere: anywhere, def: FALSE, word: TRUE, case: FALSE];
CloseEvent[]; RETURN [FALSE] };
FindPrevWordCaseless: CommandProc = {
Find[viewer: viewer, findWhere: backwards, def: FALSE, word: TRUE, case: FALSE];
CloseEvent[]; RETURN [FALSE] };
FindNextDefCaseless: CommandProc = {
Find[viewer: viewer, findWhere: forwards, def: TRUE, word: TRUE, case: FALSE];
CloseEvent[]; RETURN [FALSE] };
FindAnyDefCaseless: CommandProc = {
Find[viewer: viewer, findWhere: anywhere, def: TRUE, word: TRUE, case: FALSE];
CloseEvent[]; RETURN [FALSE] };
FindPrevDefCaseless: CommandProc = {
Find[viewer: viewer, findWhere: backwards, def: TRUE, word: TRUE, case: FALSE];
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] };
Position: CommandProc = {
CloseEvent[];
TEditSelection.ShowPosition[viewer: viewer, skipCommentNodes: TRUE];
RETURN[FALSE]
};
PositionIncludingComments: CommandProc = {
CloseEvent[];
TEditSelection.ShowPosition[viewer: viewer, skipCommentNodes: FALSE];
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:
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 ← 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 [
BOOL] = {
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[$EditFormat, EditFormat];
Register[$EditType, EditFormat]; -- For compatability
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[$FindNextCaseless, FindNextCaseless];
Register[$FindAnyCaseless, FindAnyCaseless];
Register[$FindPrevCaseless, FindPrevCaseless];
Register[$FindNextDefCaseless, FindNextDefCaseless];
Register[$FindAnyDefCaseless, FindAnyDefCaseless];
Register[$FindPrevDefCaseless, FindPrevDefCaseless];
Register[$FindNextWordCaseless, FindNextWordCaseless];
Register[$FindAnyWordCaseless, FindAnyWordCaseless];
Register[$FindPrevWordCaseless, FindPrevWordCaseless];
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, Position];
Register[$PositionIncludingComments, PositionIncludingComments];
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.