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 + -
显示快捷键?