cledit.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 527 行
C
527 行
/****************************************************************************
*
* 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 <stdlib.h>
#include <string.h>
#include "vi.h"
#include "posix.h"
#include "keys.h"
#include "win.h"
#ifdef __WIN__
#include "winvi.h"
#include "utils.h"
#endif
#ifdef __WIN__
#ifndef __NT__
BOOL isMultipleFiles( char *altname )
{
while( *altname && *altname != ' ' ) {
altname++;
}
if( *altname == ' ' ) {
return( TRUE );
}
return( FALSE );
}
#else
BOOL isMultipleFiles( char *altname )
{
while( *altname ) {
altname++;
}
if( altname[0] == 0 && altname[1] != 0 ) {
return( TRUE );
}
return( FALSE );
}
/*
* EliminateFirstNT - eliminate first n chars from buff for \0\0-strings
*/
static void EliminateFirstNT( char *buff, int n )
{
char *buff2;
buff2 = &buff[n];
while( buff2[0] != 0 || buff2[1] != 0 ) {
*buff++ = *buff2++;
}
buff[0] = 0;
buff[1] = 0;
} /* EliminateFirstNT */
/*
* NextWordNT - get next \0 delimited word in buff, final delimitier is \0\0
*/
static int NextWordNT( char *buff, char *res )
{
int j,k=0;
char c, cnext;
if( buff[k] == 0 && buff[k+1] == 0 ) {
res[0] = 0;
return( -1 );
}
j = 0;
/*
* get word
*/
while( TRUE ) {
c = buff[k];
cnext = buff[k+1];
if( c==0 ) {
res[j] = 0;
EliminateFirstNT( buff, k+1 );
return( j );
} else {
res[j++] = c;
k++;
}
}
} /* NextWordNT */
/* on NT, we have \0 instead of spaces to delimit single file names and \0\0 to end the string */
#define NextWord1(a,b) NextWordNT(a,b)
#endif
#endif
/*
* EditFile - read a file into text
*/
int EditFile( char *name, int dammit )
{
char *fn,**list,*currfn;
int rc=ERR_NO_ERR,i,cnt,ocnt;
int j,len;
window_id wn;
char cdir[FILENAME_MAX];
info *ci,*il;
bool usedir = FALSE;
char mask[FILENAME_MAX];
bool reset_dir;
int index;
char *altname = NULL;
fn = MemAlloc( FILENAME_MAX );
/*
* get file name
*/
strcpy( cdir, CurrentDirectory );
reset_dir = FALSE;
RemoveLeadingSpaces( name );
if( name[0] == '$' ) {
EliminateFirstN( name, 1 );
usedir = TRUE;
}
fn[0] = 0;
// if( NextWord1( name, fn ) <= 0 )
if( GetStringWithPossibleQuote2( name, fn, FALSE ) != ERR_NO_ERR ) {
usedir = TRUE;
mask[0] = '*';
mask[1] = 0;
}
if( usedir ) {
if( EditFlags.ExMode ) {
MemFree( fn );
return( ERR_INVALID_IN_EX_MODE );
}
len = strlen( fn );
if( len > 0 ) {
i = len-1;
strcpy( mask, fn );
cnt = 0;
while( i >= 0 ) {
if( fn[i] == FILE_SEP ) {
for( j=i+1;j<=len;j++ ) {
mask[j-(i+1)] = fn[j];
}
cnt = i;
break;
}
i--;
}
fn[ cnt ] = 0;
}
if( fn[0] != 0 ) {
i = SelectFileOpen( fn, &fn, mask, TRUE );
} else {
#ifdef __WIN__
if( name[ 0 ] == '\0' ) {
altname = MemAlloc( 1000 );
i = SelectFileOpen( CurrentDirectory, &altname, mask, TRUE );
NextWord1( altname, fn ); // if multiple, kill path
if( isMultipleFiles( altname ) ) {
NextWord1( altname, fn ); // get 1st name
}
} else {
i = SelectFileOpen( CurrentDirectory, &fn, mask, TRUE );
}
#else
i = SelectFileOpen( CurrentDirectory, &fn, mask, TRUE );
#endif
}
if( altname ) {
name = altname;
}
if( i || fn[0] == 0 ) {
MemFree( fn );
SetCWD( cdir );
return( i );
}
}
/*
* loop through all files
*/
EditFlags.WatchForBreak = TRUE;
#ifdef __WIN__
ToggleHourglass( TRUE );
#endif
do {
if( IsDirectory( fn ) ) {
if( EditFlags.ExMode ) {
rc = ERR_INVALID_IN_EX_MODE;
reset_dir = TRUE;
break;
}
rc = SelectFileOpen( fn, &fn, "*", FALSE );
if( rc ) {
reset_dir = TRUE;
break;
}
if( fn[0] == 0 ) {
reset_dir = TRUE;
rc = ERR_NO_ERR;
break;
}
}
currfn = fn;
ocnt = cnt = ExpandFileNames( currfn, &list );
if( !cnt ) {
cnt = 1;
} else {
currfn = list[0];
}
/*
* loop through all expanded files
*/
index = 1;
while( cnt > 0 ) {
cnt--;
/*
* quit current file if ! specified, else just save current state
*/
if( dammit ) {
ci = InfoHead;
if( CurrentInfo == ci ) {
ci=ci->next;
}
RemoveFromAutoSaveList();
CloseAWindow( CurrentWindow );
FreeUndoStacks();
FreeMarkList();
FreeEntireFile( CurrentFile );
MemFree( DeleteLLItem( (ss**)&InfoHead, (ss**)&InfoTail, (ss*)CurrentInfo ) );
CurrentInfo = NULL;
CurrentWindow = NO_WINDOW;
} else {
ci = CurrentInfo;
SaveCurrentInfo();
wn = CurrentWindow;
}
/*
* see if new file is already being edited
*/
SaveCurrentInfo();
il = InfoHead;
while( il != NULL ) {
if( SameFile( il->CurrentFile->name, currfn ) ) {
BringUpFile( il, TRUE );
goto EVIL_CONTINUE;
}
if( strcmp( CurrentDirectory, il->CurrentFile->home ) ) {
/* directory has changed -- check with full path
* note that this will fail if an absolute path
* was specified thus we do the regular check first */
char path[FILENAME_MAX];
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
_splitpath( il->CurrentFile->name, drive, dir, fname, ext );
if( !strlen( drive ) ) {
_splitpath( il->CurrentFile->home,
drive, NULL, NULL, NULL );
}
if( !strlen( dir ) ) {
_splitpath( il->CurrentFile->home,
NULL, dir, NULL, NULL );
} else if( dir[0] != '\\' ) {
char dir2[_MAX_DIR];
_splitpath( il->CurrentFile->home,
NULL, dir2, NULL, NULL );
strcat( dir2, dir );
strcpy( dir, dir2 );
}
_makepath( path, drive, dir, fname, ext );
if( SameFile( path, currfn ) ) {
BringUpFile( il, TRUE );
goto EVIL_CONTINUE;
}
}
il = il->next;
}
/*
* file not edited, go get it
*/
rc = NewFile( currfn, FALSE );
if( rc && rc != NEW_FILE ) {
RestoreInfo( ci );
DCDisplayAllLines();
break;
}
if( !dammit ) {
InactiveWindow( wn );
}
if( EditFlags.BreakPressed ) {
break;
}
EVIL_CONTINUE:
if( cnt > 0 ) {
currfn = list[index];
index++;
}
}
if( ocnt > 0 ) {
MemFreeList( ocnt, list );
}
if( EditFlags.BreakPressed ) {
ClearBreak();
break;
}
} while( NextWord1( name, fn ) > 0 );
if( altname ) {
MemFree( altname );
}
MemFree( fn );
#ifdef __WIN__
ToggleHourglass( FALSE );
#endif
EditFlags.WatchForBreak = FALSE;
if( reset_dir ) {
SetCWD( cdir );
}
return( rc );
} /* EditFile */
#if defined( __WIN__ ) && defined( __NT__ )
#undef NextWord1
#endif
#ifndef __WIN__
static char _NEAR *_NEAR fileOpts[] = {
"<F1> Go To",
"<F2> Quit",
"<F3> Save & Quit"
};
#define NUM_OPTS sizeof( fileOpts )/sizeof( char _NEAR * )
/*
* EditFileFromList - edit from file in current active list
*/
int EditFileFromList( void )
{
int i,tmp,j,n=0,rc,fcnt;
window_id optwin;
bool repeat=TRUE;
info *cinfo;
char **list,modchar;
int evlist[4] = { VI_KEY( F1 ), VI_KEY( F2 ), VI_KEY( F3 ), -1 };
bool show_lineno;
window_info wi;
selectitem si;
/*
* set up options for file list
*/
memcpy( &wi, &extraw_info, sizeof( window_info ) );
wi.x1 =2;
wi.x2 = 19;
i = DisplayExtraInfo( &wi, &optwin, fileOpts, NUM_OPTS );
if( i ) {
return( i );
}
while( repeat ) {
/*
* set up for this pass
*/
repeat = FALSE;
MoveWindowToFrontDammit( optwin, FALSE );
SaveCurrentInfo();
/*
* allocate a buffer for strings, add strings
*/
list = (char **) MemAlloc( GimmeFileCount()*sizeof( char * ) );
j = 0;
cinfo = InfoHead;
while( cinfo != NULL ) {
list[j] = MemAlloc( strlen( cinfo->CurrentFile->name ) +3 );
if( cinfo->CurrentFile->modified ) {
modchar = '*';
}
else modchar = ' ';
MySprintf(list[j],"%c %s",modchar, cinfo->CurrentFile->name );
j++;
cinfo = cinfo->next;
}
fcnt = j;
tmp = filelistw_info.y2;
i = filelistw_info.y2 - filelistw_info.y1+1;
if( filelistw_info.has_border ) {
i -= 2;
}
if( j < i ) {
filelistw_info.y2 -= ( i-j );
}
show_lineno = TRUE;
/*
* get file
*/
if( n+1 > j ) {
n = j-1;
}
memset( &si, 0, sizeof( si ) );
si.wi = &filelistw_info;
si.title = "Current Files";
si.list = list;
si.maxlist = j;
si.num = n;
si.retevents = evlist;
si.event = -1;
si.show_lineno = show_lineno;
si.cln = n+1;
si.eiw = optwin;
rc = SelectItem( &si );
n = si.num;
if( !rc ) {
if( n >= 0 ) {
j = 0;
cinfo = InfoHead;
while( n != j ) {
j++;
cinfo = cinfo->next;
}
BringUpFile( cinfo, TRUE );
switch( si.event ) {
case -1: case VI_KEY( F1 ):
break;
case VI_KEY( F2 ):
rc = NextFile();
if( rc <= 0 ) {
repeat = TRUE;
}
break;
case VI_KEY( F3 ):
rc = SaveAndExit( NULL );
if( rc <= 0 ) {
repeat = TRUE;
}
break;
}
}
}
filelistw_info.y2 = tmp;
MemFreeList( fcnt, list );
}
/*
* get rid of option stuff
*/
CloseAWindow( optwin );
return( rc );
} /* EditFileFromList */
#endif
/*
* OpenWindowOnFile - open a window on a file
*/
int OpenWindowOnFile( char *data )
{
char *name;
int rc;
window_id wn;
RemoveLeadingSpaces( data );
name = data;
if( data[0] == 0 ) {
name = NULL;
}
wn = CurrentWindow;
rc = NewFile( name, TRUE );
if( !rc ) {
InactiveWindow( wn );
DCDisplayAllLines();
}
return( rc );
} /* OpenWindowOnFile */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?