undo_do.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 226 行
C
226 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include <stdio.h>
#include <string.h>
#include "vi.h"
static char usName[] = "undo stack";
static char uusName[] = "undo-undo stack";
/*
* validateUndo - make sure an undo has the correct number of open/closes
*/
static int validateUndo( undo *cundo )
{
bool done = FALSE;
int depth=0;
/*
* run through entries in this undo record, counting the
* start/end groups. if there are not an equal number, then
* an error occurred while forming this undo and the whole
* bloody stack is fried.
*/
while( !done ) {
switch( cundo->type ) {
case START_UNDO_GROUP:
depth--;
if( depth == 0 ) {
done = TRUE;
}
break;
case END_UNDO_GROUP:
depth++;
break;
}
cundo = cundo->next;
if( cundo == NULL ) {
break;
}
}
if( !done ) {
return( ERR_INVALID_UNDO );
}
return( ERR_NO_ERR );
} /* validateUndo */
/*
* realUndo - perform an undo
*/
static int realUndo( undo_stack *stack, undo_stack *us )
{
undo *cundo,*tundo;
bool done=FALSE;
int rc=ERR_NO_ERR;
int col,depth=0;
linenum lne,top;
char *name;
linedel_flags ldf;
if( stack == NULL ) {
return( ERR_NO_FILE );
}
if( stack->OpenUndo > 0 ) {
return( ERR_OPEN_UNDO );
}
cundo = PopUndoStack( stack );
if( cundo == NULL ) {
if( stack == UndoUndoStack ) {
return( ERR_NO_MORE_REDOS );
}
else {
return( ERR_NO_MORE_UNDOS );
}
}
if( validateUndo( cundo ) ) {
PurgeUndoStack( UndoStack );
PurgeUndoStack( UndoUndoStack );
return( ERR_INVALID_UNDO );
}
tundo = cundo;
StartUndoGroup( us );
EditFlags.DisplayHold = TRUE;
ldf = 0;
if( us == UndoUndoStack ) {
ldf = USE_UNDO_UNDO;
}
/*
* loop through all undos in this group
*/
while( !done ) {
switch( cundo->type ) {
case START_UNDO_GROUP:
depth--;
if( depth == 0 ) {
done = TRUE;
}
if( cundo->data.sdata.depth == 1 ) {
lne = cundo->data.sdata.line;
top = cundo->data.sdata.top;
col = cundo->data.sdata.col;
}
break;
case END_UNDO_GROUP:
depth++;
break;
case UNDO_INSERT_LINES:
rc = DeleteLineRange( cundo->data.del_range.start,
cundo->data.del_range.end, ldf );
break;
case UNDO_DELETE_FCBS:
rc = InsertLines( cundo->data.fcbs.fcb_head->start_line,
cundo->data.fcbs.fcb_head,cundo->data.fcbs.fcb_tail, us );
break;
}
if( rc > 0 ) {
break;
}
cundo = cundo->next;
if( cundo == NULL ) {
break;
}
}
if( !done ) {
stack->OpenUndo = 0;
}
/*
* finish up
*/
EndUndoGroup( us );
UndoFree( tundo, FALSE );
CMergeAllFcbs();
EditFlags.DisplayHold = FALSE;
TopOfPage = top;
SetCurrentLineNumber( lne );
CurrentColumn = 1;
CGimmeLinePtr( lne, &CurrentFcb, &CurrentLine );
GoToColumnOK( col );
UpdateStatusWindow();
DCDisplayAllLines();
if( !rc ) {
if( stack == UndoStack ) {
name = usName;
} else {
name = uusName;
}
if( stack->current < 0 ) {
Message1( "%s is empty",name );
if( stack == UndoStack ) {
if( !stack->rolled ) {
Modified( FALSE );
}
}
} else {
Message1( "%d items left on %s",stack->current+1,name );
}
rc = DO_NOT_CLEAR_MESSAGE_WINDOW;
}
return( rc );
} /* realUndo */
/*
* DoUndo - do an undo
*/
int DoUndo( void )
{
return( realUndo( UndoStack, UndoUndoStack ) );
} /* DoUndo */
/*
* DoUndoUndo - do an undo
*/
int DoUndoUndo( void )
{
int rc;
EditFlags.UndoInProg = TRUE;
rc = realUndo( UndoUndoStack, UndoStack );
EditFlags.UndoInProg = FALSE;
return( rc );
} /* DoUndoUndo */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?