Example #1
0
/*
 * GoToColumnOnCurrentLine - go to a specified column on the current line
 */
vi_rc GoToColumnOnCurrentLine( int colno )
{
    if( CurrentLine == NULL ) {
        return( ERR_NO_FILE );
    }

    if( EditFlags.Modeless ) {
        GoToColumn( colno, CurrentLine->len + 1 );
    } else {
        GoToColumn( colno, CurrentLine->len );
    }

    return( ERR_NO_ERR );

} /* GoToColumnOnCurrentLine */
Example #2
0
/*
 * IMDelete - handle DEL key pressed in insert mode
 */
vi_rc IMDelete( void )
{
    int wlen;

    if( CurrentFile == NULL ) {
        return( ERR_NO_FILE );
    }

    startNewLineUndo();
    wlen = WorkLine->len + 1;
    if( wlen == 0 ) {
        wlen = CurrentLine->len + 1;
    }
    if( EditFlags.Modeless && CurrentPos.column == wlen && CurrentLine->next ) {
        /* go to beginning of next line */
        GoToLineRelCurs( CurrentPos.line + 1 );
        GoToColumnOK( 1 );
        GetCurrentLine();
    } else {
        GoToColumn( CurrentPos.column + 1, wlen );
        if( CurrentPos.column != wlen - 1 || abbrevCnt == 0 ) {
            abbrevCnt++;        /* gets subtracted by IMBackSpace */
        }
    }
    return( IMBackSpace() );

} /* IMDelete */
Example #3
0
/*
 * insertTextOnOtherLine - open up a different line
 */
static vi_rc insertTextOnOtherLine( insert_dir type )
{
    char        *buffx;
    int         i, j;
    linenum     a, b;
    bool        above_line = FALSE;
    vi_rc       rc;

    rc = ModificationTest();
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }
    /*
     * special case: no data in file
     */
    if( CurrentFcb->nullfcb ) {
        return( InsertTextAfterCursor() );
    }

    /*
     * get line deletion and undo crap
     */
    a = b = CurrentPos.line + 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( CurrentPos.column, FALSE );
    return( ERR_NO_ERR );

} /* insertTextOnOtherLine */
Example #4
0
/*
 * IMBackSpace - process the backspace key in insert mode
 */
vi_rc IMBackSpace( void )
{
    char        killedChar, overChar;
    bool        mv_right;
    bool        stay_at_end;
    int         i;

    if( CurrentFile == NULL ) {
        return( ERR_NO_FILE );
    }

    startNewLineUndo();
    if( abbrevCnt > 0 ) {
        abbrevCnt--;
    }
    if( CurrentPos.column == 1 ) {

        if( !EditFlags.WrapBackSpace ) {
            return( ERR_NO_ERR );
        }
        if( CurrentPos.line ==1 ) {
            return( ERR_NO_ERR );
        }
        stay_at_end = FALSE;
        if( WorkLine->len == 0 ) {
            stay_at_end = TRUE;
        }
        doneWithCurrentLine();
        abbrevCnt = 0;
        GoToLineRelCurs( CurrentPos.line - 1 );
        GoToColumnOnCurrentLine( CurrentLine->len );
        mv_right = TRUE;
        if( CurrentLine->len == 0 ) {
            mv_right = FALSE;
        }
        GenericJoinCurrentLineToNext( FALSE );
        if( mv_right && !stay_at_end ) {
            GoToColumnOnCurrentLine( CurrentPos.column + 1 );
        }
        if( stay_at_end ) {
            GoToColumnOK( CurrentLine->len + 1 );
        }
        CurrentLineReplaceUndoStart();
        currLineRepUndo = TRUE;
        GetCurrentLine();
        return( ERR_NO_ERR );
    }
    killedChar = WorkLine->data[CurrentPos.column - 2];
    overChar = WorkLine->data[CurrentPos.column - 1];
    for( i = CurrentPos.column - 1; i <= WorkLine->len + 1; i++ ) {
        WorkLine->data[i - 1] = WorkLine->data[i];
    }
    WorkLine->len--;
    GoToColumn( CurrentPos.column - 1, WorkLine->len + 1 );
    DisplayWorkLine( SSKillsFlags( killedChar ) || SSKillsFlags( overChar ) );
    return( ERR_NO_ERR );

} /* IMBackSpace */
Example #5
0
/*
 * EnterHexKey - enter a hexidecimal key stroke and insert it into the text
 */
vi_rc EnterHexKey( void )
{
    int         i;
    char        st[MAX_STR], val;
    vi_rc       rc;
    const char  *ptr;

    rc = ModificationTest();
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }
    if( CurrentLine->len >= EditVars.MaxLine - 1 ) {
        return( ERR_LINE_FULL );
    }

    rc = PromptForString( "Enter the number of char to insert:", st, sizeof( st ) - 1, NULL );
    if( rc != ERR_NO_ERR ) {
        if( rc == NO_VALUE_ENTERED ) {
            return( ERR_NO_ERR );
        }
        return( rc );
    }

    /*
     * get value
     */
    ptr = SkipLeadingSpaces( st );
    val = (char)strtol( ptr, NULL, 0 );
    if( val == '\0' ) {
        return( ERR_INVALID_VALUE );
    }

    /*
     * build undo record
     */
    StartUndoGroup( UndoStack );
    CurrentLineReplaceUndoStart();
    CurrentLineReplaceUndoEnd( true );
    EndUndoGroup( UndoStack );

    /*
     * add the char
     */
    GetCurrentLine();
    for( i = WorkLine->len; i >= CurrentPos.column - 1; i-- ) {
        WorkLine->data[i + 1] = WorkLine->data[i];
    }
    WorkLine->data[CurrentPos.column - 1] = val;
    WorkLine->len++;
    DisplayWorkLine( true );
    if( CurrentPos.column < WorkLine->len ) {
        GoToColumn( CurrentPos.column + 1, WorkLine->len + 1 );
    }
    ReplaceCurrentLine();
    EditFlags.Dotable = true;
    return( ERR_NO_ERR );

} /* EnterHexKey */
Example #6
0
/*
 * insertChar - insert a char into the working line
 */
static vi_rc insertChar( bool add_to_abbrev, bool move_to_new_col )
{
    if( WorkLine->len == EditVars.MaxLine ) {
        return( ERR_NO_ERR );
    }
    addChar( LastEvent );
    if( move_to_new_col ) {
        GoToColumn( CurrentPos.column + 1, WorkLine->len + 1 );
    }
    if( abbrevCnt < sizeof( abbrevBuff ) && add_to_abbrev ) {
        abbrevBuff[abbrevCnt++] = LastEvent;
    }
    checkWrapMargin();
    return( ERR_NO_ERR );

} /* insertChar */
Example #7
0
/*
 * IMChar - insert a character in insert mode
 */
vi_rc IMChar( void )
{
    if( CurrentFile == NULL ) {
        return( ERR_NO_ERR );
    }
    CurrentFile->need_autosave = TRUE;

    startNewLineUndo();
    if( EditFlags.EscapedInsertChar ) {
        DisplayWorkLine( SSKillsFlags( LastEvent ) ||
                         SSKillsFlags( WorkLine->data[CurrentPos.column - 1] ) );
        WorkLine->data[CurrentPos.column - 1] = LastEvent;
        GoToColumn( CurrentPos.column + 1, WorkLine->len + 1 );
        EditFlags.EscapedInsertChar = FALSE;
        return( ERR_NO_ERR );
    }

    return( insertChar( TRUE, TRUE ) );

} /* IMChar */
Example #8
0
/*
 * IMCloseBracket - handle a ')' being entered in insert mode
 */
vi_rc IMCloseBracket( void )
{
    vi_rc       rc;
    i_mark      pos;

    startNewLineUndo();
    insertChar( TRUE, FALSE );
    if( EditFlags.ShowMatch ) {

        ReplaceCurrentLine();
        rc = FindMatch( &pos );
        if( rc == ERR_NO_ERR ) {
            tempMatch( &pos );
        }
        GetCurrentLine();

    }
    GoToColumn( CurrentPos.column + 1, WorkLine->len + 1 );
    return( ERR_NO_ERR );

} /* IMCloseBracket */
Example #9
0
/*
 * CheckAbbrev - look for an abbreviation, and expand it
 */
bool CheckAbbrev( const char *data, int *ccnt )
{
    int         i, j, owl, col;
    alias_list  *curr;
    size_t      len;

    if( EditFlags.Modeless ) {
        return( false );
    }

    /*
     * get the current string, and matching alias
     */
    len = *ccnt;
    *ccnt = 0;
    if( len == 0 ) {
        return( false );
    }
    curr = checkGenericAlias( data, len, abHead );
    if( curr == NULL ) {
        return( false );
    }

    i = CurrentPos.column - 1 - len;
    j = CurrentPos.column - 2;

    /*
     * replace with full form
     */
    owl = WorkLine->len;
    WorkLine->len = ReplaceSubString( WorkLine->data, WorkLine->len,
                                      i, j, curr->expand, strlen( curr->expand ) );
    col = CurrentPos.column + WorkLine->len - owl;
    GoToColumn( col, WorkLine->len + 1 );
    return( true );

} /* CheckAbbrev */
Example #10
0
/*
 * IMCloseBrace - handle '}' in insert mode
 */
vi_rc IMCloseBrace( void )
{
    int         i, j;
    int         ts;
    fcb         *cfcb;
    line        *cline;
    vi_rc       rc;
    int         newcol;
    i_mark      pos;

    startNewLineUndo();
    insertChar( TRUE, FALSE );
    newcol = CurrentPos.column + 1;
    if( EditFlags.ShowMatch ) {
        ReplaceCurrentLine();
        rc = FindMatch( &pos );
        if( rc == ERR_NO_ERR ) {
            tempMatch( &pos );
        }
        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( &pos );
            if( rc == ERR_NO_ERR ) {
                newcol = VirtualColumnOnCurrentLine( CurrentPos.column );
                CGimmeLinePtr( pos.line, &cfcb, &cline );
                i = FindStartOfALine( cline );
                i = GetVirtualCursorPosition( cline->data, i );
                j = i - VirtualColumnOnCurrentLine( CurrentPos.column );
                ts = EditVars.ShiftWidth;
                if( j > 0 ) {
                    EditVars.ShiftWidth = j;
                    Shift( CurrentPos.line, CurrentPos.line, '>', FALSE );
                } else if( j < 0 ) {
                    EditVars.ShiftWidth = -j;
                    Shift( CurrentPos.line, CurrentPos.line, '<', FALSE );
                }
                EditVars.ShiftWidth = ts;
                newcol = 1 + RealColumnOnCurrentLine( j + newcol );
            }
            GetCurrentLine();
        }
    }
    GoToColumn( newcol, WorkLine->len + 1 );
    return( ERR_NO_ERR );

} /* IMCloseBrace */
Example #11
0
/*
 * IMTabs - handle tabs in insert mode
 */
vi_rc 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 >= EditVars.MaxLine ) {
                break;
            }
            addChar( '\t' );
            GoToColumn( CurrentPos.column + 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 = VirtualColumnOnCurrentLine( CurrentPos.column );
        if( CurrentPos.column - 1 == WorkLine->len && !EditFlags.Modeless ) {
            add = 1;
        } else {
            add = 0;
        }
        j = 0;
        back = FALSE;
        switch( LastEvent ) {
        case VI_KEY( SHIFT_TAB ):
            j = ShiftTab( vc, EditVars.TabAmount );
            back = TRUE;
            break;
        case VI_KEY( CTRL_D ):
            j = ShiftTab( vc, EditVars.ShiftWidth );
            back = TRUE;
            break;
        case VI_KEY( TAB ):
            j = Tab( vc, EditVars.TabAmount );
            break;
        case VI_KEY( CTRL_T ):
            j = Tab( vc, EditVars.ShiftWidth );
            break;
        }
        if( back && (vc - j < 1) ) {
            break;
        } else if( VirtualLineLen( WorkLine->data ) + j >= EditVars.MaxLine ) {
            break;
        }

        /*
         * create a real version of the line
         */
        buff = StaticAlloc();
        ExpandTabsInABufferUpToColumn( CurrentPos.column - 1, WorkLine->data, WorkLine->len, buff, EditVars.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, EditVars.MaxLine );
        } else {
            strcpy( WorkLine->data, buff );
        }
        WorkLine->len = strlen( WorkLine->data );
        StaticFree( buff );
        cp = RealColumnOnCurrentLine( cp ) + add;
        GoToColumn( cp, WorkLine->len + 1 );
        DisplayWorkLine( FALSE );
        break;
    }
    return( ERR_NO_ERR );

} /* IMTabs */
Example #12
0
/*
 * IMCursorKey - handle cursor keys in insert mode
 */
vi_rc IMCursorKey( void )
{
    int         wlen;
    event       *ev;
    int         type;

    wlen = WorkLine->len + 1;
    if( wlen == 0 ) {
        wlen = CurrentLine->len + 1;
    }

    /*
     * handle movement on the same line
     */
    switch( LastEvent ) {
    case VI_KEY( HOME ):
        GoToColumn( 1, wlen );
        abbrevCnt = 0;
        return( ERR_NO_ERR );
    case VI_KEY( END ):
        GoToColumnOK( wlen );
        abbrevCnt = 0;
        return( ERR_NO_ERR );
    case VI_KEY( LEFT ):
        GoToColumn( CurrentPos.column - 1, wlen );
        abbrevCnt = 0;
        return( ERR_NO_ERR );
    case VI_KEY( RIGHT ):
        GoToColumn( CurrentPos.column + 1, wlen );
        abbrevCnt = 0;
        return( ERR_NO_ERR );
    }

    /*
     * handle movement that leaves the current line
     */
    ev = &EventList[LastEvent];
    if( EditFlags.Modeless ) {
        type = ev->alt_b.type;
    } else {
        type = ev->b.type;
    }

    if( needNewUndoForLine ) {
        if( type == EVENT_REL_MOVE || type == EVENT_ABS_MOVE ) {
            DoMove( ev );
        } else {
            if( EditFlags.Modeless ) {
                ev->alt_rtn.old();
            } else {
                ev->rtn.old();
            }
        }
        return( ERR_NO_ERR );
    }
    if( CurrentPos.column > WorkLine->len ) {
        GoToColumnOK( WorkLine->len + 1 );
    }
    doneWithCurrentLine();
    if( type == EVENT_REL_MOVE || type == EVENT_ABS_MOVE ) {
        DoMove( ev );
    } else {
        if( EditFlags.Modeless ) {
            ev->alt_rtn.old();
        } else {
            ev->rtn.old();
        }
    }
    needNewUndoForLine = TRUE;
    abbrevCnt = 0;
    return( ERR_NO_ERR );

} /* IMCursorKey */
Example #13
0
/*
 * insertGenericSavebuf - insert contents of a savebuf before/after current pos
 */
static vi_rc insertGenericSavebuf( int buf, bool afterflag )
{
#ifdef __WIN__
    savebuf     clip;
#endif
    savebuf     *tmp;
    fcb_list    fcblist;
    fcb         *end;
    int         i, scol, len;
    int         maxCursor;
    vi_rc       rc;

    rc = ModificationTest();
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }

    if( EditFlags.Modeless ) {
        DeleteSelectedRegion();
        SelRgn.selected = false;
    }

#ifdef __WIN__
    if( buf == CLIPBOARD_SAVEBUF ) {
        rc = GetClipboardSavebuf( &clip );
        if( rc != ERR_NO_ERR ) {
            return( rc );
        }
        tmp = &clip;
    } else
#endif
    if( buf >= MAX_SAVEBUFS ) {
        tmp = &SpecialSavebufs[buf - MAX_SAVEBUFS];
    } else {
        tmp = &Savebufs[buf];
    }
    switch( tmp->type ) {
    case SAVEBUF_NOP:
        rc = ERR_EMPTY_SAVEBUF;
        break;
    case SAVEBUF_LINE:
        /*
         * get starting data
         */
        len = strlen( tmp->u.data );
        if( len + CurrentLine->len >= EditVars.MaxLine ) {
            rc = ERR_LINE_FULL;
            break;
        }
        if( afterflag ) {
            scol = CurrentPos.column;
        } else {
            scol = CurrentPos.column - 1;
        }
        CurrentLineReplaceUndoStart();
        GetCurrentLine();

        /*
         * open up line and copy in data
         */
        if( WorkLine->len == 0 ) {
            scol = 0;
        }
        for( i = WorkLine->len; i >= scol; i-- ) {
            WorkLine->data[i + len] = WorkLine->data[i];
        }
        for( i = 0; i < len; i++ ) {
            WorkLine->data[i + scol] = tmp->u.data[i];
        }
        WorkLine->len += len;
        DisplayWorkLine( true );
        ReplaceCurrentLine();
        CurrentLineReplaceUndoEnd( true );
        scol += len + 1;

        maxCursor = CurrentLine->len;
        if( EditFlags.Modeless ) {
            maxCursor++;
        }
        if( scol > maxCursor ) {
            scol = maxCursor;
        }
        rc = GoToColumn( scol, maxCursor );
        break;

    case SAVEBUF_FCBS:
        fcblist.head = NULL;
        fcblist.tail = NULL;
        end = tmp->u.fcbs.tail->next;
        tmp->u.fcbs.tail->next = NULL;
        CreateDuplicateFcbList( tmp->u.fcbs.head, &fcblist );
        tmp->u.fcbs.tail->next = end;

        if( !EditFlags.LineBased ) {
            rc = InsertLinesAtCursor( &fcblist, UndoStack );
        } else {
            if( afterflag) {
                rc = InsertLines( CurrentPos.line, &fcblist, UndoStack );
            } else {
                rc = InsertLines( CurrentPos.line - 1, &fcblist, UndoStack );
            }
        }
        break;
    }
#ifdef __WIN__
    if( tmp == &clip ) {
        freeSavebuf( &clip );
    }
#endif

    EditFlags.Dotable = true;

    return( rc );

} /* insertGenericSavebuf */
Example #14
0
/*
 * GoToColumnOK - go to a specified column that does not need a max check
 */
vi_rc GoToColumnOK( int colno )
{
    return( GoToColumn( colno, colno ) );

} /* GoToColumnOK */
Example #15
0
/*
 * GenericJoinCurrentLineToNext
 */
vi_rc GenericJoinCurrentLineToNext( bool remsp )
{
    line        *nline = CurrentLine;
    fcb         *nfcb = CurrentFcb;
    int         i, j, k;
    vi_rc       rc;

    /*
     * get next line data
     */
    rc = CGimmeNextLinePtr( &nfcb, &nline );
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }
    if( CurrentLine->len + nline->len + 1 >= EditVars.MaxLine ) {
        return( ERR_LINE_FULL );
    }

    /*
     * now, copy in the data
     */
    StartUndoGroup( UndoStack );
    CurrentLineReplaceUndoStart();
    CurrentLineReplaceUndoEnd( true );
    GetCurrentLine();

    if( remsp ) {
        while( WorkLine->len > 0 && WorkLine->data[WorkLine->len - 1] == ' ' ) {
            WorkLine->data[WorkLine->len - 1] = 0;
            WorkLine->len--;
        }
        j = FindStartOfALine( nline ) - 1;
	    k = 0;
        if( !(j == 0 && nline->data[0] == ' ') ) {
            if( WorkLine->len != 0 ) {
                WorkLine->data[WorkLine->len] = ' ';
                k = WorkLine->len + 1;
            }
            for( i = j; i <= nline->len; i++ ) {
                WorkLine->data[k + i - j] = nline->data[i];
            }
        }
    } else {
        k = WorkLine->len;
        for( i = 0; i <= nline->len; i++ ) {
            WorkLine->data[k + i] = nline->data[i];
        }
    }
    WorkLine->len = strlen( WorkLine->data );
    ReplaceCurrentLine();

    /*
     * delete next line
     */
    rc = DeleteLineRange( CurrentPos.line + 1, CurrentPos.line + 1, 0 );
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }
    EndUndoGroup( UndoStack );
    if( remsp ) {
        if( k < 2 ) {
            k = 2;
        }
        rc = GoToColumn( k - 1, CurrentLine->len );
        if( rc != ERR_NO_ERR ) {
            return( rc );
        }
    }
    DCDisplayAllLines();
    return( ERR_NO_ERR );

} /* GenericJoinCurrentLineToNext */
Example #16
0
vi_rc Change( range *r )
{
    int         scol, ecol;
    int         tmp;
    vi_rc       rc;
    vi_key      key;
#ifndef __WIN__
    int         vecol;
#endif

    /*
     * change line ranges
     */
    if( r->start.line != r->end.line ) {
        StartUndoGroup( UndoStack );
        if( !r->line_based ) {
            rc = Cut( r->start.line, r->start.column, r->end.line, r->end.column, true );
            r->end.column = -1;
            scol = -1;
            ecol = -1;
        } else {
            if( r->start.line == CurrentPos.line ) {
                r->start.line++;
            } else {
                r->end.line--;
            }
            if( r->start.line <= r->end.line ) {
                rc = DeleteLineRange( r->start.line, r->end.line, 0 );
                if( rc != ERR_NO_ERR ) {
                    EndUndoGroup( UndoStack );
                    return( rc );
                }
            }
            scol = FindStartOfCurrentLine() - 1;
            ecol = CurrentLine->len - 1;
        }
        DCDisplayAllLines();
        rc = DeleteAndInsertText( scol, ecol );
        EndUndoGroup( UndoStack );
        return( rc );
    }

    /*
     * change text on current line
     */
    rc = ERR_NO_ERR;
    GoToLineNoRelCurs( r->start.line );
    ecol = r->end.column;
    scol = r->start.column;
#ifdef __WIN__
//    GetCurrentLine();
    strcpy( WorkLine->data, CurrentLine->data );
    tmp = WorkLine->data[ecol];
    WorkLine->data[ecol] = '$';
#else
    vecol = VirtualColumnOnCurrentLine( ecol + 1 );
    vecol--;
    ExpandTabsInABuffer( CurrentLine->data, CurrentLine->len, WorkLine->data, EditVars.MaxLine + 1 );
    WorkLine->len = strlen( WorkLine->data );
    tmp = WorkLine->data[vecol];
    WorkLine->data[vecol] = '$';
#endif
    if( WorkLine->len == 0 ) {
        WorkLine->data[1] = '\0';
    }
    EditFlags.InsertModeActive = true;
    GoToColumn( scol + 1, CurrentLine->len );
    EditFlags.InsertModeActive = false;
    DisplayWorkLine( true );
    UnselectRegion();
    DCUpdate();
#ifndef __WIN__
    HiliteAColumnRange( CurrentPos.line, scol, ecol );
#endif

    /*
     * now, get ready to do change
     */
    key = GetNextEvent( false );
#ifdef __WIN__
    WorkLine->data[ecol] = tmp;
#else
    WorkLine->data[vecol] = tmp;
#endif
    DisplayWorkLine( true );
    if( key == VI_KEY( ESC ) && !EditFlags.ChangeLikeVI ) {
        WorkLine->len = -1;
        GoToColumn( scol + 1, CurrentLine->len );
    } else {
        KeyAdd( key );
        rc = DeleteAndInsertText( scol, ecol );
    }
    return( rc );

} /* Change */