/* * UndoReplaceLines - undo the replacement of a group of lines */ vi_rc UndoReplaceLines( linenum sline, linenum eline ) { vi_rc rc; fcb_list fcblist; if( !EditFlags.Undo || UndoStack == NULL ) { return( ERR_NO_ERR ); } rc = GetCopyOfLineRange( sline, eline, &fcblist ); if( rc != ERR_NO_ERR ) { return( rc ); } StartUndoGroup( UndoStack ); UndoDeleteFcbs( sline - 1, &fcblist, UndoStack ); UndoInsert( sline, eline, UndoStack ); EndUndoGroup( UndoStack ); return( ERR_NO_ERR ); } /* UndoReplaceLines */
/* * DoGenericFilter - filter some crap */ vi_rc DoGenericFilter( linenum s, linenum e, const char *cmd ) { fcb *cfcb, *tfcb; line *cline; vi_rc rc; char filtin[_MAX_PATH], filtout[_MAX_PATH]; fcb_list fcblist; int fh; rc = ModificationTest(); if( rc != ERR_NO_ERR ) { return( rc ); } /* * filter on a line */ rc = GetCopyOfLineRange( s, e, &fcblist ); if( rc != ERR_NO_ERR ) { return( rc ); } /* * get file */ MakeTmpPath( filtin, FILTER_FILE_NAME ); fh = mkstemp( filtin ); if( fh == -1 ) return( ERR_FILE_OPEN ); /* * now, dump this crap to a tmp file */ for( cfcb = fcblist.head; cfcb != NULL; cfcb = tfcb ) { FetchFcb( cfcb ); for( cline = cfcb->lines.head; cline != NULL; cline = cline->next ) { write( fh, cline->data, strlen( cline->data ) ); #if defined( __UNIX__ ) write( fh, "\n", 1 ); #else write( fh, "\r\n", 2 ); #endif } tfcb = cfcb->next; FcbFree( cfcb ); } close( fh ); MakeTmpPath( filtout, FILTER_FILE_NAME ); fh = mkstemp( filtout ); if( fh == -1 ) { remove( filtin ); return( ERR_FILE_OPEN ); } close( fh ); /* * shell out to the given command */ ExecCmd( filtin, filtout, cmd ); StartUndoGroup( UndoStack ); rc = DeleteLineRange( s, e, 0 ); if( rc == ERR_NO_ERR ) { ReadAFile( s - 1, filtout ); Message1( "%l lines filtered through %s", e - s + 1, cmd ); } EndUndoGroup( UndoStack ); /* * cleanup */ if( rc == ERR_NO_ERR ) { rc = DO_NOT_CLEAR_MESSAGE_WINDOW; } remove( filtin ); remove( filtout ); return( rc ); } /* DoGenericFilter */
/* * 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 */