EditToolOpsImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Russ Atkinson, September 28, 1983 2:21 pm
Doug Wyatt, March 4, 1985 10:26:32 am PST
Russ Atkinson (RRA) June 18, 1985 4:59:53 pm PDT
DIRECTORY
Buttons USING [ButtonProc],
EditToolBuilder USING [BadNumber, BuildButton, BuildDataFieldPair, ConvertList, DataFieldButton, GetDataNode, GetInt, HGap, VGap],
EditToolPrivate USING [CheckPSel, DoButton, Info, mainToolInfo, Register, TrySearch],
FS USING [Error, ExpandName, nullOpenFile, Open, OpenFile, StreamFromOpenFile],
IO USING [Close, EndOfStream, GetChar, GetLength, GetRefAny, RIS, STREAM],
List USING [Append, Nconc1],
MessageWindow USING [Append, Blink],
Rope USING [Cat, Concat, Fetch, FromProc, ROPE, Size, Substr],
TEditDocument USING [Selection],
TEditHistory USING [CurrentEventNumber, GetRepeatList, SliceSize],
TEditInput USING [CloseEvent, CommandProc, CurrentEvent, GetCommand, GetRepeatSequence, Interpret, SetCommand],
TEditOps USING [GetSelData, SetTextContents],
TEditProfile USING [GetToken],
TEditSelection USING [LockSel, UnlockSel],
TextEdit USING [GetRope],
TiogaMenuOps USING [CloseAndNewViewer, Empty, Load, New],
TiogaOps USING [FirstChild, SelectDocument, SetSelection, ViewerDoc],
TiogaOpsDefs USING [Ref],
TypeScript USING [IsATypeScript],
UndoEvent USING [Ref, Reset],
ViewerClasses USING [Viewer],
ViewerOps USING [DestroyViewer, SaveViewer];
EditToolOpsImpl:
CEDAR
PROGRAM
IMPORTS EditToolPrivate, EditToolBuilder, FS, IO, List, MessageWindow, Rope, TEditInput, TEditOps, TextEdit, TEditHistory, TEditSelection, TiogaMenuOps, TiogaOps, TEditProfile, TypeScript, UndoEvent, ViewerOps
EXPORTS EditToolPrivate
= { OPEN ViewerClasses, EditToolBuilder, EditToolPrivate;
--------------------------
Flash:
PROC[message, message2, message3:
ROPE ←
NIL] = {
MessageWindow.Append[message, TRUE];
IF message2#NIL THEN MessageWindow.Append[message2];
IF message3#NIL THEN MessageWindow.Append[message3];
MessageWindow.Blink[];
};
--------------------------
opsAtom: LIST OF REF = Register[$Operations,OpsArgOp];
clearOpsAtom: LIST OF REF = Register[$ClearOperations,ClearOpsArgOp];
OpsButton: Buttons.ButtonProc = {
DoButton[opsAtom,clearOpsAtom, mouseButton=red] };
OpsArgOp: TEditInput.CommandProc = { OpsArg[mainToolInfo] };
OpsArg: PROC [info: Info] = { DataFieldButton[info.opsArg,FALSE] };
ClearOpsArgOp: TEditInput.CommandProc = { ClearOpsArg[mainToolInfo] };
ClearOpsArg: PROC [info: Info] = { DataFieldButton[info.opsArg,TRUE] };
BuildOperationField:
PUBLIC
PROC [info: Info] = {
OPEN info;
[,opsArg] ← BuildDataFieldPair[layout, "Operations:", OpsButton, info, 2] };
GetOps:
PUBLIC
PROC [info: Info]
RETURNS [list:
LIST
OF
REF
ANY] = {
OPEN
IO, info;
rope: ROPE ← TextEdit.GetRope[GetDataNode[opsArg]];
h: IO.STREAM ← IO.RIS[rope];
item: REF ANY ← NIL;
DO
item ← IO.GetRefAny[h ! IO.EndOfStream => { item ← NIL; CONTINUE}];
IF item = NIL THEN EXIT;
list ← List.Nconc1[list, item];
ENDLOOP;
};
--------------------------
BuildFileListEntries:
PUBLIC
PROC [info: Info] = {
OPEN info;
[] ← BuildButton[layout, "DoForEachFile", DoFilesListButton, info, TRUE];
[] ← BuildButton[layout, "SearchEachFile", SearchFilesListButton, info, TRUE];
HGap[layout];
[,filesArg] ← BuildDataFieldPair[layout, "Files:", FilesListButton, info, 1];
VGap[layout];
[,wdirArg] ← BuildDataFieldPair[layout, "Working Directory:", WDirButton, info, 1];
--------------------------
filesListAtom: LIST OF REF = Register[$FilesList,FilesListOp];
clearFilesListAtom: LIST OF REF = Register[$ClearFilesList,ClearFilesListOp];
FilesListButton: Buttons.ButtonProc = {
DoButton[filesListAtom,clearFilesListAtom, mouseButton=red] };
FilesListOp: TEditInput.CommandProc = { FilesList[mainToolInfo] };
FilesList: PROC [info: Info] = { DataFieldButton[info.filesArg,FALSE] };
ClearFilesListOp: TEditInput.CommandProc = { ClearFilesList[mainToolInfo] };
ClearFilesList: PROC [info: Info] = { DataFieldButton[info.filesArg,TRUE] };
--------------------------
wDirAtom: LIST OF REF = Register[$WDir,WDirOp];
clearWDirAtom: LIST OF REF = Register[$ClearWDir,ClearWDirOp];
WDirButton: Buttons.ButtonProc = {
DoButton[wDirAtom,clearWDirAtom, mouseButton=red] };
WDirOp: TEditInput.CommandProc = { WDir[mainToolInfo] };
WDir: PROC [info: Info] = { DataFieldButton[info.wdirArg,FALSE] };
ClearWDirOp: TEditInput.CommandProc = { ClearWDir[mainToolInfo] };
ClearWDir: PROC [info: Info] = { DataFieldButton[info.wdirArg,TRUE] };
--------------------------
searchFilesListAtom: LIST OF REF = Register[$SearchEachFile,SearchFilesListOp];
SearchFilesListButton: Buttons.ButtonProc = { DoButton[searchFilesListAtom] };
SearchFilesListOp: TEditInput.CommandProc = { SearchFilesListCom[mainToolInfo] };
SearchFilesListCom: PROC [info: Info] = { DoFilesList[info, FALSE] };
--------------------------
doFilesListAtom: LIST OF REF = Register[$DoForEachFile,DoFilesListOp];
DoFilesListButton: Buttons.ButtonProc = { DoButton[doFilesListAtom] };
DoFilesListOp: TEditInput.CommandProc = { DoFilesListCom[mainToolInfo] };
DoFilesListCom: PROC [info: Info] = { DoFilesList[info, TRUE] };
DoFilesList:
PROC [info: Info, do:
BOOL] = {
params: LIST OF REF ANY;
pSel: TEditDocument.Selection;
viewer: Viewer;
found: BOOL ← FALSE;
event: UndoEvent.Ref = TEditInput.CurrentEvent[];
fileList: ROPE ← TextEdit.GetRope[GetDataNode[info.filesArg]];
wDir: ROPE ← TextEdit.GetRope[GetDataNode[info.wdirArg]];
GetFilesList:
PROC [fileName:
ROPE]
RETURNS [filesList:
ROPE] = {
len: INT;
s: IO.STREAM;
readChar: PROC RETURNS [CHAR] = { RETURN [IO.GetChar[s]] };
file: FS.OpenFile ← FS.nullOpenFile;
file ←
FS.Open[name: fileName, wDir: wDir
!
FS.Error =>
IF error.code=$unknownFile THEN CONTINUE
ELSE { Flash[error.explanation]; GOTO Quit }
];
IF file=
FS.nullOpenFile
THEN file ←
FS.Open[name: fileName.Concat[".cm"], wDir: wDir
!
FS.Error =>
IF error.code=$unknownFile THEN CONTINUE
ELSE { Flash[error.explanation]; GOTO Quit }
];
IF file=FS.nullOpenFile THEN { Flash[fileName, " not found"]; GOTO Quit };
s ← FS.StreamFromOpenFile[file];
len ← IO.GetLength[s];
filesList ← Rope.FromProc[len, readChar];
IO.Close[s];
EXITS Quit => { filesList ← NIL };
};
DoEachInList:
PROC [list:
ROPE]
RETURNS [remainder:
ROPE] = {
offset: INT ← 0;
DO
-- process each file
filename: ROPE;
IF info.interrupt^ THEN RETURN [Rope.Substr[list, offset]];
[filename, offset] ← TEditProfile.GetToken[list, offset];
IF Rope.Size[filename]=0 THEN RETURN [NIL];
IF Rope.Fetch[filename,0]='@
THEN {
-- process list
sub: ROPE = DoEachInList[GetFilesList[Rope.Substr[filename,1]]];
IF sub=NIL THEN LOOP; -- finished the sublist
RETURN [Rope.Cat[sub, " ", Rope.Substr[list, offset]]] };
IF viewer.newVersion THEN viewer ← TiogaMenuOps.CloseAndNewViewer[viewer]
ELSE TiogaMenuOps.Empty[viewer];
[fullFName: filename] ←
FS.ExpandName[name: filename, wDir: wDir
! FS.Error => { Flash[error.explanation]; filename ← NIL; CONTINUE }];
IF filename#NIL THEN TiogaMenuOps.Load[viewer, filename];
IF viewer.file#
NIL
THEN {
-- got the file
IF do
THEN {
TiogaOps.SelectDocument[viewer];
TEditInput.Interpret[viewer, params];
IF viewer.newVersion THEN ViewerOps.SaveViewer[viewer];
UndoEvent.Reset[event] } -- so we don't fill up VM with trash
ELSE {
-- search
node: TiogaOpsDefs.Ref = TiogaOps.FirstChild[TiogaOps.ViewerDoc[viewer]];
TiogaOps.SetSelection[viewer, [node,0], [node,0], point];
make point selection at start of document
IF TrySearch[forwards, info]
THEN
found ← info.interrupt^ ← TRUE; -- so will stop after this one
}};
ENDLOOP
};
info.interrupt^ ← FALSE;
IF do AND (params ← GetOps[info])=NIL THEN { Flash["Enter operations."]; RETURN };
IF fileList=NIL THEN { Flash["Enter list of files."]; RETURN };
TEditInput.CloseEvent[];
TEditSelection.LockSel[primary, "DoFilesList"];
pSel ← TEditOps.GetSelData[];
viewer ←
IF pSel.viewer#
NIL
AND pSel.viewer.parent=
NIL
AND ~TypeScript.IsATypeScript[pSel.viewer]
THEN
IF pSel.viewer.file=
NIL
THEN pSel.viewer
ELSE TiogaMenuOps.CloseAndNewViewer[pSel.viewer]
ELSE TiogaMenuOps.New[];
TEditOps.SetTextContents[info.filesArg, DoEachInList[fileList]];
TEditSelection.UnlockSel[primary];
IF do OR (~found AND ~viewer.newVersion) THEN ViewerOps.DestroyViewer[viewer];
};
--------------------------
BuildGetAndSetOpsEntries:
PUBLIC
PROC [info: Info] = {
OPEN info;
[] ← BuildButton[layout, "GetLast", DoGetLastOpsButton, info];
[] ← BuildButton[layout, "Do", DoOpsButton, info];
[] ← BuildButton[layout, "Begin", DoBeginButton, info];
[] ← BuildButton[layout, "End", DoEndButton, info];
[] ← BuildButton[layout, "SetCom", DoSetOpsButton, info];
[] ← BuildButton[layout, "GetCom", DoGetOpsButton, info];
HGap[layout];
BuildComNumField[info];
-- "Command number [0..9]:" field
};
doGetLastOpsAtom: LIST OF REF = Register[$DoGetLastOps,DoGetLastOpsOp];
DoGetLastOpsButton: Buttons.ButtonProc = {
DoButton[doGetLastOpsAtom] };
DoGetLastOpsOp: TEditInput.CommandProc = {
DoGetLastOpsCom[mainToolInfo]; RETURN [FALSE] };
DoGetLastOpsCom:
PROC [info: Info] = {
ShowOps[TEditInput.GetRepeatSequence[],info] };
ShowOps:
PROC [list:
LIST
OF
REF
ANY, info: Info] = {
TEditOps.SetTextContents[info.opsArg, ConvertList[list]] };
doOpsAtom: LIST OF REF = Register[$DoOps,DoOpsOp];
DoOpsButton: Buttons.ButtonProc = {
DoButton[doOpsAtom] };
DoOpsOp: TEditInput.CommandProc = { DoOpsCom[mainToolInfo] };
DoOpsCom:
PUBLIC
PROC [info: Info] = {
pSel: TEditDocument.Selection ← TEditOps.GetSelData[];
params: LIST OF REF ANY;
IF ~CheckPSel[pSel] THEN { Flash["Make a selection."]; RETURN };
IF (params ← GetOps[info])=NIL THEN { Flash["Enter operations."]; RETURN };
TEditSelection.LockSel[primary, "DoOpsCom"];
TEditInput.Interpret[pSel.viewer, params];
TEditSelection.UnlockSel[primary] };
SetCom:
PROC [num: [0..9], info: Info] = {
list: LIST OF REF ANY ← GetOps[info];
TEditInput.SetCommand[num,list];
};
doSetOpsAtom: LIST OF REF = Register[$DoSetOps,DoSetOpsOp];
DoSetOpsButton: Buttons.ButtonProc = {
DoButton[doSetOpsAtom] };
DoSetOpsOp: TEditInput.CommandProc = { DoSetOpsCom[mainToolInfo] };
DoSetOpsCom:
PROC [info: Info] = {
num: INT ← GetInt[info.comArg ! BadNumber => GOTO BadNum];
IF num NOT IN [0..9] THEN GOTO BadNum;
SetCom[num,info];
EXITS BadNum => { Flash["Enter number from 0 to 9 in Command Number field"] }
doGetOpsAtom: LIST OF REF = Register[$DoGetOps,DoGetOpsOp];
DoGetOpsButton: Buttons.ButtonProc = {
DoButton[doGetOpsAtom] };
DoGetOpsOp: TEditInput.CommandProc = { DoGetOpsCom[mainToolInfo] };
DoGetOpsCom:
PROC [info: Info] = {
num: INT ← GetInt[info.comArg ! BadNumber => GOTO BadNum];
IF num NOT IN [0..9] THEN GOTO BadNum;
ShowOps[TEditInput.GetCommand[num],info];
EXITS BadNum => { Flash["Enter number from 0 to 9 in Command Number field"] }
doBeginAtom: LIST OF REF = Register[$DoBegin,DoBeginOp];
DoBeginButton: Buttons.ButtonProc = {
DoButton[doBeginAtom] };
DoBeginOp: TEditInput.CommandProc = { DoBeginCom[mainToolInfo] };
beginEvent: INT ← 0;
DoBeginCom:
PROC [info: Info] = {
[] ← TEditInput.GetRepeatSequence[]; -- to make sure the event is terminated
beginEvent ← TEditHistory.CurrentEventNumber[];
TEditInput.CloseEvent[] };
doEndAtom: LIST OF REF = Register[$DoEnd,DoEndOp];
DoEndButton: Buttons.ButtonProc = {
DoButton[doEndAtom] };
DoEndOp: TEditInput.CommandProc = { DoEndCom[mainToolInfo] };
DoEndCom:
PROC [info: Info] = {
list: LIST OF REF ANY;
endEvent: INT;
[] ← TEditInput.GetRepeatSequence[]; -- to make sure the event is terminated
endEvent ← TEditHistory.CurrentEventNumber[];
IF endEvent-beginEvent > TEditHistory.SliceSize[]
THEN {
Flash["Not all events still recorded. Some missing at start."];
};
FOR i:
INT ← beginEvent+1, i+1
UNTIL i > endEvent
DO
list ← List.Append[list, TEditHistory.GetRepeatList[i]];
ENDLOOP;
ShowOps[list,info] };
--------------------------
comNumAtom: LIST OF REF = Register[$CommandNumber,DoComNumOp];
clearComNumAtom: LIST OF REF = Register[$ClearCommandNumber,ClearComNumOp];
ComNumButton: Buttons.ButtonProc = {
DoButton[comNumAtom,clearComNumAtom, mouseButton=red] };
DoComNumOp: TEditInput.CommandProc = { DoComNum[mainToolInfo] };
DoComNum: PROC [info: Info] = { DataFieldButton[info.comArg,FALSE] };
ClearComNumOp: TEditInput.CommandProc = { ClearComNum[mainToolInfo] };
ClearComNum: PROC [info: Info] = { DataFieldButton[info.comArg,TRUE] };
BuildComNumField:
PUBLIC
PROC [info: Info] = {
OPEN info;
[,comArg] ← BuildDataFieldPair[layout, "Command [0..9]:", ComNumButton, info, 1];
TEditOps.SetTextContents[comArg, "1 "]; };
--------------------------
}...