Exemplo n.º 1
0
/*
 * ColorFind - find string and color it
 */
vi_rc ColorFind( char *data, find_type findfl )
{
    vi_rc       rc;
    int         len;
    char        *buff;
    i_mark      pos;

    /*
     * get search string and flags
     */
    buff = StaticAlloc();
    if( (len = NextWordSlash( data, buff ) ) <= 0 ) {
        StaticFree( buff );
        return( ERR_INVALID_FIND_CMD );
    }

    /*
     * go get the match
     */
    GoToLineNoRelCurs( 1 );
    rc = GetFind( buff, &pos, &len, FINDFL_FORWARD | findfl );
    if( rc == ERR_NO_ERR ) {
        pos.column += 1;
        JumpTo( &pos );
        DCUpdate();
#ifndef __WIN__
        // Windows selects instead
        HiliteAColumnRange( pos.line, pos.column, pos.column + len - 1 );
#endif
        EditFlags.ResetDisplayLine = TRUE;
    }
    StaticFree( buff );
    return( rc );

} /* ColorFind */
Exemplo n.º 2
0
void DCUpdateAll( void )
{
    info        *curr, *info;
    bool        saved_cinfo;

    if( EditFlags.Quiet ) {
        return;
    }

    saved_cinfo = false;
    info = CurrentInfo;
    for( curr = info; curr != NULL; curr = curr->next ) {
        if( curr->CurrentFile->needs_display ) {
            if( !saved_cinfo ) {
                SaveCurrentInfo();
                saved_cinfo = true;
            }
            RestoreInfo( curr );
            DCUpdate();
            curr->CurrentFile->needs_display = false;
        }
    }
    if( saved_cinfo ) {
        RestoreInfo( info );
        SetWindowCursor();
    }
}
Exemplo n.º 3
0
/*
 * LocateCmd - parse a locate command (format: locate r,c[,len])
 */
vi_rc LocateCmd( const char *data )
{
    char        tmp[MAX_STR];
    linenum     r;
    int         c;
    int         len;

#ifdef __WIN__
    if( BAD_ID( current_window_id ) ) {
        return( ERR_INVALID_LOCATE );
    }
#endif
    data = GetNextWord1( data, tmp );
    if( *tmp == '\0' ) {
        return( ERR_INVALID_LOCATE );
    }
    r = atol( tmp );
    data = GetNextWord1( data, tmp );
    if( *tmp == '\0' ) {
        return( ERR_INVALID_LOCATE );
    }
    c = atoi( tmp );

    // real selection length
    while( isspace( *data ) ) {
        data++;
    }
    len = 0;
    if( *data != 0 ) {
        data = GetNextWord1( data, tmp );
        if( *tmp == '\0' ) {
            return( ERR_INVALID_LOCATE );
        }
        len = atoi( tmp );
    }

    GoToLineNoRelCurs( r );

    c = RealColumnOnCurrentLine( c );
    GoToColumnOnCurrentLine( c + len );

#ifdef __WIN__
    // likely only called by dde, which doesn't use event loop,
    // so must ensure cache ok and set cursor here

    DCInvalidateAllLines();
    DCDisplayAllLines();
    DCUpdate();
    SetWindowCursor();
    SetWindowCursorForReal();
#endif

    if( len > 0 ) {
        SetSelRegionCols( CurrentPos.line, c, c + len - 1 );
    }
    return( ERR_NO_ERR );

} /* LocateCmd */
Exemplo n.º 4
0
/*
 * HilightSearchString - bring a search string into view and hilight it
 */
void HilightSearchString( i_mark *pos, int slen )
{
    if( slen > 0 ) {
        GoToColumnOK( pos->column + slen );
    }
    GoToColumnOK( pos->column + 1 );
    if( slen > 0 ) {
#ifdef __WIN__
        SetSelRegionCols( pos->line, pos->column + 1, pos->column + slen );
        DCUpdate();
#else
        DCUpdate();
        HiliteAColumnRange( pos->line, pos->column, pos->column + slen - 1 );
#endif
    }
    EditFlags.ResetDisplayLine = TRUE;

} /* HilightSearchString */
Exemplo n.º 5
0
/*
 * ResetDisplayLine - reset display line, if required (after hilight)
 */
void ResetDisplayLine( void )
{
    if( EditFlags.ResetDisplayLine ) {
        memcpy( WorkLine->data, CurrentLine->data, CurrentLine->len + 1 );
        WorkLine->len = CurrentLine->len;
        DisplayWorkLine( false );
        DCUpdate();
        WorkLine->len = -1;
        EditFlags.ResetDisplayLine = false;
    }

} /* ResetDisplayLine */
Exemplo n.º 6
0
/*
 * tempMatch - show a temporary match
 */
static void tempMatch( i_mark *pos )
{
    SaveCurrentFilePos();
    GoToLineNoRelCurs( pos->line );
    GoToColumnOK( pos->column );
#ifdef __WIN__
    DCDisplayAllLines();
    DCUpdate();

    SetWindowCursorForReal();
    MyDelay( 150 );
    RestoreCurrentFilePos();

    DCDisplayAllLines();
    DCUpdate();
#else
    MyDelay( 150 );
    RestoreCurrentFilePos();
    DCDisplayAllLines();
#endif

} /* tempMatch */
Exemplo n.º 7
0
/*
 * DoMove - handle a movement command
 */
vi_rc DoMove( event *ev )
{
    range       range;
    vi_rc       rc;
    int         curcol;
    int         type;

    defaultRange( &range );
    if( EditFlags.Modeless ) {
        rc = ev->alt_rtn.move( &range, GetRepeatCount() );
        type = ev->alt_b.type;
    } else {
        rc = ev->rtn.move( &range, GetRepeatCount() );
        type = ev->b.type;
    }
    if( rc == ERR_NO_ERR ) {
        curcol = CurrentPos.column;
        if( range.start.line != CurrentPos.line ) {
            if( type == EVENT_REL_MOVE ) {
                GoToLineRelCurs( range.start.line );
            } else {
                curcol = -1;
                MemorizeCurrentContext();
                GoToLineNoRelCurs( range.start.line );
            }
        }
        if( curcol != range.start.column ) {
            GoToColumnOK( range.start.column );
        }
#ifndef __WIN__
        if( range.highlight ) {
            // don't handle multi-line highlights yet
            assert( range.hi_start.line == range.hi_end.line );
            EditFlags.ResetDisplayLine = true;
            DCUpdate();
            HiliteAColumnRange( range.hi_start.line,
                range.hi_start.column, range.hi_end.column );
        }
#endif
    }
    return( rc );
}
Exemplo n.º 8
0
/*
 * ResizeWindow - give a window a new size
 */
vi_rc ResizeWindow( window_id wid, windim x1, windim y1, windim x2, windim y2, bool scrflag )
{
    window      *oldw;
//    int         bt, k;
//    char        *txt, *tptr;
//    char        *ot;
//    int         i, j;

    oldw = WINDOW_FROM_ID( wid );
    AccessWindow( oldw );

    if( !ValidDimension( x1, y1, x2, y2, oldw->has_border ) ) {
        ReleaseWindow( oldw );
        return( ERR_WIND_INVALID );
    }
    RestoreOverlap( wid, scrflag );

    AllocWindow( wid, x1, y1, x2, y2, oldw->has_border, oldw->has_gadgets, true,
            oldw->border_color1, oldw->border_color2, oldw->text_color, oldw->background_color );
    MarkOverlap( wid );

    /*
     * display the new text
     */
    ClearWindow( wid );
    if( oldw->title != NULL ) {
        WindowTitle( wid, oldw->title );
    } else {
        DrawBorder( wid );
    }
    DCResize( CurrentInfo );
    DCDisplayAllLines();
    DCUpdate();

    FreeWindow( oldw );
    ReleaseWindow( WINDOW_FROM_ID( wid ) );

    return( ERR_NO_ERR );

} /* ResizeWindow */
Exemplo n.º 9
0
/*
 * InsertTextForSpecialKey - insert text for ^O, ALT_O
 */
void InsertTextForSpecialKey( vi_key event, char *buff )
{
    linenum     line;
    int         type;

    if( CurrentFile == NULL ) {
        return;
    }

    line = CurrentPos.line;
    type = INSERT_BEFORE;
    if( event == VI_KEY( CTRL_O ) ) {
        type = INSERT_AFTER;
        line += 1;
    }
    Modified( true );
    StartUndoGroup( UndoStack );
    UndoInsert( line, line, UndoStack );
    AddNewLineAroundCurrent( buff, strlen( buff ), type );
    EndUndoGroup( UndoStack );
    DCDisplayAllLines();
    DCUpdate();

} /* InsertTextForSpecialKey */
Exemplo n.º 10
0
/*
 * UpdateDrag - update selected region
 */
void UpdateDrag( window_id id, int win_x, int win_y )
{
    int         nx, ny, height;
    int         moveCursor;

    SelRgn.selected = TRUE;
    moveCursor = 0;
    height = WindowAuxInfo( CurrentWindow, WIND_INFO_TEXT_LINES );
#ifdef __WIN__
    if( id == CurrentWindow && InsideWindow( id, MouseX, MouseY ) ) {
#else
    if( id == CurrentWindow && InsideWindow( id, win_x, win_y ) ) {
#endif
        ny = LeftTopPos.line + win_y - 1;
        if( ny > CurrentFile->fcbs.tail->end_line ) {
            ny = CurrentFile->fcbs.tail->end_line;
            moveCursor = 1;
        } else if( ny < 1 ) {
            ny = 1;
            moveCursor = -1;
        }
        GoToLineRelCurs( ny );
        win_x += LeftTopPos.column;
        nx = RealColumnOnCurrentLine( win_x );
        GoToColumnOnCurrentLine( nx );
    } else {
#ifndef __WIN__
        if( MouseRow >= WindowAuxInfo( CurrentWindow, WIND_INFO_Y2 ) ) {
            GoToLineRelCurs( LeftTopPos.line + height );
        } else if( MouseRow <= WindowAuxInfo( CurrentWindow, WIND_INFO_Y1 ) ) {
            GoToLineRelCurs( LeftTopPos.line - 1 );
        } else if( MouseCol <= WindowAuxInfo( CurrentWindow, WIND_INFO_X1 ) ) {
            GoToColumnOnCurrentLine( LeftTopPos.column - 1 );
        } else if( MouseCol >= WindowAuxInfo( CurrentWindow, WIND_INFO_X2 ) ) {
            GoToColumnOnCurrentLine( LeftTopPos.column + WindowAuxInfo( CurrentWindow, WIND_INFO_WIDTH ));
        }
#else
        {
            RECT            rect;

            GetClientRect( CurrentWindow, &rect );
            if( MouseY > rect.bottom ) {
                ny = LeftTopPos.line + height;
                if( ny > CurrentFile->fcbs.tail->end_line ) {
                    ny = CurrentFile->fcbs.tail->end_line;
                    moveCursor = 1;
                }
                GoToLineRelCurs( ny );
            } else if( MouseY < 0 ) {
                ny = LeftTopPos.line - 1;
                if( ny < 1 ) {
                    ny = 1;
                    moveCursor = -1;
                }
                GoToLineRelCurs( ny );
            } else if( MouseX < 0 ) {
                GoToColumnOnCurrentLine( LeftTopPos.column - 1 );
            } else if( MouseX > rect.right ) {
                if( EditFlags.Modeless ) {
                    GoToColumnOnCurrentLine( 1 + LeftTopPos.column +
                        WindowAuxInfo( CurrentWindow, WIND_INFO_TEXT_COLS ) );
                } else {
                    GoToColumnOnCurrentLine( LeftTopPos.column +
                        WindowAuxInfo( CurrentWindow, WIND_INFO_TEXT_COLS ) );
                }
            }
        }
#endif
    }

    if( moveCursor == -1 ) {
        GoToColumnOnCurrentLine( 1 );
    } else if( moveCursor == 1 ) {
        GoToColumnOnCurrentLine( CurrentFile->fcbs.tail->lines.tail->len + 1 );
    }

} /* UpdateDrag */

/*
 * UpdateCursorDrag - update drag after cursor movement
 */
void UpdateCursorDrag( void )
{
    if( !EditFlags.Dragging ) {
        return;
    }
    if( SelRgn.end.line == CurrentPos.line && SelRgn.end.column == CurrentPos.column ) {
        return;
    }
#ifndef __WIN__
    markRegion( FALSE );
#endif
    SelRgn.end = CurrentPos;
    if( EditFlags.LineBased == FALSE ) {
        SelRgn.lines = FALSE;
    } else if( SelRgn.start.line != SelRgn.end.line ) {
        SelRgn.lines = TRUE;
    } else if( SelRgn.start.column == SelRgn.end.column ) {
        SelRgn.lines = TRUE;
    } else {
        SelRgn.lines = FALSE;
    }
    updateRegion();

} /* UpdateCursorDrag */

/*
 * SetSelRegionCols - set selected region on a line
 */
void SetSelRegionCols( linenum sl, int sc, int ec )
{
    vi_rc   rc;
    line    *line;
    fcb     *fcb;
    char    *data;

    SelRgn.lines = FALSE;
    SelRgn.selected = TRUE;
    SelRgn.start.line = SelRgn.end.line = sl;
    SelRgn.start.column = sc;
    SelRgn.end.column = ec + 1;
    SelRgn.start_col_v = 0;
    rc = CGimmeLinePtr( sl, &fcb, &line );
    if( rc == ERR_NO_ERR ) {
        data = ( line->u.ld.nolinedata ) ? WorkLine->data : line->data;
        SelRgn.start_col_v = GetVirtualCursorPosition( data, SelRgn.start.column );
    }

    updateRegion();
    DCUpdate();

} /* SetSelRegionCols */
Exemplo n.º 11
0
/*
 * MainWindowProc - procedure for main (root) window
 */
WINEXPORT LRESULT CALLBACK MainWindowProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
    RECT        rect;
    vi_rc       rc;
    HANDLE      hfileinfo;
    int         cnt, i;
    char        *buff;

    switch( msg ) {
    case WM_CREATE:
        Root = hwnd;
        GetClientRect( hwnd, &rect );
        EditContainer = CreateContainerWindow( &rect );
        InitWindows();
        DragAcceptFiles( hwnd, TRUE );
        timerID = SetTimer( hwnd, TIMER_ID, 60L * 1000L, NULL );
        break;
    case WM_DROPFILES:
        hfileinfo = (HANDLE) wparam;
        cnt = DragQueryFile( hfileinfo, (UINT)-1, NULL, 0 );
        buff = alloca( FILENAME_MAX + 2 );   /* we add a " at the beginning and at the end so we can handle path- and filenames with spaces */
        if( buff != NULL ) {
            buff[0] = '"';      /* one " at the beginning of the filename */
            for( i = 0; i < cnt; i++ ) {
                if( DragQueryFile( hfileinfo, i, buff + 1, FILENAME_MAX ) == (UINT)-1 ) {
                    break;
                }
                strcat( buff, "\"" );
                rc = EditFile( buff, FALSE );
                if( rc > ERR_NO_ERR ) {
                    Error( GetErrorMsg( rc ) );
                }
            }
        }
        DragFinish( hfileinfo );
        break;
    case WM_TIMER:
        UpdateStatusWindow();
        break;
    case WM_KEYDOWN:
        if( WindowsKeyPush( wparam, HIWORD( lparam ) ) ) {
            return( 0 );
        }
        break;
    case WM_SIZE:
        DefFrameProc( hwnd, EditContainer, msg, wparam, lparam );
        RootState = wparam;
        if( wparam != SIZE_MINIMIZED ) {
            ResizeRoot();
            GetWindowRect( hwnd, &RootRect );
            if( wparam != SIZE_MAXIMIZED ) {
                RootState = 0;
            }
        }
        return( 0 );
    case WM_MOVE:
        DefFrameProc( hwnd, EditContainer, msg, wparam, lparam );
        if( RootState != SIZE_MINIMIZED ) {
            GetWindowRect( hwnd, &RootRect );
        }
        return( 0 );
    case WM_ACTIVATEAPP:
        if( BAD_ID( CurrentWindow ) ) {
            break;
        }
        SetFocus( Root );
#if 0
        if( !wparam ) {
            InactiveWindow( CurrentWindow );
        } else {
            SendMessage( EditContainer, WM_MDIACTIVATE, (WPARAM)CurrentWindow, 0L );
        }
#endif
        if( wparam ) {
            ResetEditWindowCursor( CurrentWindow );
        } else {
            GoodbyeCursor( CurrentWindow );
        }
        break;
    case WM_MOUSEACTIVATE:
        SetFocus( hwnd );
        return( MA_ACTIVATE );
    case WM_SETFOCUS:
        if( BAD_ID( CurrentWindow ) ) {
            break;
        }
        if( !IsIconic( CurrentWindow ) ) {
            SendMessage( EditContainer, WM_MDIACTIVATE, (WPARAM)CurrentWindow, 0L );
            DCUpdate();
            SetWindowCursor();
            SetWindowCursorForReal();
            return( 0 );
        }
        break;
    case WM_NCLBUTTONDBLCLK:
        break;
    case WM_COMMAND:
        if( LOWORD( wparam ) > 0xF000 ) {
            break;
        } else {
            rc = MenuCommand( LOWORD( wparam ) );
            if( rc != MENU_COMMAND_NOT_HANDLED ) {
                DCUpdateAll();
                if( rc > ERR_NO_ERR ) {
                    char        *msg;
                    msg = GetErrorMsg( rc );
                    Error( msg );
                }
            }
            SetWindowCursor();
        }
        return( 0 );
    case WM_INITMENU:
        if( (HMENU)wparam == GetMenu( hwnd ) ) {
            HandleInitMenu( (HMENU)wparam );
        } else {
            ResetMenuBits();
        }
        break;
    case WM_MENUSELECT:
        HandleMenuSelect( wparam, lparam );
        break;
    case WM_ENDSESSION:
        if( wparam ) {
            ExitEditor( 0 );
            // will not return
        }
        return( 0 );
    case WM_QUERYENDSESSION:
        return( ExitWithPrompt( FALSE, TRUE ) );
    case WM_CLOSE:
        ExitWithPrompt( TRUE, TRUE );
        return( 0 );
#ifdef __NT__        
    case WM_MOUSEWHEEL:
        {
            int     i, increment;
            ULONG   linesPerNotch;
            HWND    activeWnd;
            
            activeWnd = (HWND)SendMessage( EditContainer, WM_MDIGETACTIVE, 0, 0 );
            SystemParametersInfo( SPI_GETWHEELSCROLLLINES, 0, &linesPerNotch, 0 );
            
            increment = GET_WHEEL_DELTA_WPARAM( wparam ) / 120;
                // see WM_MOUSEWHEEL-documentation for information about the "120"

            if( increment > 0 ) {
                for( i = 0; i < increment * (int)linesPerNotch; i++ ) {
                    SendMessage( activeWnd, WM_VSCROLL, SB_LINEUP, 0 );
                }
            } else {
                for( i = 0; i < (-increment) * (int)linesPerNotch; i++ ) {
                    SendMessage( activeWnd, WM_VSCROLL, SB_LINEDOWN, 0 );
                }
            }
        }
        return( 0 );
#endif
    case WM_DESTROY:
        DestroyToolBar();
        DragAcceptFiles( hwnd, FALSE );
        EditContainer = 0;
        if( timerID ) {
            KillTimer( hwnd, TIMER_ID );
        }
        return( 0 );
    }
    return( DefFrameProc( hwnd, EditContainer, msg, wparam, lparam ) );

} /* MainWindowProc */
Exemplo n.º 12
0
/*
 * EditMain - main driver for editor (command mode)
 */
void EditMain( void )
{
    vi_rc       rc;
    char        *msg = NULL;
    bool        doclear;

    /*
     * loop forever, or at least until all done
     */
    for( ;; ) {

#if 0
#ifdef __WIN__
        PushMode();
        UpdateFiles();
        PopMode();
#endif
#endif
        if( !EditFlags.InsertModeActive || EditFlags.Modeless ) {
            if( EditFlags.Modeless ) {
                UpdateEditStatus();
                EditFlags.NoCapsLock = false;
            } else {
                UpdateCurrentStatus( CSTATUS_COMMAND );
                EditFlags.NoCapsLock = true;
            }

            if( !EditFlags.Modeless && EditFlags.ReturnToInsertMode &&
                                !NonKeyboardEventsPending() ) {
                EditFlags.ReturnToInsertMode = false;
                if( EditFlags.WasOverstrike ) {
                    LastEvent = 'R';
                } else {
                    LastEvent = 'i';
                }
            } else {
                DCUpdateAll();
#ifdef __WIN__
                SetWindowCursorForReal();
#endif
                LastEvent = GetNextEvent( true );
            }
            EditFlags.NoCapsLock = false;
            doclear = true;
            if( LastEvent == VI_KEY( MOUSEEVENT ) ) {
                if( LastMouseEvent == MOUSE_MOVE ) {
                    doclear = false;
                }
            }
            if( doclear ) {
                if( EditFlags.AutoMessageClear ) {
                    ClearWindow( MessageWindow );
                }
#ifndef __WIN__
                ResetDisplayLine();
#endif
            }
        } else {
            // Cannot do a RestoreInfo while we are in insert mode
            // because it will call ValidateCurrentColumn which will
            // do something stupid on us... PushMode/PopMode solution
            // not working yet... this needs a little work
            DCUpdate();
#ifdef __WIN__
            SetWindowCursorForReal();
#endif
            LastEvent = GetNextEvent( true );
        }

        rc = DoLastEvent();

        if( EditFlags.ReadOnlyError && rc <= ERR_NO_ERR ) {
            EditFlags.ReadOnlyError = false;
            rc = ERR_READ_ONLY_FILE_MODIFIED;
        }
        if( rc > ERR_NO_ERR ) {
            msg = GetErrorMsg( rc );
        }

        DoneLastEvent( rc, false );

        if( rc > ERR_NO_ERR ) {
            Error( msg );
        }

    }

} /* EditMain */
Exemplo n.º 13
0
/*
 * ResizeWindow - give a window a new size
 */
vi_rc ResizeWindow( window_id wn, int x1, int y1, int x2, int y2, int scrflag )
{
    wind        *tmp, *w;
    int         bt, k;
//    char        *txt, *tptr;
//    char        *ot;
//    int         i, j;

    w = AccessWindow( wn );

    if( !ValidDimension( x1, y1, x2, y2, w->has_border ) ) {
        ReleaseWindow( w );
        return( ERR_WIND_INVALID );
    }

    tmp = AllocWindow( x1, y1, x2, y2, w->has_border, w->border_color1,
                       w->border_color2, w->text_color, w->background_color );
    tmp->id = wn;
    tmp->has_gadgets = w->has_gadgets;
    // txt = MemAlloc( w->width + 1 );
    // tptr = txt;

    RestoreOverlap( wn, scrflag );

    Windows[wn] = tmp;
    tmp->accessed = TRUE;
    ResetOverlap( tmp );
    MarkOverlap( wn );

    /*
     * display the new text
     */
    k = 1;
    bt = (int) w->has_border;
    ClearWindow( wn );
    if( w->title != NULL ) {
        WindowTitle( wn, w->title );
    } else {
        DrawBorder( wn );
    }
#if 0
    for( j = bt; j < w->height - bt; j++ ) {

        ot = &(w->text[(j * w->width) * sizeof( char_info )]);
        for( i = bt; i < w->width - bt; i++ ) {
            *txt++ = ot[i * sizeof( char_info )];
        }
        *txt = 0;
        DisplayLineInWindow( wn, k++, tptr );
        txt = tptr;
    }
#else
    DCResize( CurrentInfo );
    DCDisplayAllLines();
    DCUpdate();
#endif

    FreeWindow( w );

    ReleaseWindow( tmp );
    return( ERR_NO_ERR );

} /* ResizeWindow */
Exemplo n.º 14
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 */