예제 #1
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 */
예제 #2
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 */
예제 #3
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 */
예제 #4
0
/*
 * SelectDown - update selected region, moving down
 */
vi_rc SelectDown( void )
{
    if( !EditFlags.Dragging ) {
        startSelectedRegion( EditFlags.LineBased );
        if( EditFlags.LineBased ) {
            return ERR_NO_ERR;
        }
    }
    return( GoToLineRelCurs( CurrentPos.line + 1 ) );

} /* SelectDown */
예제 #5
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 );
}
예제 #6
0
/*
 * IMEnter - process the enter key in insert mode
 */
vi_rc IMEnter( void )
{
    char        *buff, *buffx;
    int         len, col, el;

    if( CurrentFile == NULL ) {
        return( ERR_NO_FILE );
    }
    CurrentFile->need_autosave = TRUE;

    startNewLineUndo();
    CheckAbbrev( abbrevBuff, &abbrevCnt );
    abbrevCnt = 0;

    /*
     * truncate the working line
     */
    buff = StaticAlloc();
    buffx = StaticAlloc();
    el = WorkLine->len - CurrentPos.column + 1;
    if( el > 0 && WorkLine->len > 0 ) {
        memcpy( buff, &WorkLine->data[CurrentPos.column - 1], el + 1 );
        WorkLine->len -= el;
        WorkLine->data[CurrentPos.column - 1] = 0;
    } else {
        el = 0;
        buff[0] = 0;
    }

    len = trimWorkLine();

    /*
     * replace the current line with the working copy
     */
    ReplaceCurrentLine();
    if( currLineRepUndo ) {
        CurrentLineReplaceUndoEnd( FALSE );
        currLineRepUndo = FALSE;
    }

    /*
     * create a new line, insert leading spaces if needed
     * and copy in the truncation
     */
    if( EditFlags.AutoIndent ) {
        len = GetAutoIndentAmount( buffx, len, FALSE );
        el += len;
        strcat( buffx, buff );
        AddNewLineAroundCurrent( buffx, el, INSERT_AFTER );
        col = len + 1;
    } else {
        AddNewLineAroundCurrent( buff, el, INSERT_AFTER );
        col = 1;
    }
    UndoInsert( CurrentPos.line + 1, CurrentPos.line + 1, UndoStack );

    /*
     * display the result
     */
    DCDisplayAllLines();
    GoToLineRelCurs( CurrentPos.line + 1 );
    GoToColumnOK( col );
    GetCurrentLine();
    StaticFree( buff );
    StaticFree( buffx );
    return( ERR_NO_ERR );

} /* IMEnter */
예제 #7
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 */
예제 #8
0
/*
 * HandleMouseEvent - handle main editor mouse events
 */
vi_rc HandleMouseEvent( void )
{
    windim      win_x, win_y;
    window_id   wid;
    info        *cinfo;
    window      *w;
    int         i;
    bool        diff_word;
    vi_rc       rc;

    wid = GetMousePosInfo( &win_x, &win_y );
    if( BAD_ID( wid ) ) {
        return( ERR_NO_ERR );
    }
    w = WINDOW_FROM_ID( wid );
    if( !w->has_border ) {
        win_x += 1;
        win_y += 1;
    }

    if( dragThumb ) {
        if( LastMouseEvent == MOUSE_RELEASE ) {
            dragThumb = false;
        }
        if( wid != current_window_id ) {
            return( ERR_NO_ERR );
        }
        if( win_x == w->width - 1 ) {
            return( PositionToNewThumbPosition( w, win_y ) );
        }
        return( ERR_NO_ERR );
    }

    if( EditFlags.Dragging ) {
        if( LastMouseEvent == MOUSE_DRAG || LastMouseEvent == MOUSE_REPEAT ) {
            UpdateDrag( wid, win_x, win_y );
        } else {
            if( LastMouseEvent == MOUSE_PRESS_R || LastMouseEvent == MOUSE_PRESS ) {
                EditFlags.Dragging = false;
                if( LastMouseEvent == MOUSE_PRESS_R ) {
                    LastMouseEvent = MOUSE_RELEASE_R;
                }
            }
        }
    }

    if( LastMouseEvent == MOUSE_RELEASE_R || LastMouseEvent == MOUSE_DCLICK ) {
        if( wid == current_window_id && InsideWindow( wid, win_x, win_y ) ) {
            diff_word = (LastMouseEvent == MOUSE_DCLICK);
            if( GoToLineRelCurs( LeftTopPos.line + win_y - 1 ) ) {
                return( ERR_NO_ERR );
            }
            win_x += LeftTopPos.column;
            win_x = RealColumnOnCurrentLine( win_x );
            GoToColumnOnCurrentLine( win_x );
            if( diff_word ) {
                InitWordSearch( EditVars.WordAltDefn );
            }
            rc = DoSelectSelection( true );
            if( diff_word ) {
                InitWordSearch( EditVars.WordDefn );
            }
            return( rc );
        }
    }

    /*
     * all kinds of stuff to do if the button was pressed
     */
    if( LastMouseEvent == MOUSE_PRESS || LastMouseEvent == MOUSE_PRESS_R ) {
        if( wid != current_window_id ) {
            /*
             * swap to another window
             */
            for( cinfo = InfoHead; cinfo != NULL; cinfo = cinfo->next ) {
                if( wid == cinfo->current_window_id ) {
                    BringUpFile( cinfo, true );
                    break;
                }
            }
        }
        if( wid == current_window_id ) {
            if( !ShiftDown() ) {
                UnselectRegion();
            }
            if( w->has_border && LastMouseEvent == MOUSE_PRESS ) {
                /*
                 * clicked on menu for window
                 */
                if( win_x == 0 && win_y == 0 ) {
                    return( DoWindowGadgetMenu() );
                }

                /*
                 * check for resize request
                 */
                if( win_x == w->width - 1 && win_y == w->height - 1 ) {
                    return( ResizeCurrentWindowWithMouse() );
                }

                /*
                 * check for move request
                 */
                if( win_y == 0 ) {
                    return( MoveCurrentWindowWithMouse() );
                }
            }

            /*
             * check for locate cursor
             */
            if( InsideWindow( wid, win_x, win_y ) ) {
                if( ShiftDown() ) {
                    EditFlags.Dragging = true;
                }
                if( GoToLineRelCurs( LeftTopPos.line + win_y - 1 ) ) {
                    return( ERR_NO_ERR );
                }
                win_x += LeftTopPos.column;
                win_x = RealColumnOnCurrentLine( win_x );
                GoToColumnOnCurrentLine( win_x );
                if( ShiftDown() ) {
                    EditFlags.Dragging = false;
                } else {
                    InitSelectedRegion();
                }
                return( ERR_NO_ERR );
            }
        }
        if( EditFlags.Menus && wid == menu_window_id ) {
            i = GetMenuIdFromCoord( win_x - 1 );
            if( i >= 0 ) {
                return( SetToMenuId( i ) );
            }
        }
    }

    /*
     * allow double click to close window
     */
    if( wid == current_window_id && LastMouseEvent == MOUSE_DCLICK ) {
        if( win_y == 0 && win_x == 0 ) {
            return( NextFile() );
        }
    }

    /*
     * try to scroll screen
     */
    if( (LastMouseEvent == MOUSE_REPEAT || LastMouseEvent == MOUSE_DCLICK ||
         LastMouseEvent == MOUSE_PRESS) && w->has_border &&
        wid == current_window_id && win_x == w->width - 1 ) {
        if( win_y == w->height - 2 ) {
            return( MoveScreenDown() );
        }
        if( win_y == 1 ) {
            return( MoveScreenUp() );
        }
        /*
         * if we have gadgets, then scroll based on position of scroll
         * thumb. furthermore, if the thumb is selected, then begin
         * thumb dragging mode
         */
        if( w->has_gadgets ) {
            if( win_y == w->vert_scroll_pos ) {
                dragThumb = true;
                return( ERR_NO_ERR );
            } else if( win_y < w->vert_scroll_pos ) {
                return( MovePageUp() );
            } else {
                return( MovePageDown() );
            }
        } else {
            if( win_y < w->height / 2 ) {
                return( MovePageUp() );
            } else {
                return( MovePageDown() );
            }
        }
    }

    /*
     * start dragging
     */
    if( wid == current_window_id && (LastMouseEvent == MOUSE_DRAG ||
                                LastMouseEvent == MOUSE_DRAG_R ) &&
        InsideWindow( wid, win_x, win_y ) ) {
        EditFlags.Dragging = true;
        UpdateDrag( wid, win_x, win_y );
    }

    return( ERR_NO_ERR );

} /* HandleMouseEvent */