EditToolOpsImpl.mesa
Paxton on June 2, 1983 9:20 am
McGregor on September 20, 1982 2:42 pm
Maxwell, January 19, 1983 2:54 pm
Russ Atkinson, September 28, 1983 2:21 pm
Doug Wyatt, February 4, 1984 4:54:07 pm PST
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],
TextNode USING [Offset],
TiogaMenuOps USING [CloseAndNewViewer, Empty, Load, New],
TiogaOps USING [FirstChild, SelectDocument, SetSelection, ViewerDoc],
TiogaOpsDefs USING [Offset, 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;
----------------------------
ROPE: TYPE = Rope.ROPE;
Offset: TYPE = TextNode.Offset;
----------------------------
Flash: PROC[message, message2, message3: ROPENIL] = {
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.STREAMIO.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: BOOLFALSE;
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 "]; };
----------------------------
}...