static int checkRightMove( linenum line, int *col, range *r ) { int len; if( CurrentLine == NULL ) { return( ERR_NO_FILE ); } len = LineLength( line ); if( EditFlags.Modeless ) { len++; } if( (*col) > len ) { if( EditFlags.Modeless ) { if( !IsPastLastLine( line + 1 ) ) { r->start.line = line + 1; r->line_based = TRUE; *col = 1; } else { *col = len; } } else { if( EditFlags.OperatorWantsMove ) { if( *col == len + 1 ) { return( ERR_NO_ERR ); } } *col = len; return( ERR_NO_SUCH_COLUMN ); } } return( ERR_NO_ERR ); }
static char *nextLine( i_mark *mark ) { do { mark->line += 1; mark->column = 1; } while( LineLength( mark->line ) == 0 && !IsPastLastLine( mark->line ) ); return( ptrFromMark( mark ) ); } /* nextLine */
/* * verifyMoveFromPageTop - move a certain amount past the top of page, * verifying that the end of file is not overrun */ static vi_rc verifyMoveFromPageTop( range *r, linenum ln ) { if( CurrentLine == NULL ) { return( ERR_NO_FILE ); } ln += LeftTopPos.line; if( IsPastLastLine( ln ) ) { CFindLastLine( &ln ); } r->line_based = TRUE; r->start.line = ln; return( ERR_NO_ERR ); } /* verifyMoveFromPageTop */
/* * MovePosition - move to a screen position */ vi_rc MovePosition( void ) { linenum lne, lines; vi_key key; vi_rc rc; if( RepeatDigits == 0 ) { lne = CurrentPos.line; } else { lne = GetRepeatCount(); if( IsPastLastLine( lne ) ) { return( ERR_INVALID_REDRAW ); } } lines = WindowAuxInfo( CurrentWindow, WIND_INFO_TEXT_LINES ); key = GetNextEvent( false ); switch( key ) { case '.': LeftTopPos.line = lne - lines / 2; break; case VI_KEY( ENTER ): LeftTopPos.line = lne; break; case '-': LeftTopPos.line = lne - lines + 1; break; default: return( ERR_INVALID_REDRAW ); } if( LeftTopPos.line < 1 ) { LeftTopPos.line = 1; } SetCurrentLineNumber( lne ); rc = CGimmeLinePtr( CurrentPos.line, &CurrentFcb, &CurrentLine ); CurrentPos.column = 1; DCInvalidateAllLines(); DCDisplayAllLines(); if( rc == ERR_NO_ERR ) { rc = GoToColumnOnCurrentLine( FindStartOfCurrentLine() ); } return( rc ); } /* MovePosition */
vi_rc MovePageBottom( range *r, long count ) { linenum ln; int lines; int amt; if( CurrentLine == NULL ) { return( ERR_NO_FILE ); } lines = WindowAuxInfo( CurrentWindow, WIND_INFO_TEXT_LINES ); if( IsPastLastLine( LeftTopPos.line + lines ) ) { CFindLastLine( &ln ); amt = ln - LeftTopPos.line - count + 1; } else { amt = lines - count; } return( verifyMoveFromPageTop( r, amt ) ); } /* MovePageBottom */
/* * setLineCol - set up line and column to start search at */ static vi_rc setLineCol( char *st, i_mark *pos, find_type flags ) { fcb *cfcb; line *cline; bool wrapped; /* * get next position */ if( st[0] == 0 ) { if( lastFind == NULL ) { return( ERR_NO_PREVIOUS_SEARCH_STRING ); } if( lastPos.line != 0 && currPos.column == CurrentPos.column && currPos.line == CurrentPos.line ) { *pos = lastPos; if( flags & FINDFL_FORWARD ) { pos->column += 1; } else { pos->column -= 2; } } else { *pos = CurrentPos; if( flags & FINDFL_FORWARD ) { pos->column += 0; } else { pos->column -= 2; } } AddString2( &sStr, lastFind ); } else { if( !(flags & FINDFL_NOCHANGE) ) { AddString2( &lastFind, st ); } AddString2( &sStr, st ); *pos = CurrentPos; if( flags & FINDFL_FORWARD ) { pos->column += 0; } else { pos->column -= 2; } } /* * wrap if needed */ if( flags & FINDFL_NEXTLINE ) { wrapped = FALSE; if( flags & FINDFL_FORWARD ) { pos->column = 0; pos->line += 1; if( IsPastLastLine( pos->line ) ) { pos->line = 1; wrapped = TRUE; } } else { pos->line -= 1; if( pos->line == 0 ) { CFindLastLine( &pos->line ); wrapped = TRUE; } CGimmeLinePtr( pos->line, &cfcb, &cline ); pos->column = cline->len - 1; if( pos->column < 0 ) { pos->column = 0; } } if( wrapped && !(flags & FINDFL_WRAP) ) { if( flags & FINDFL_FORWARD ) { return( ERR_FIND_END_OF_FILE ); } else { return( ERR_FIND_TOP_OF_FILE ); } } } return( ERR_NO_ERR ); } /* setLineCol */
/* * ProcessEx - process an ex command */ vi_rc ProcessEx( linenum n1, linenum n2, bool n2f, int tkn, const char *data ) { vi_rc rc = ERR_INVALID_COMMAND, i; char word[MAX_STR]; linenum addr, tlines; fcb *cfcb; line *cline; fcb_list fcblist; GetNextWord1( data, word ); data = word; if( GetAddress( &data, &addr ) != ERR_NO_ERR ) { addr = -1; } tlines = n2 - n1 + 1; switch( tkn ) { case EX_T_APPEND: if( !EditFlags.ExMode ) { return( ERR_ONLY_VALID_IN_EX_MODE ); } if( !n2f ) { rc = Append( n1, true ); } break; case EX_T_CHANGE: if( !EditFlags.ExMode ) { return( ERR_ONLY_VALID_IN_EX_MODE ); } StartUndoGroup( UndoStack ); rc = DeleteLineRange( n1, n2, 0 ); if( rc != ERR_NO_ERR ) { EndUndoGroup( UndoStack ); break; } rc = Append( n1 - 1, false ); if( rc != ERR_NO_ERR ) { EndUndoGroup( UndoStack ); break; } break; case EX_T_COPY: if( addr < 0 || IsPastLastLine( addr ) ) { return( ERR_INVALID_ADDRESS ); } i = GetCopyOfLineRange( n1, n2, &fcblist ); if( i ) { break; } rc = InsertLines( addr, &fcblist, UndoStack ); GoToLineNoRelCurs( addr ); if( rc == ERR_NO_ERR ) { Message1( strCmmsg, tlines, "copied", addr ); } break; case EX_T_INSERT: if( !EditFlags.ExMode ) { return( ERR_ONLY_VALID_IN_EX_MODE ); } if( !n2f ) { rc = Append( n1 - 1, true ); } break; case EX_T_JOIN: if( SaveAndResetFilePos( n1 ) != ERR_NO_ERR ) { rc = ERR_NO_SUCH_LINE; break; } if( tlines == 1 ) { n2 = n1 + 1; tlines = 2; } SetRepeatCount( tlines - 1 ); rc = JoinCurrentLineToNext(); RestoreCurrentFilePos(); GoToLineNoRelCurs( n1 ); if( rc == ERR_NO_ERR ) { Message1( "lines %l to %l joined", n1, n2 ); } break; case EX_T_LIST: if( !EditFlags.ExMode ) { return( ERR_ONLY_VALID_IN_EX_MODE ); } for( rc = CGimmeLinePtr( n1, &cfcb, &cline ); rc == ERR_NO_ERR; rc = CGimmeNextLinePtr( &cfcb, &cline ) ) { if( EditFlags.LineNumbers ) { MyPrintf( "%M %s\n", n1, cline->data ); } else { MyPrintf( "%s\n", cline->data ); } if( n1 >= n2 ) { break; } n1++; } break; case EX_T_MARK: rc = SetGenericMark( n1, 1, C2VIKEY( word[0] ) ); break; case EX_T_MOVE: if( addr < 0 || IsPastLastLine( addr ) ) { return( ERR_INVALID_ADDRESS ); } SavebufNumber = WORK_SAVEBUF; StartUndoGroup( UndoStack ); rc = DeleteLineRange( n1, n2, SAVEBUF_FLAG ); if( SavebufNumber != WORK_SAVEBUF ) { /* if this changes, the command will fail * this could be caused by checking out a read-only file * so fix the deleted text and give an error message */ DoUndo(); return( ERR_INVALID_COMMAND ); } if( rc != ERR_NO_ERR ) { EndUndoGroup( UndoStack ); break; } if( addr > n2 ) { addr -= tlines; } else if( addr >= n1 && addr <= n2 ) { addr = n1; } rc = InsertLines( addr, &WorkSavebuf->u.fcbs, UndoStack ); EndUndoGroup( UndoStack ); GoToLineNoRelCurs( addr ); if( rc == ERR_NO_ERR ) { Message1( strCmmsg, tlines, "moved", addr ); } break; case EX_T_UNDO: rc = DoUndo(); break; case EX_T_UNDO_DMT: rc = DoUndoUndo(); break; case EX_T_EQUALS: Message1( "%l", n1 ); rc = ERR_NO_ERR; break; case EX_T_VERSION: rc = DoVersion(); break; case EX_T_VISUAL: case EX_T_VISUAL_DMT: if( EditFlags.LineDisplay ) { ScreenPage( -1 ); EditFlags.ExMode = false; EditFlags.LineDisplay = false; EditFlags.ClockActive = true; ReDisplayScreen(); DoVersion(); } if( word[0] != '\0' ) { rc = EditFile( word, ( tkn == EX_T_VISUAL_DMT ) ); } else { rc = ERR_NO_ERR; } break; } return( rc ); } /* ProcessEx */