editins.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,162 行 · 第 1/2 页
C
1,162 行
} /* IMSpace */
/*
* IMTabs - handle tabs in insert mode
*/
int IMTabs( void )
{
char *buff;
bool back;
int cp,vc,tc,add;
int i,j;
int len;
startNewLineUndo();
CheckAbbrev( abbrevBuff, &abbrevCnt );
abbrevCnt = 0;
switch( LastEvent ) {
case VI_KEY( TAB ):
if( EditFlags.RealTabs ) {
if( WorkLine->len + 1 >= MaxLine ) {
break;
}
addChar( '\t' );
GoToColumn( CurrentColumn +1, WorkLine->len+1 );
checkWrapMargin();
break;
}
/* fall through if not real tabs */
case VI_KEY( CTRL_T ):
case VI_KEY( SHIFT_TAB ):
case VI_KEY( CTRL_D ):
/*
* get position of cursor on virtual line
*/
vc = VirtualCursorPosition();
if( CurrentColumn-1 == WorkLine->len && !EditFlags.Modeless ) {
add=1;
} else {
add=0;
}
switch( LastEvent ) {
case VI_KEY( SHIFT_TAB ):
j = ShiftTab( vc, TabAmount );
back = TRUE;
break;
case VI_KEY( CTRL_D ):
j = ShiftTab( vc, ShiftWidth );
back = TRUE;
break;
case VI_KEY( TAB ):
j = Tab( vc, TabAmount );
back = FALSE;
break;
case VI_KEY( CTRL_T ):
j = Tab( vc, ShiftWidth );
back = FALSE;
break;
}
if( back && (vc - j < 1) ) {
break;
} else if( RealLineLen( WorkLine->data) + j >= MaxLine ) {
break;
}
/*
* create a real version of the line
*/
buff = StaticAlloc();
ExpandTabsInABufferUpToColumn( CurrentColumn-1, WorkLine->data,
WorkLine->len, buff, MaxLine );
len = strlen( buff );
/*
* put in/suck out the tab
*/
tc = vc-1;
if( back ) {
for( i=tc; i<=len+1; i++ ) {
buff[i-j] = buff[i];
}
len -= j;
} else {
for( i=len; i>=tc; i-- ) {
buff[i+j] = buff[i];
}
for( i=0; i<j; i++ ) {
buff[tc+i] = ' ';
}
len += j;
}
/*
* put tabs back in
*/
if( back ) {
cp = vc-j;
} else {
cp = vc+j;
}
if( EditFlags.RealTabs ) {
ConvertSpacesToTabsUpToColumn( cp, buff, len, WorkLine->data, MaxLine );
} else {
strcpy( WorkLine->data, buff );
}
WorkLine->len = strlen( WorkLine->data );
StaticFree( buff );
cp = RealCursorPosition( cp )+add;
GoToColumn( cp, WorkLine->len+1 );
DisplayWorkLine( FALSE );
break;
}
return( ERR_NO_ERR );
} /* IMTabs */
/*
* IMEscapeNextChar - handle ^Q and ^V in insert mode
*/
int IMEscapeNextChar( void )
{
int rc;
startNewLineUndo();
LastEvent = '^';
rc = insertChar( FALSE, FALSE );
EditFlags.EscapedInsertChar = TRUE;
return( rc );
} /* IMEscapeNextChar */
/*
* IMInsert - handle INS key pressed in insert mode
*/
int IMInsert( void )
{
if( overStrike ) {
overStrike = FALSE;
} else {
overStrike = TRUE;
}
UpdateEditStatus();
return( ERR_NO_ERR );
} /* IMInsert */
/*
* tempMatch - show a temporary match
*/
static void tempMatch( linenum mline, int mcol )
{
SaveCurrentFilePos();
GoToLineNoRelCurs( mline );
GoToColumnOK( mcol );
#ifdef __WIN__
DCDisplayAllLines();
DCUpdate();
SetWindowCursorForReal();
MyDelay( 150 );
RestoreCurrentFilePos();
DCDisplayAllLines();
DCUpdate();
#else
MyDelay( 150 );
RestoreCurrentFilePos();
DCDisplayAllLines();
#endif
} /* tempMatch */
/*
* IMCloseBracket - handle a ')' being entered in insert mode
*/
int IMCloseBracket( void )
{
int rc,mcol;
linenum mline;
startNewLineUndo();
insertChar( TRUE, FALSE );
if( EditFlags.ShowMatch ) {
ReplaceCurrentLine();
rc = FindMatch( &mline, &mcol );
if( !rc ) {
tempMatch( mline, mcol );
}
GetCurrentLine();
}
GoToColumn( CurrentColumn+1, WorkLine->len+1 );
return( ERR_NO_ERR );
} /* IMCloseBracket */
/*
* getBracketLoc - find a matching '(' for a ')'
*/
static int getBracketLoc( linenum *mline, int *mcol )
{
int rc;
char tmp[3];
int len;
linenum lne;
bool oldmagic = EditFlags.Magic;
EditFlags.Magic = TRUE;
tmp[0] = '\\';
tmp[1] = ')';
tmp[2] = 0;
lne = CurrentLineNumber;
rc = GetFind( tmp, mline, mcol, &len, FINDFL_BACKWARDS|FINDFL_NOERROR);
if( *mline != CurrentLineNumber ) {
EditFlags.Magic = oldmagic;
return( ERR_FIND_NOT_FOUND );
}
if( rc ) {
EditFlags.Magic = oldmagic;
return( rc );
}
/*
* find the matching '('
*/
CurrentLineNumber = *mline;
CurrentColumn = *mcol;
CGimmeLinePtr( CurrentLineNumber, &CurrentFcb, &CurrentLine );
rc = FindMatch( mline, mcol );
EditFlags.Magic = oldmagic;
return( rc );
} /* getBracketLoc */
/*
* findMatchingBrace find '{' for a '}'
*/
static int findMatchingBrace( linenum *mline, int *mcol )
{
int rc;
int col;
linenum sline;
rc = FindMatch( mline, mcol );
if( rc ) {
return( rc );
}
SaveCurrentFilePos();
CurrentLineNumber = *mline;
CurrentColumn = *mcol;
CGimmeLinePtr( CurrentLineNumber, &CurrentFcb, &CurrentLine );
rc = getBracketLoc( &sline, &col );
RestoreCurrentFilePos();
if( !rc ) {
*mline = sline;
*mcol = col;
}
return( ERR_NO_ERR );
} /* findMatchingBrace */
/*
* IMCloseBrace - handle '}' in insert mode
*/
int IMCloseBrace( void )
{
int i,j;
int ts;
fcb *cfcb;
line *cline;
int rc;
int newcol;
linenum mline;
int mcol;
startNewLineUndo();
insertChar( TRUE, FALSE );
newcol = CurrentColumn+1;
if( EditFlags.ShowMatch ) {
ReplaceCurrentLine();
rc = FindMatch( &mline, &mcol );
if( !rc ) {
tempMatch( mline, mcol );
}
GetCurrentLine();
}
if( EditFlags.CMode ) {
i = 0;
while( isspace( WorkLine->data[i] ) ) {
i++;
}
if( WorkLine->data[i] == '}' ) {
/*
* added a {, so:
* find matching }
* find out indentation of that line
* shift current line over to that indentation
* set current indentation to that
*/
ReplaceCurrentLine();
rc = findMatchingBrace( &mline, &mcol );
if( !rc ) {
newcol = VirtualCursorPosition();
CGimmeLinePtr( mline, &cfcb, &cline );
i = FindStartOfALine( cline );
i = GetVirtualCursorPosition( cline->data, i );
j = i - VirtualCursorPosition2( CurrentColumn );
ts = ShiftWidth;
if( j > 0 ) {
ShiftWidth = j;
Shift( CurrentLineNumber, CurrentLineNumber, '>', FALSE );
} else if( j < 0 ) {
ShiftWidth = -j;
Shift( CurrentLineNumber, CurrentLineNumber, '<', FALSE );
}
ShiftWidth = ts;
newcol = 1+RealCursorPosition( j + newcol );
}
GetCurrentLine();
}
}
GoToColumn( newcol, WorkLine->len+1 );
return( ERR_NO_ERR );
} /* IMCloseBrace */
/*
* continueInsertText - continue in insert mode after mouse events
*/
static void continueInsertText( int col, bool overstrike )
{
overStrike = overstrike;
abbrevCnt = 0;
if( !EditFlags.Modeless ) {
UpdateEditStatus();
}
EditFlags.Dotable = TRUE;
EditFlags.NoReplaceSearchString = TRUE;
EditFlags.InsertModeActive = TRUE;
if( col > 1 && CurrentLine->len == 0 ) {
col = 1;
}
GoToColumnOK( col );
GetCurrentLine();
} /* continueInsertText */
/*
* stdInsert - standard insert on a line
*/
static int stdInsert( int col, bool overstrike )
{
int rc;
if( rc = ModificationTest() ) {
return( rc );
}
StartUndoGroup( UndoStack );
CurrentLineReplaceUndoStart();
currLineRepUndo = TRUE;
continueInsertText( col, overstrike );
return( ERR_NO_ERR );
} /* stdInsert */
/*
* DeleteAndInsertText - delete text range, then insert at beginning
*/
int DeleteAndInsertText( int scol, int ecol )
{
int rc,startcol;
StartUndoGroup( UndoStack );
CurrentLineReplaceUndoStart();
currLineRepUndo = TRUE;
if( ecol >= 0 ) {
if( CurrentLine->len > 0 ) {
rc = DeleteBlockFromCurrentLine( scol, ecol, FALSE );
if( !rc ) {
startcol = CurrentColumn;
if( scol > ecol ) {
startcol = ecol+1;
}
if( startcol > WorkLine->len ) {
startcol = WorkLine->len+1;
}
DisplayWorkLine( TRUE );
ReplaceCurrentLine();
rc=GoToColumnOK( startcol );
}
if( rc ) {
CurrentLineReplaceUndoCancel();
EndUndoGroup( UndoStack );
return( rc );
}
} else {
ReplaceCurrentLine();
}
}
continueInsertText( CurrentColumn, FALSE );
return( ERR_NO_ERR );
} /* DeleteAndInsertText */
/*
* insertTextOnOtherLine - open up a different line
*/
static int insertTextOnOtherLine( insert_dir type )
{
char *buffx;
int i,j;
linenum a,b;
bool above_line = FALSE;
if( i = ModificationTest() ) {
return( i );
}
/*
* special case: no data in file
*/
if( CurrentFcb->nullfcb ) {
return( InsertTextAfterCursor() );
}
/*
* get line deletion and undo crap
*/
a = b = CurrentLineNumber+1;
if( type == INSERT_BEFORE ) {
a--;
b--;
above_line = TRUE;
}
/*
* set up for undo
*/
StartUndoGroup( UndoStack );
Modified( TRUE );
StartUndoGroup( UndoStack );
UndoInsert( a, a, UndoStack );
currLineRepUndo = FALSE;
/*
* add extra line, and spaces if needed.
*/
if( EditFlags.AutoIndent ) {
buffx = StaticAlloc();
i = GetAutoIndentAmount( buffx, 0, above_line );
AddNewLineAroundCurrent( buffx,i, type );
StaticFree( buffx );
j = i+1;
} else {
AddNewLineAroundCurrent( NULL,0, type );
j = 1;
}
GoToLineRelCurs( b );
GoToColumn( j,CurrentLine->len+1 );
DCDisplayAllLines();
continueInsertText( CurrentColumn, FALSE );
return( ERR_NO_ERR );
} /* insertTextOnOtherLine */
int InsertTextOnNextLine( void )
{
return( insertTextOnOtherLine( INSERT_AFTER ) );
}
int InsertTextOnPreviousLine( void )
{
return( insertTextOnOtherLine( INSERT_BEFORE ) );
}
int InsertTextAtCursor( void )
{
return( stdInsert( CurrentColumn, FALSE ) );
}
int InsertTextAfterCursor( void )
{
return( stdInsert( CurrentColumn+1, FALSE ) );
}
int InsertTextAtLineStart( void )
{
if( CurrentFile != NULL ) {
return( stdInsert( FindStartOfCurrentLine(), FALSE ) );
}
return( ERR_NO_ERR );
}
int InsertTextAtLineEnd( void )
{
if( CurrentFile != NULL ) {
return( stdInsert( CurrentLine->len+1, FALSE ) );
}
return( ERR_NO_ERR );
}
/*
* DoReplaceText - go into overstrike mode
*/
int DoReplaceText( void )
{
int rc;
rc = stdInsert( CurrentColumn, TRUE );
return( rc );
} /* DoReplaceText */
/*
* InsertLikeLast - go into insert mode, the same mode as last time
*/
int InsertLikeLast( void )
{
bool overstrike;
int rc;
if( EditFlags.WasOverstrike ) {
overstrike = TRUE;
} else {
overstrike = FALSE;
}
rc = stdInsert( CurrentColumn, overstrike );
return( rc );
} /* InsertLikeLast */
typedef struct mode {
struct mode *prev;
bool wasinsert:1;
bool wasoverstrike:1;
} mode;
static mode *modeTail;
/*
* PushMode - push our current mode
*/
void PushMode( void )
{
mode *cmode;
cmode = MemAlloc( sizeof( mode ) );
cmode->prev = modeTail;
modeTail = cmode;
cmode->wasinsert = EditFlags.InsertModeActive;
cmode->wasoverstrike = EditFlags.WasOverstrike;
DoneCurrentInsert( TRUE );
} /* PushMode */
/*
* PopMode - restore to previous mode
*/
int PopMode( void )
{
mode *cmode;
int rc;
rc = ERR_NO_ERR;
if( modeTail == NULL ) {
return( ERR_NO_ERR );
}
cmode = modeTail;
modeTail = cmode->prev;
DoneCurrentInsert( TRUE );
if( cmode->wasinsert ) {
rc = stdInsert( CurrentColumn, cmode->wasoverstrike );
}
MemFree( cmode );
return( rc );
} /* PopMode */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?