Example #1
0
/*
 * CheckCurrentColumn - check state of current column, return true if need to
 *                      redisplay page
 */
bool CheckCurrentColumn( void )
{
    int     clen, vcp;
    bool    dispall = false;

    clen = VirtualLineLen( CurrentLine->data );
    if( clen == 0 ) {
        clen = 1;
    }
    ValidateCurrentColumn();

    vcp = VirtualColumnOnCurrentLine( CurrentPos.column );

    if( vcp != VirtualColumnDesired ) {
        if( clen >= VirtualColumnDesired ) {
            CurrentPos.column = RealColumnOnCurrentLine( VirtualColumnDesired );
        } else {
            if( EditFlags.InsertModeActive || EditFlags.Modeless ) {
                CurrentPos.column = CurrentLine->len + 1;
            } else {
                CurrentPos.column = CurrentLine->len;
            }
        }
        ValidateCurrentColumn();
        dispall = !CheckLeftColumn();
        /* changed CurrentPos.column - update horiz scrollbar
        */
        PositionHorizontalScrollThumb( current_window_id, LeftTopPos.column );
    }
    VarAddGlobalLong( "C", (long) CurrentPos.column );
    return( dispall );

} /* CheckCurrentColumn */
Example #2
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 */
Example #3
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 #4
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 #5
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 */
Example #6
0
static int getCursorInfo( HWND hwnd, int row, int col, int *x, int *width )
{
    ss_block    *ss, *ss_start, *ss_prev;
    dc          dc_line;
    int         len;
    int         old_col = 0;
    char        *str;
    int         funny = 0;

    col--;      // we like base 0
    row--;

    // this section checks if current line is valid.

    assert( hwnd == CurrentInfo->CurrentWindow );
    if( row < 0 || row >= CurrentInfo->dc_size ) {
        // not on screen -> not displayed
        *x = -10;
        *width = 0;
        return( 0 );
    }
    dc_line = DCFindLine( row, hwnd );

    if( dc_line->display != 0 ){
        // line has not been drawn yet. Can't set cursor.
        *x = -10;
        *width = 0;
        return( 0 );
    }

    assert( dc_line->valid );

    if( dc_line->start_col != LeftTopPos.column ) {
        // not in cache -> not on screen -> not displayed
        *x = -10;
        *width = 0;
        return( 0 );
    }
    ss_start = ss = dc_line->ss;
    ss_prev = NULL;


    // this bit adjusts col for real tabs

    if( EditFlags.RealTabs ){
        // this takes it from the current line!!!! %$#@!
        // what if row isn't the current line! oops!!!
        // luckily this works because who wants to know cursor info
        // for any line but the current one!

        // if( thisLine == CurrentLine ){
            int real_left = RealColumnOnCurrentLine( LeftTopPos.column + 1 );
            old_col = col;
            col = RealColumnOnCurrentLine( col + 1 ) - real_left;

            // kludge! - Real Cursor position refuses to say cursor is to right
            //           of last character like it ought to when Modeless
            if( CursorPositionOffRight( old_col + 1 ) &&
                (EditFlags.Modeless == FALSE) ) {
                 col++;
            }

        // } else {
            // int real_left = RealCursorPositionOnLine( thisLine, LeftColumn + 1 );
            // old_col = col;
            // col = RealCursorPositionOnLine( thisLine, col + 1 ) - real_left;
        // }
    }


    // this bit finds the block we want
    while( ss->end < col ) {
        ss++;
    }

    // handle cursor being off the right of text
    if( ss->end == BEYOND_TEXT ) {
        *width = FontAverageWidth( SEType[ss->type].font );
        if( ss == ss_start ) {
            *x = (*width) * col;
        } else {
            ss_prev = ss - 1;
            *x = ((*width) * (col - ss_prev->end - 1)) + ss_prev->offset;
        }
        return( 0 );
    }

    // setup to figure out where cursor is within text.
    if( ss != ss_start ) {
        ss_prev = ss - 1;
        str = dc_line->text + ss_prev->end + 1;
        len = col - ss_prev->end - 1;
    } else {
        str = dc_line->text;
        len = col;
    }

    // Magic Tabs positioning
    if( EditFlags.RealTabs ) {
        type_style      *this_style = &SEType[ss->type];
        int             no_tab = FALSE;
        int             avg_width = FontAverageWidth( SEType[ss->type].font );
        int             left, extent, end_tab;
        char            *cur_pos;
        char            *end_str;

        if( ss != ss_start ) {
            left = ss_prev->offset;
        } else {
            left = 0;
        }

        if( len > 0 ) {
            // Note: this will not work with 16bit chars or embedded chars
            // but niether will the drawing routines, so not to worry (yet)

            // Is there a tab in the current block ?
            end_str = cur_pos = str + len;
            while( *(--cur_pos) != '\t' ){
                if(cur_pos == str){
                    no_tab = TRUE;
                    break;
                }
            }

            // if so, figure out where the last tab stop is.
            if( no_tab == FALSE ) {

                // dist is the virtual curpos - the number of chars before
                // the first tab. this should be the tab boundry.
                int dist = (old_col + 1) - (end_str - cur_pos);
                // unless the end_str was also a tab, So we round down.
                left = (dist - (dist % EditVars.HardTab) - LeftTopPos.column) * avg_width;

                cur_pos++;
            }

            // now get the extent of the leading chars ...
            extent = MyTextExtent( hwnd, this_style, cur_pos, end_str - cur_pos );
        } else {
            extent = 0;
            cur_pos = str;
            end_str = str;
        }


        // ... and find the position and width of the cursor.
        if( *end_str == '\t' ){
            // in strange case, tab may start before end of prev string
            end_tab = (old_col - LeftTopPos.column + 1) * avg_width;
            *x = left + extent;
            if( *x > end_tab )
                *x = end_tab;
            *width = end_tab - *x;
            if( *width < 1 )
                *width = 1;
            funny = 0;
        } else {
            *x = left + extent;
            *width = MyTextExtent( hwnd, this_style, cur_pos,
                                   end_str - cur_pos + 1 ) - extent;
            funny = (*width) / 2;
        }
    } else {
        type_style *this_style = &SEType[ss->type];

        *x = MyTextExtent( hwnd, this_style, str, len );
        *width = MyTextExtent( hwnd, this_style,  str, len + 1 ) - *x;
        if( ss != ss_start ) {
            *x += ss_prev->offset;
        }
        funny = (*width) / 2;
    }
    if( FontIsFunnyItalic( SEType[ss->type].font ) ) {
        return( funny );
    } else {
        return( 0 );
    }
}
Example #7
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 */