-- file: EditorUndo.Mesa -- edited by Brotz, May 4, 1981 4:32 PM -- edited by Levin, February 22, 1980 12:42 PM DIRECTORY Editor, exD: FROM "ExceptionDefs", inD: FROM "InteractorDefs", intCommon: FROM "IntCommon", ovD: FROM "OverviewDefs", vmD: FROM "VirtualMgrDefs"; EditorUndo: PROGRAM IMPORTS Editor, exD, intC: intCommon, vmD EXPORTS Editor = BEGIN OPEN Editor, inD; Undo: PUBLIC PROCEDURE [mnp: MessageTextNbrPtr] = -- Undoes the last command, ignoring subsequent window commands or selections. BEGIN commandType: POINTER TO CommandType = @intC.commandType; actionPoint: POINTER TO ovD.CharIndex = @intC.actionPoint; target: TextSelectionPtr = @intC.target; modelessEditor: BOOLEAN = (intC.editorType = modeless); IF commandType^ = noCommand THEN RETURN; CancelTargetSelection[]; IF commandType^ = get THEN BEGIN -- flip buffers back SwapMessageWithDeletionBuffer[mnp]; target^ _ TextSelection[mnp, 0, vmD.GetMessageSize[mnp.message], 0, char, FALSE]; IF modelessEditor THEN {target.start _ target.end; intC.newTargetSelection _ FALSE}; SetHighWaterMark[0]; RefreshSoThatFirstCharStartsLine[0, mnp.lines, mnp]; TurnOnDeliver[]; END ELSE BEGIN thisInsertionLength: CARDINAL = vmD.GetMessageSize[mnp.deletionBuffer]; thisDeletionLength: CARDINAL = vmD.GetMessageSize[mnp.insertionBuffer]; ReplaceRangeInMess[ to: vmD.MessageRange [actionPoint^, actionPoint^ + vmD.GetMessageSize[mnp.insertionBuffer], mnp.message], from: vmD.MessageRange[0, thisInsertionLength, mnp.deletionBuffer]]; SwapInsertionWithDeletionBuffer[mnp]; target^ _ TextSelection [mnp, actionPoint^, actionPoint^ + thisInsertionLength, 0, char, FALSE]; IF modelessEditor THEN {target.start _ target.end; intC.newTargetSelection _ FALSE}; UpdateScreen[start: actionPoint^, nCharsDeleted: thisDeletionLength, nCharsInserted: thisInsertionLength, mnp: mnp]; END; commandType^ _ SELECT commandType^ FROM get => get, insert, append => delete, delete => insert, ENDCASE => replace; END; -- of Undo -- Redo: PUBLIC PROCEDURE [mnp: MessageTextNbrPtr] = -- Redoes the last command with the Segment [start .. end). BEGIN commandType: POINTER TO CommandType = @intC.commandType; target: TextSelectionPtr = @intC.target; start: ovD.CharIndex _ target.start; end: ovD.CharIndex _ target.end; modelessEditor: BOOLEAN = (intC.editorType = modeless); insertionLength: CARDINAL = vmD.GetMessageSize[mnp.insertionBuffer]; deletionBufferLength: CARDINAL = vmD.GetMessageSize[mnp.deletionBuffer]; IF modelessEditor AND start = end THEN RETURN; SELECT commandType^ FROM noCommand, get => RETURN; insert => IF modelessEditor THEN start _ end _ target.point ELSE end _ start; append => IF modelessEditor THEN start _ end _ target.point ELSE start _ end; ENDCASE; IF commandType^ = insert OR commandType^ = append THEN CancelTargetSelection[] ELSE target.pendingDelete _ FALSE; intC.actionPoint _ start; ReplaceRangeInMess [to: vmD.MessageRange[0, deletionBufferLength, mnp.deletionBuffer], from: vmD.MessageRange[start, end, mnp.message]]; ReplaceRangeInMess [to: vmD.MessageRange[start, end, mnp.message], from: vmD.MessageRange[0, insertionLength, mnp.insertionBuffer]]; target^ _ TextSelection[mnp, start, start + insertionLength, 0, char, FALSE]; IF modelessEditor THEN {target.start _ target.end; intC.newTargetSelection _ FALSE}; UpdateScreen[start: start, nCharsDeleted: end - start, nCharsInserted: insertionLength, mnp: mnp]; END; -- of Redo -- InsertFromLastCommand: PUBLIC PROCEDURE [mnp: MessageTextNbrPtr] = -- Only callable if editorType = modal. BEGIN target: TextSelectionPtr = @intC.target; insertionLength: CARDINAL; IF intC.editorType = modeless OR intC.pendingCommandType = noCommand THEN exD.SysBug[]; IF (intC.pendingCommandType = insert OR intC.pendingCommandType = append) AND intC.commandType = delete THEN BEGIN SwapInsertionWithDeletionBuffer[mnp]; ResetDeletionBuffer[mnp]; END; intC.commandType _ intC.pendingCommandType; intC.actionPoint _ target.point; intC.pendingCommandType _ noCommand; CancelTargetSelection[]; insertionLength _ vmD.GetMessageSize[mnp.insertionBuffer]; InsertRangeInMess [targetIndex: target.point, targetMessage: LOOPHOLE[mnp.message], from: vmD.MessageRange[0, insertionLength, mnp.insertionBuffer]]; target^ _ TextSelection [mnp, intC.actionPoint, intC.actionPoint + insertionLength, 0, char, FALSE]; UpdateScreen[start: intC.actionPoint, nCharsDeleted: 0, nCharsInserted: insertionLength, mnp: mnp]; END; -- of InsertFromLastCommand -- InsertLastDeletion: PUBLIC PROCEDURE [mnp: MessageTextNbrPtr] = BEGIN -- Only callable if editor is modeless. target: TextSelectionPtr = @intC.target; commandType: POINTER TO CommandType = @intC.commandType; insertionLength: CARDINAL= vmD.GetMessageSize[mnp.deletionBuffer]; deletionLength: CARDINAL _ 0; insertionBufferIndex: ovD.CharIndex; IF intC.newTargetSelection THEN BEGIN IF target.pendingDelete THEN BEGIN target.point _ target.start; commandType^ _ replace; END ELSE {CancelTargetSelection[]; commandType^ _ insert}; ResetInsertionBuffer[mnp]; intC.actionPoint _ target.point; intC.newTargetSelection _ FALSE; END ELSE IF commandType^ = delete THEN commandType^ _ replace; insertionBufferIndex _ vmD.GetMessageSize[mnp.insertionBuffer]; -- Move deletion buffer contents to insertion buffer. InsertRangeInMess [targetIndex: insertionBufferIndex, targetMessage: mnp.insertionBuffer, from: vmD.MessageRange[0, insertionLength, mnp.deletionBuffer]]; IF target.pendingDelete THEN BEGIN -- Move selection to deletion buffer. deletionLength _ target.end - target.start; ReplaceRangeInMess[to: [0, insertionLength, mnp.deletionBuffer], from: [target.start, target.end, mnp.message]]; END; -- Move new stuff to message. ReplaceRangeInMess[ to: [target.point, target.point + deletionLength, LOOPHOLE[mnp.message]], from: [insertionBufferIndex, insertionBufferIndex + insertionLength, mnp.insertionBuffer]]; target^ _ TextSelection [mnp, target.point + insertionLength, target.point + insertionLength, target.point, char, FALSE]; UpdateScreen[start: target.point, nCharsDeleted: deletionLength, nCharsInserted: insertionLength, mnp: mnp]; END; -- of InsertLastDeletion -- END. -- of EditorUndo -- (635)\f1