void JumpTo( i_mark *pos ) { if( CurrentPos.line != pos->line ) { GoToLineNoRelCurs( pos->line ); } if( CurrentPos.column != pos->column ) { GoToColumnOK( pos->column ); } }
void EditRCSCurrentFile( void ) { linenum row; int col; row = CurrentPos.line; col = CurrentPos.column; EditFile( CurrentFile->name, true ); GoToLineNoRelCurs( row ); GoToColumnOnCurrentLine( col ); }
/* * SelectAll - select the entire contents of the file */ vi_rc SelectAll( void ) { range r; vi_rc rc; r.line_based = TRUE; r.start.line = 1; CFindLastLine( &r.end.line ); rc = SetSelectedRegion( &r ); if( rc != ERR_NO_ERR ) { return( rc ); } rc = GoToLineNoRelCurs( r.end.line ); if( rc != ERR_NO_ERR ) { return( rc ); } return( GoToColumnOK( LineLength( r.end.line ) + 1 ) ); } /* SelectAll */
/* * 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 ); }
/* * 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 */
/* * doPush - shove/suck tab spaces in text */ static vi_rc doPush( range *r, bool shove ) { vi_rc rc; /* * get the line range */ if( r->start.line == r->end.line && !r->line_based ) { rc = ERR_INVALID_LINE_RANGE; } else { rc = Shift( r->start.line, r->end.line, shove ? '>' : '<', true ); if( rc <= ERR_NO_ERR ) { #if 0 GoToLineNoRelCurs( r->start.line ); #endif GoToColumnOnCurrentLine( FindStartOfCurrentLine() ); EditFlags.Dotable = true; } } return( rc ); } /* doPush */
/* * MoveScreenDown - expose bottom line */ vi_rc MoveScreenDown( void ) { linenum lne, cnt, lines, top, x; CFindLastLine( &lne ); lines = WindowAuxInfo( CurrentWindow, WIND_INFO_TEXT_LINES ); x = lne - lines + 1; if( x <= 0 ) { return( ERR_NO_ERR ); } cnt = GetRepeatCount(); top = LeftTopPos.line + cnt; if( top > x ) { top = x; } LeftTopPos.line = top; if( top >= CurrentPos.line ) { GoToLineNoRelCurs( top ); } DCDisplayAllLines(); SetWindowCursor(); return( ERR_NO_ERR ); } /* MoveScreenDown */
/* * MoveScreenUp - expose top line */ vi_rc MoveScreenUp( void ) { linenum lne, cnt, lines, top, nlne; lines = WindowAuxInfo( CurrentWindow, WIND_INFO_TEXT_LINES ); CFindLastLine( &lne ); cnt = GetRepeatCount(); top = LeftTopPos.line - cnt; if( top < 1 ) { top = 1; } LeftTopPos.line = top; if( CurrentPos.line >= top + lines ) { nlne = top + lines - 1; if( nlne > lne ) { nlne = lne; } GoToLineNoRelCurs( nlne ); } DCDisplayAllLines(); SetWindowCursor(); return( ERR_NO_ERR ); } /* MoveScreenUp */
/* * PopFileStack - go to file at top of file stack */ vi_rc PopFileStack( void ) { file_stack *fs; vi_rc rc; if( fDepth == 0 ) { return( ERR_FILE_STACK_EMPTY ); } fDepth--; fs = fStack[fDepth]; fStack[fDepth] = NULL; rc = EditFile( fs->fname, false ); if( rc != ERR_NO_ERR ) { MemFree( fs ); return( rc ); } GoToLineNoRelCurs( fs->p.line ); GoToColumnOnCurrentLine( fs->p.column ); MemFree( fs ); Message2( "%d entries left on file stack", fDepth ); return( ERR_NO_ERR ); } /* PopFileStack */
/* * ColorFind - find string and color it */ vi_rc ColorFind( const char *data, find_type findfl ) { vi_rc rc; int len; char *buff; i_mark pos; /* * get search string and flags */ buff = StaticAlloc(); GetNextWord1( data, buff ); if( *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 */
/* * TagHunt - hunt for a specified tag */ vi_rc TagHunt( char *str ) { char buff[MAX_STR], file[FILENAME_MAX]; int num; vi_rc rc; rc = LocateTag( str, file, buff ); if( rc == ERR_NO_ERR ) { PushFileStack(); rc = EditFile( file, FALSE ); if( rc == ERR_NO_ERR ) { if( buff[0] != '/' ) { num = atoi( buff ); rc = GoToLineNoRelCurs( num ); } else { rc = FindTag( buff ); if( rc < ERR_NO_ERR ) { strcpy( buff, str ); ColorFind( buff, 0 ); rc = ERR_TAG_NOT_FOUND; } } } else { PopFileStack(); } } if( rc == ERR_TAG_NOT_FOUND ) { Error( GetErrorMsg( rc ), str ); rc = DO_NOT_CLEAR_MESSAGE_WINDOW; } return( rc ); } /* TagHunt */
/* * RunCommandLine - run a command line command */ vi_rc RunCommandLine( const char *cmdl ) { int i, x, y, x2, y2; bool n1f, n2f; int tkn, flag; bool test1; linenum n1, n2; char st[FILENAME_MAX]; info *cinfo; long val; jmp_buf jmpaddr; vi_rc rc; const char *data; /* * parse command string */ tkn = TOK_INVALID; rc = ParseCommandLine( cmdl, &n1, &n1f, &n2, &n2f, &tkn, &data ); if( rc != ERR_NO_ERR ) { return( rc ); } if( !n2f ) { if( !n1f ) { n1 = n2 = CurrentPos.line; } else { n2 = n1; } } /* * process tokens */ rc = ERR_INVALID_COMMAND; test1 = n1f || n2f; switch( tkn ) { case PCL_T_ABOUT: rc = DoAboutBox(); break; case PCL_T_PUSH: rc = PushFileStackAndMsg(); break; case PCL_T_POP: rc = PopFileStack(); break; case PCL_T_EXECUTE: data = SkipLeadingSpaces( data ); if( *data != '\0' ) { key_map scr; rc = AddKeyMap( &scr, data ); if( rc != ERR_NO_ERR ) { break; } rc = RunKeyMap( &scr, 1L ); MemFree( scr.data ); } break; case PCL_T_DELETEMENU: rc = DoMenuDelete( data ); break; case PCL_T_DELETEMENUITEM: rc = DoItemDelete( data ); break; case PCL_T_ADDMENUITEM: rc = AddMenuItem( data ); break; case PCL_T_MAXIMIZE: rc = MaximizeCurrentWindow(); break; case PCL_T_MINIMIZE: rc = MinimizeCurrentWindow(); break; case PCL_T_EXITFILESONLY: if( !ExitWithPrompt( false, false ) ) { rc = ERR_EXIT_ABORTED; } else { rc = ERR_NO_ERR; } break; case PCL_T_EXITALL: if( !ExitWithPrompt( true, false ) ) { rc = ERR_EXIT_ABORTED; } else { rc = ERR_NO_ERR; } break; case PCL_T_QUITALL: ExitWithVerify(); rc = ERR_NO_ERR; break; case PCL_T_KEYADD: data = SkipLeadingSpaces( data ); KeyAddString( data ); rc = ERR_NO_ERR; break; case PCL_T_UNALIAS: rc = UnAlias( data ); break; case PCL_T_UNABBREV: rc = UnAbbrev( data ); break; case PCL_T_UNMAP: case PCL_T_UNMAP_DMT: flag = MAPFLAG_MESSAGE + MAPFLAG_UNMAP; if( tkn == PCL_T_UNMAP_DMT ) { flag |= MAPFLAG_DAMMIT; } rc = MapKey( flag, data ); break; case PCL_T_EVAL: data = Expand( dataBuff, data, NULL ); i = setjmp( jmpaddr ); if( i != 0 ) { rc = (vi_rc)i; } else { StartExprParse( data, jmpaddr ); val = GetConstExpr(); ltoa( val, st, EditVars.Radix ); Message1( "%s", st ); rc = ERR_NO_ERR; } break; case PCL_T_COMPILE: case PCL_T_SOURCE: case PCL_T_LOAD: { char *tstr; srcline sline; data = GetNextWord1( data, st ); if( *st == '\0' ) { rc = ERR_NO_FILE_SPECIFIED; break; } if( tkn == PCL_T_COMPILE ) { EditFlags.CompileScript = true; if( st[0] == '-' ) { if( st[1] == 'a' || st[1] == 'A' ) { EditFlags.CompileAssignments = true; if( st[1] == 'A' ) { EditFlags.CompileAssignmentsDammit = true; } data = GetNextWord1( data, st); if( *st == '\0' ) { rc = ERR_NO_FILE_SPECIFIED; break; } } } } if( tkn == PCL_T_LOAD ) { EditFlags.LoadResidentScript = true; } sline = 0; rc = Source( st, data, &sline ); EditFlags.LoadResidentScript = false; EditFlags.CompileScript = false; EditFlags.CompileAssignments = false; EditFlags.CompileAssignmentsDammit = false; if( EditFlags.SourceScriptActive ) { LastError = rc; } if( rc > ERR_NO_ERR ) { Error( "%s on line %u of \"%s\"", GetErrorMsg( rc ), sline, st ); } else { if( rc != DO_NOT_CLEAR_MESSAGE_WINDOW ) { if( tkn != PCL_T_SOURCE ) { if( tkn == PCL_T_LOAD ) { tstr = strLoad; } else { tstr = strCompile; } Message1( "Script \"%s\" %s, %u lines generated, %d errors", st, tstr, sline, SourceErrCount ); rc = DO_NOT_CLEAR_MESSAGE_WINDOW; } } } break; } case PCL_T_GENCONFIG: #ifndef __WIN__ data = GetNextWord1( data,st ); if( *st != '\0' ) { rc = GenerateConfiguration( st, true ); } else { rc = GenerateConfiguration( NULL, true ); } #else { bool temp = EditFlags.SaveConfig; EditFlags.SaveConfig = true; WriteProfile(); EditFlags.SaveConfig = temp; rc = ERR_NO_ERR; } #endif break; case PCL_T_COMPRESS: rc = CompressWhiteSpace(); break; case PCL_T_EXPAND: rc = ExpandWhiteSpace(); break; case PCL_T_SHOVE: rc = Shift( n1, n2, '>', true ); break; case PCL_T_SUCK: rc = Shift( n1, n2, '<', true ); break; case PCL_T_FILES: if( EditFlags.LineDisplay ) { rc = DisplayFileStatus(); } else { rc = EditFileFromList(); } break; case PCL_T_NEXT: rc = RotateFileForward(); break; case PCL_T_PREV: rc = RotateFileBackwards(); break; case PCL_T_HELP: rc = DoHelp( data ); break; case PCL_T_VIEW: case PCL_T_VIEW_DMT: EditFlags.ViewOnly = true; case PCL_T_EDIT: case PCL_T_EDIT_DMT: rc = EditFile( data, ( tkn == PCL_T_VIEW_DMT || tkn == PCL_T_EDIT_DMT ) ); EditFlags.ViewOnly = false; break; case PCL_T_OPEN: rc = OpenWindowOnFile( data ); break; case PCL_T_HIDE: case PCL_T_HIDE_DMT: rc = HideLineRange( n1, n2, ( tkn == PCL_T_HIDE_DMT ) ); break; case PCL_T_DELETE: rc = SetSavebufNumber( data ); if( rc != ERR_NO_ERR ) { break; } if( SelRgn.selected && !EditFlags.LineBased ) { AddSelRgnToSavebufAndDelete(); rc = ERR_NO_ERR; // @ may have turned this on - it is now definitely off SelRgn.selected = false; } else { rc = DeleteLineRange( n1, n2, SAVEBUF_FLAG ); } if( rc == ERR_NO_ERR ) { DCDisplayAllLines(); LineDeleteMessage( n1, n2 ); } break; case PCL_T_SAVEANDEXIT: data = GetNextWord1( data, st ); if( *st == '\0' ) { rc = SaveAndExit( st ); } else { rc = SaveAndExit( NULL ); } break; case PCL_T_PUT: case PCL_T_PUT_DMT: rc = SetSavebufNumber( data ); if( rc != ERR_NO_ERR ) { break; } rc = SaveAndResetFilePos( n1 ); if( rc == ERR_NO_ERR ) { if( tkn == PCL_T_PUT ) { rc = InsertSavebufAfter(); } else { rc = InsertSavebufBefore(); } RestoreCurrentFilePos(); } break; case PCL_T_YANK: rc = SetSavebufNumber( data ); if( rc != ERR_NO_ERR ) { break; } if( SelRgn.selected && !EditFlags.LineBased ) { rc = YankSelectedRegion(); // @ may have turned this on - it is now definitely off SelRgn.selected = false; } else { rc = YankLineRange( n1, n2 ); } break; case PCL_T_SUBSTITUTE: rc = Substitute( n1, n2, data ); break; case PCL_T_GLOBAL: case PCL_T_GLOBAL_DMT: if( !test1 ) { n1 = 1; rc = CFindLastLine( &n2 ); if( rc != ERR_NO_ERR ) { break; } } rc = Global( n1,n2, data, ( tkn == PCL_T_GLOBAL_DMT ) ); break; case PCL_T_WRITEQUIT: if( CurrentFile == NULL ) { rc = NextFile(); } else { CurrentFile->modified = true; data = GetNextWord1( data, st ); if( *st != '\0' ) { rc = SaveAndExit( st ); } else { rc = SaveAndExit( NULL ); } } break; case PCL_T_WRITE: case PCL_T_WRITE_DMT: data = GetNextWord1( data, st ); if( test1 ) { if( *st == '\0' ) { rc = ERR_NO_FILE_SPECIFIED; } else { rc = SaveFile( st, n1, n2, ( tkn == PCL_T_WRITE_DMT ) ); } } else { if( st[0] != '\0' ) { #ifdef __WIN__ if( st[0] == '?' && st[1] == '\0' ) { rc = SaveFileAs(); break; } else { rc = SaveFile( st, -1, -1, ( tkn == PCL_T_WRITE_DMT ) ); } #else rc = SaveFile( st, -1, -1, ( tkn == PCL_T_WRITE_DMT ) ); #endif } else { rc = SaveFile( NULL, -1, -1, ( tkn == PCL_T_WRITE_DMT ) ); if( rc == ERR_NO_ERR ) { Modified( false ); } } } break; case PCL_T_READ: rc = ReadAFile( n1, data ); break; case PCL_T_QUIT: #ifdef __WIN__ rc = CurFileExitOptionSaveChanges(); #else rc = NextFile(); #endif break; case PCL_T_QUIT_DMT: rc = NextFileDammit(); break; case PCL_T_DATE: GetDateTimeString( st ); Message1( st ); rc = DO_NOT_CLEAR_MESSAGE_WINDOW; break; case PCL_T_CD: data = GetNextWord1( data, st ); if( *st != '\0' ) { rc = SetCWD( st ); } else { rc = ERR_NO_ERR; } if( rc == ERR_NO_ERR ) { Message1( "Current directory is %s",CurrentDirectory ); } break; case PCL_T_SHELL: EVIL_SHELL: { #if defined( __NT__ ) && !defined( __WIN__ ) ExecCmd( NULL, NULL, NULL ); #else char foo[FILENAME_MAX]; strcpy( foo, Comspec ); ExecCmd( NULL, NULL, foo ); #endif DoVersion(); rc = ERR_NO_ERR; } break; case PCL_T_SYSTEM: if( n1f && n2f ) { rc = DoGenericFilter( n1, n2, data ); } else { data = SkipLeadingSpaces( data ); if( *data == '\0' ) { goto EVIL_SHELL; } ExecCmd( NULL, NULL, data ); rc = ERR_NO_ERR; } break; case PCL_T_RESIZE: rc = ResizeCurrentWindowWithKeys(); break; case PCL_T_TILE: data = GetNextWord1( data, st ); if( st[0] != '\0' ) { if( st[0] == 'v' ) { y = 1; for( x = 0, cinfo = InfoHead; cinfo != NULL; cinfo = cinfo->next ) { x++; } } else if( st[0] == 'h' ) { x = 1; for( y = 0, cinfo = InfoHead; cinfo != NULL; cinfo = cinfo->next ) { y++; } } else { x = atoi( st ); data = GetNextWord1( data, st ); if( *st == '\0' ) { break; } else { y = atoi( st ); } } } else { x = EditVars.MaxWindowTileX; y = EditVars.MaxWindowTileY; } if( x > 0 && y > 0) { rc = WindowTile( x, y ); } break; case PCL_T_CASCADE: rc = WindowCascade(); break; case PCL_T_MOVEWIN: rc = MoveCurrentWindowWithKeys(); break; case PCL_T_TAG: data = GetNextWord1( data, st ); if( *st != '\0' ) { rc = TagHunt( st ); } break; case PCL_T_FGREP: { bool ci; data = SkipLeadingSpaces( data ); ci = EditFlags.CaseIgnore; if( data[0] == '-' ) { if( data[1] == 'c' ) { ci = false; data += 2; data = SkipLeadingSpaces( data ); rc = GetStringWithPossibleQuote( &data, st ); } else if( data[1] == 'i' ) { ci = true; data += 2; data = SkipLeadingSpaces( data ); rc = GetStringWithPossibleQuote( &data, st ); } else if( data[1] == 'f' ) { data += 2; data = SkipLeadingSpaces( data ); #ifdef __WIN__ // call fancy grep window { fancy_find *ff; /* ff will be set to point at a static fancy find struct * in the snoop module */ char snoopbuf[FILENAME_MAX]; if( !GetSnoopStringDialog( &ff ) ) { return( ERR_NO_ERR ); } strcpy( snoopbuf, ff->path ); /* assume no string means current directory */ if( strlen( snoopbuf ) && snoopbuf[strlen( snoopbuf ) - 1] != '\\' ){ strcat( snoopbuf, "\\" ); } MySprintf( st, "%s", ff->find ); strcat( snoopbuf, ff->ext ); ci = ff->case_ignore; if( !ff->use_regexp ) { //MakeExpressionNonRegular( st ); rc = DoFGREP( snoopbuf, st, ci ); } else { rc = DoEGREP( snoopbuf, st ); } break; } #endif } } else { rc = GetStringWithPossibleQuote( &data, st ); } if( rc != ERR_NO_STRING ) { rc = DoFGREP( data, st, ci ); } } break; case PCL_T_EGREP: rc = GetStringWithPossibleQuote( &data, st ); if( rc != ERR_NO_STRING ) { rc = DoEGREP( data, st ); } break; case PCL_T_SIZE: data = GetNextWord1( data, st ); if( *st == '\0' ) { break; } x = atoi( st ); data = GetNextWord1( data, st ); if( *st == '\0' ) { break; } y = atoi( st ); data = GetNextWord1( data, st ); if( *st == '\0' ) { break; } x2 = atoi( st ); data = GetNextWord1( data, st ); if( *st == '\0' ) { break; } y2 = atoi( st ); rc = CurrentWindowResize( x, y, x2, y2 ); break; case PCL_T_ECHO: data = GetNextWord1( data, st ); if( *st == '\0' ) { break; } rc = ERR_NO_ERR; if( !stricmp( st, "on" ) ) { EditFlags.EchoOn = true; break; } else if( !stricmp( st, "off" ) ) { EditFlags.EchoOn = false; break; } x = atoi( st ); data = SkipLeadingSpaces( data ); /* * FIXME: This is not good - I will definately have to * fix this code up. But right now I have to get the * editor ready for tomorrow. Brad. */ if( data[0] == '"' || data[0] == '/' ) { GetStringWithPossibleQuote( &data, st ); if( x > 2 ) { /* this is obviously a sick individual */ Error( "Invalid Echo" ); } else if( x == 1 ) { Message1( st ); } else if( x == 2 ) { Message2( st ); } // DisplayLineInWindow( MessageWindow, x, st ); } else { if( x > 2 ) { /* this is obviously a sick individual */ Error( "Invalid Echo" ); } else if( x == 1 ) { Message1( data ); } else if( x == 2 ) { Message2( data ); } // DisplayLineInWindow( MessageWindow, x, data ); } break; #ifdef VI_RCS case PCL_T_CHECKOUT: rc = ERR_NO_ERR; #ifdef __WINDOWS__ if( isOS2() ) break; // OS/2 shell returns before checkout finishes #endif if( CurrentFile != NULL ) { rc = ViRCSCheckout( rc ); } break; case PCL_T_CHECKIN: if( CurrentFile != NULL ) { rc = ViRCSCheckin( rc ); } break; #endif default: if( tkn >= 1000 ) { rc = ProcessEx( n1, n2, n2f, tkn - 1000, data ); break; } rc = TryCompileableToken( tkn, data, true ); if( rc != NOT_COMPILEABLE_TOKEN ) { break; } rc = ProcessWindow( tkn, data ); if( rc >= ERR_NO_ERR ) { break; } case TOK_INVALID: if( n1f && !n2f ) { if( !n1 ) { n1 = 1; } MemorizeCurrentContext(); rc = GoToLineNoRelCurs( n1 ); if( rc == ERR_NO_ERR ) { GoToColumnOnCurrentLine( 1 ); if( EditFlags.LineDisplay ) { MyPrintf( "%s\n", CurrentLine->data ); } } return( rc ); } rc = ERR_INVALID_COMMAND; break; } if( rc == ERR_NO_ERR ) { rc = DO_NOT_CLEAR_MESSAGE_WINDOW; } return( rc ); } /* RunCommandLine */
/* * Substitute - perform substitution */ vi_rc Substitute( linenum n1, linenum n2, char *data ) { char *sstr, *rstr, *newr; char flag[20], *linedata; bool iflag = false; bool gflag = false; bool undoflag = false; bool restline = false; bool splitpending = false; bool undoline = false; int i, rlen, slen; bool splitme; long changecnt = 0, linecnt = 0; linenum llineno, ll, lastline = 0, extra; i_mark pos; vi_rc rc; LastSubstituteCancelled = 0; LastChangeCount = 0; LastLineCount = 0; sstr = alloca( MAX_INPUT_LINE ); if( sstr == NULL ) { return( ERR_NO_STACK ); } strcpy( sstr, data ); rc = ModificationTest(); if( rc != ERR_NO_ERR ) { return( rc ); } strcpy( data, sstr ); rstr = alloca( MAX_INPUT_LINE ); if( rstr == NULL ) { return( ERR_NO_STACK ); } if( NextWordSlash( data, sstr ) < 0 ) { return( ERR_INVALID_SUBS_CMD ); } if( NextWordSlash( data, rstr ) < 0 ) { return( ERR_INVALID_SUBS_CMD ); } slen = NextWord1( data, flag ); for( i = 0; i < slen; i++ ) { switch( flag[i] ) { case 'g': gflag = true; break; case 'i': case 'c': iflag = true; break; } } rc = CurrentRegComp( sstr ); if( rc != ERR_NO_ERR ) { return( rc ); } /* * verify last line */ if( n2 > CurrentFile->fcbs.tail->end_line ) { rc = CFindLastLine( &ll ); if( rc != ERR_NO_ERR ) { return( rc ); } if( n2 > ll ) { return( ERR_INVALID_LINE_RANGE ); } } /* * set for start of search */ if( EditFlags.Verbose && EditFlags.EchoOn ) { ClearWindow( MessageWindow ); } SaveCurrentFilePos(); llineno = n1 - 1; EditFlags.AllowRegSubNewline = true; newr = StaticAlloc(); for( pos.column = 0, pos.line = n1; pos.line <= n2; nextSearchStartPos( &pos, gflag, rlen ) ) { /* * get regular expression, and build replacement string */ rc = FindRegularExpression( NULL, &pos, &linedata, n2, 0 ); if( rc != ERR_NO_ERR || pos.line > n2 ) { break; } slen = GetCurrRegExpLength(); splitme = RegSub( CurrentRegularExpression, rstr, newr, pos.line ); rlen = strlen( newr ); ProcessingMessage( pos.line ); /* * if in global mode, see if we already have an undo for * this line */ if( gflag ) { if( lastline != pos.line ) { undoline = false; } } /* * interactive mode? yes, then display text and ask to change */ if( iflag ) { change_resp rsp; if( !restline ) { ClearWindow( MessageWindow ); } restline = true; GoToLineNoRelCurs( pos.line ); if( EditFlags.GlobalInProgress ) { EditFlags.DisplayHold = false; DCDisplayAllLines(); EditFlags.DisplayHold = true; } HilightSearchString( &pos, slen ); rsp = ChangePrompt(); if( rsp == CHANGE_NO ) { ResetDisplayLine(); rlen = 1; continue; } else if( rsp == CHANGE_CANCEL ) { ResetDisplayLine(); LastSubstituteCancelled = 1; break; } else if( rsp == CHANGE_ALL ) { ResetDisplayLine(); iflag = false; } } /* * set up for global undo if we haven't already */ if( !undoflag ) { StartUndoGroup( UndoStack ); undoflag = true; } /* * bump change counts */ changecnt++; if( llineno != pos.line ) { if( splitpending ) { splitpending = false; extra = SplitUpLine( llineno ); n2 += extra; pos.line += extra; } linecnt++; llineno = pos.line; } /* * get copy of line, and verify that new stuff fits */ CurrentPos.line = pos.line; rc = CGimmeLinePtr( pos.line, &CurrentFcb, &CurrentLine ); if( rc != ERR_NO_ERR ) { break; } if( CurrentLine->len + rlen - slen >= EditVars.MaxLine ) { rc = ERR_LINE_FULL; break; } /* * now build the individual undo */ CurrentFcb->non_swappable = true; if( !undoline ) { CurrentLineReplaceUndoStart(); CurrentLineReplaceUndoEnd( true ); if( gflag ) { undoline = true; lastline = pos.line; } } /* * remove the old string */ GetCurrentLine(); WorkLine->len = ReplaceSubString( WorkLine->data, WorkLine->len, pos.column, pos.column + slen - 1, newr, rlen ); if( iflag ) { DisplayWorkLine( true ); } ReplaceCurrentLine(); /* * if not global, only do this change on this line */ if( splitme ) { splitpending = true; } CurrentFcb->non_swappable = false; } StaticFree( newr ); EditFlags.AllowRegSubNewline = false; /* * is there still a split line pending? */ if( splitpending ) { SplitUpLine( llineno ); } RestoreCurrentFilePos(); if( restline ) { SetCurrentLine( CurrentPos.line ); GoToColumnOK( CurrentPos.column ); } if( undoflag ) { EndUndoGroup( UndoStack ); } switch( rc ) { case ERR_NO_ERR: case ERR_LINE_FULL: case ERR_FIND_PAST_TERM_LINE: case ERR_FIND_NOT_FOUND: case ERR_FIND_END_OF_FILE: /* * display results */ if( rc == ERR_LINE_FULL ) { Message1( "Stopped at line %l - line full", pos.line ); } else { Message1( "%l changes on %l lines", changecnt, linecnt ); LastLineCount = linecnt; LastChangeCount = changecnt; } DCDisplayAllLines(); rc = ERR_NO_ERR; break; default: break; } return( rc ); } /* Substitute */
/* * NewFile - load up a new file */ vi_rc NewFile( char *name, bool same_file ) { vi_rc rc; bool dup; status_type oldstatus; dup = EditFlags.DuplicateFile; EditFlags.DuplicateFile = false; oldstatus = UpdateCurrentStatus( CSTATUS_READING ); ScreenPage( 1 ); #ifdef __WIN__ EditFlags.ResizeableWindow = true; #endif rc = createNewFile( name, same_file ); if( rc != ERR_NO_ERR && rc != NEW_FILE ) { ScreenPage( -1 ); if( !EditFlags.Starting ) { MoveWindowToFrontDammit( MessageWindow, true ); MoveWindowToFrontDammit( CurrentWindow, true ); } UpdateCurrentStatus( oldstatus ); return( rc ); } GoToLineNoRelCurs( 1 ); GoToColumnOnCurrentLine( 1 ); FileSPVAR(); SaveCurrentInfo(); if( !same_file ) { inReadHook++; rc = SourceHook( SRC_HOOK_READ, rc ); inReadHook--; } /* * back from hook, so all loadings are done * (who should have priority - hook or fts commands?) */ #if 0 rc = FTSRunCmds( CurrentFile->name ); FTSRunCmds( CurrentFile->name ); #endif /* * reset the screen to the display page, display everything */ ScreenPage( -1 ); MoveWindowToFrontDammit( CurrentWindow, true ); UpdateStatusWindow(); SetWindowCursor(); DCDisplayAllLines(); EditFlags.DuplicateFile = dup; DisplayFileStatus(); SaveCurrentInfo(); ActiveWindow( CurrentWindow ); VarAddRandC(); SetModifiedVar( false ); UpdateCurrentStatus( oldstatus ); if( !same_file && !inReadHook ) { UpdateLastFileList( CurrentFile->name ); } #ifdef __WIN__ DCUpdateAll(); ResetEditWindowCursor( CurrentWindow ); SetWindowCursorForReal(); GotoFile( CurrentWindow ); #endif return( rc ); } /* NewFile */
/* * doInitializeEditor - do just that */ static void doInitializeEditor( int argc, char *argv[] ) { int i, arg, cnt, ocnt, startcnt = 0; srcline sline; int k, j; char tmp[FILENAME_MAX], c[1]; char buff[MAX_STR], file[MAX_STR], **list; char cmd[MAX_STR * 2]; char *parm; char *startup[MAX_STARTUP]; char *startup_parms[MAX_STARTUP]; vi_rc rc; vi_rc rc1; /* * Make sure WATCOM is setup and if it is not, make a best guess. */ watcom_setup_env(); /* * If EDPATH is not set, use system default %WATCOM%\EDDAT. */ if( getenv( "EDPATH" ) == NULL ) { char *watcom; watcom = getenv( "WATCOM" ); if( watcom != NULL ) { char edpath[FILENAME_MAX]; sprintf( edpath, "%s%c%s", watcom, FILE_SEP, "eddat" ); if( setenv( "EDPATH", edpath, 0 ) != 0 ) { /* * Bail out silently on error, as we will get error message later on. */ } } } /* * misc. set up */ MaxMemFree = MemSize(); StaticStart(); FTSInit(); BoundDataInit(); EditFlags.Starting = true; InitCommandLine(); ChkExtendedKbd(); SSInitBeforeConfig(); GetCWD1( &HomeDirectory ); GetCWD1( &CurrentDirectory ); SetCWD( HomeDirectory ); if( cfgFN == NULL ){ cfgFN = DupString( CFG_NAME ); } checkFlags( &argc, argv, startup, startup_parms, &startcnt ); ScreenInit(); SetWindowSizes(); EditFlags.ClockActive = false; SetInterrupts(); #ifdef __WIN__ InitClrPick(); InitFtPick(); SubclassGenericInit(); CursorOp( COP_INIT ); #else InitColors(); #endif InitSavebufs(); InitKeyMaps(); /* * initial configuration */ EditVars.Majick = MemStrDup( "()~@" ); EditVars.FileEndString = MemStrDup( "[END_OF_FILE]" ); MatchInit(); SetGadgetString( NULL ); WorkLine = MemAlloc( sizeof( line ) + EditVars.MaxLine + 2 ); WorkLine->len = -1; sline = 0; if( cfgFN[0] != 0 ) { c[0] = 0; rc = Source( cfgFN, c, &sline ); if( rc == ERR_FILE_NOT_FOUND ) { #ifdef __WIN__ CloseStartupDialog(); MessageBox( (HWND)NULLHANDLE, "Could not locate configuration information; please make sure your EDPATH environment variable is set correctly", EditorName, MB_OK ); ExitEditor( -1 ); #else rc = ERR_NO_ERR; #endif } } else { rc = ERR_NO_ERR; } if( wantNoReadEntireFile ) { EditFlags.ReadEntireFile = false; } VerifyTmpDir(); while( LostFileCheck() ); HookScriptCheck(); if( EditFlags.Quiet ) { EditFlags.Spinning = false; EditFlags.Clock = false; } ExtendedMemoryInit(); /* * more misc. setup */ if( EditVars.WordDefn == NULL ) { EditVars.WordDefn = DupString( &WordDefnDefault[6] ); InitWordSearch( EditVars.WordDefn ); } if( EditVars.WordAltDefn == NULL ) { EditVars.WordAltDefn = DupString( WordDefnDefault ); } if( EditVars.TagFileName == NULL ) { EditVars.TagFileName = DupString( "tags" ); } DotBuffer = MemAlloc( (maxdotbuffer + 2) * sizeof( vi_key ) ); AltDotBuffer = MemAlloc( (maxdotbuffer + 2) * sizeof( vi_key ) ); DotCmd = MemAlloc( (maxdotbuffer + 2) * sizeof( vi_key ) ); SwapBlockInit( EditVars.MaxSwapBlocks ); ReadBuffer = MemAlloc( MAX_IO_BUFFER + 6 ); WriteBuffer = MemAlloc( MAX_IO_BUFFER + 6 ); FindHistInit( EditVars.FindHist.max ); FilterHistInit( EditVars.FilterHist.max ); CLHistInit( EditVars.CLHist.max ); LastFilesHistInit( EditVars.LastFilesHist.max ); GetClockStart(); GetSpinStart(); SelRgnInit(); SSInitAfterConfig(); #if defined( VI_RCS ) ViRCSInit(); #endif /* * create windows */ StartWindows(); InitMouse(); rc1 = NewMessageWindow(); if( rc1 != ERR_NO_ERR ) { FatalError( rc1 ); } DoVersion(); rc1 = InitMenu(); if( rc1 != ERR_NO_ERR ) { FatalError( rc1 ); } EditFlags.SpinningOurWheels = true; EditFlags.ClockActive = true; EditFlags.DisplayHold = true; rc1 = NewStatusWindow(); if( rc1 != ERR_NO_ERR ) { FatalError( rc1 ); } EditFlags.DisplayHold = false; MaxMemFreeAfterInit = MemSize(); /* * look for a tag: if there is one, set it up as the file to start */ EditFlags.WatchForBreak = true; if( cTag != NULL && !EditFlags.NoInitialFileLoad ) { #if defined( __NT__ ) && !defined( __WIN__ ) { if( !EditFlags.Quiet ) { SetConsoleActiveScreenBuffer( OutputHandle ); } } #endif rc1 = LocateTag( cTag, file, buff ); cFN = file; if( rc1 != ERR_NO_ERR ) { if( rc1 == ERR_TAG_NOT_FOUND ) { Error( GetErrorMsg( rc1 ), cTag ); ExitEditor( 0 ); } FatalError( rc1 ); } } /* * start specified file(s) */ cmd[0] = 'e'; cmd[1] = 0; arg = argc - 1; k = 1; while( !EditFlags.NoInitialFileLoad ) { if( cFN == nullFN && !EditFlags.UseNoName ) { break; } #ifdef __NT__ { int k2; int arg2; char path[_MAX_PATH]; int found; int fd; size_t len; size_t len1; char *p; /* * check for the existence of a file name containing spaces, and open it if * there is one */ len = _MAX_PATH - 1; found = 0; p = path; arg2 = arg; for( k2 = k; argv[k2] != NULL; ) { len1 = strlen( argv[k2] ); if( len1 > len ) break; memcpy( p, argv[k2], len1 ); p += len1; *p = '\0'; len -= len1; --arg2; ++k2; fd = open( path, O_RDONLY ); if( fd != -1 ) { close( fd ); k = k2; arg = arg2; found = 1; break; } *p++ = ' '; } if( found ) { #ifndef __UNIX__ len1 = strlen( path ); if( path[len1 - 1] == '.' ) path[len1 - 1] = '\0'; #endif rc1 = NewFile( path, false ); if( rc1 != ERR_NO_ERR ) { FatalError( rc1 ); } cFN = argv[k]; if( arg < 1 ) { break; } continue; } } #endif strcat( cmd, SingleBlank ); strcat( cmd, cFN ); ocnt = cnt = ExpandFileNames( cFN, &list ); if( cnt == 0 ) { cnt = 1; } else { cFN = list[0]; } for( j = 0; j < cnt; j++ ) { rc1 = NewFile( cFN, false ); if( rc1 != ERR_NO_ERR && rc1 != NEW_FILE ) { FatalError( rc1 ); } if( EditFlags.BreakPressed ) { break; } if( cnt > 0 && j < cnt - 1 ) { cFN = list[j + 1]; } } if( ocnt > 0 ) { MemFreeList( ocnt, list ); } if( EditFlags.BreakPressed ) { ClearBreak(); break; } k++; arg--; if( cTag != NULL || arg < 1 ) { break; } cFN = argv[k]; } if( EditFlags.StdIOMode ) { rc1 = NewFile( "stdio", false ); if( rc1 != ERR_NO_ERR ) { FatalError( rc1 ); } } EditFlags.WatchForBreak = false; EditFlags.Starting = false; /* * if there was a tag, do the appropriate search */ if( cTag != NULL && !EditFlags.NoInitialFileLoad ) { if( buff[0] != '/' ) { i = atoi( buff ); rc1 = GoToLineNoRelCurs( i ); } else { rc1 = FindTag( buff ); } if( rc1 > 0 ) { Error( GetErrorMsg( rc1 ) ); } } /* * try to run startup file */ if( EditFlags.RecoverLostFiles ) { startcnt = 0; } for( i = 0; i < startcnt; i++ ) { GetFromEnv( startup[i], tmp ); ReplaceString( &cfgFN, tmp ); if( cfgFN[0] != 0 ) { if( startup_parms[i] != NULL ) { parm = startup_parms[i]; } else { c[0] = 0; parm = c; } #if defined( __NT__ ) && !defined( __WIN__ ) { if( !EditFlags.Quiet ) { SetConsoleActiveScreenBuffer( OutputHandle ); } } #endif sline = 0; rc = Source( cfgFN, parm, &sline ); } } if( rc > ERR_NO_ERR ) { Error( "%s on line %u of \"%s\"", GetErrorMsg( rc ), sline, cfgFN ); } if( argc == 1 ) { LoadHistory( NULL ); } else { LoadHistory( cmd ); } if( EditVars.GrepDefault == NULL ) { EditVars.GrepDefault = DupString( "*.(c|h)" ); } if( goCmd[0] != 0 ) { KeyAddString( goCmd ); } if( keysToPush != NULL ) { KeyAddString( keysToPush ); } #ifdef __WIN__ if( lineToGoTo != 0 ) { SetCurrentLine( lineToGoTo ); NewCursor( CurrentWindow, EditVars.NormalCursorType ); } #endif AutoSaveInit(); HalfPageLines = WindowAuxInfo( CurrentWindow, WIND_INFO_TEXT_LINES ) / 2 - 1; #if defined( _M_X64 ) VarAddGlobalStr( "OSX64", "1" ); #elif defined( _M_IX86 ) && !defined( _M_I86 ) VarAddGlobalStr( "OS386", "1" ); #endif if( EditVars.StatusString == NULL ) { EditVars.StatusString = DupString( "L:$6L$nC:$6C" ); } UpdateStatusWindow(); #ifdef __WIN__ if( CurrentInfo == NULL ) { // no file loaded - screen is disconcertenly empty - reassure DisplayFileStatus(); } #endif NewCursor( CurrentWindow, EditVars.NormalCursorType ); #if defined( __NT__ ) && !defined( __WIN__ ) { SetConsoleActiveScreenBuffer( OutputHandle ); } #endif } /* doInitializeEditor */
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 */
/* * Global - perform global command */ vi_rc Global( linenum n1, linenum n2, const char *data, int dmt ) { char *sstr, *linedata; bool match; vi_rc rc; vi_rc rc1; long changecnt = 0; linenum ll; fcb *cfcb; line *cline; regexp crx; i_mark pos; /* * get search string and command */ rc = ModificationTest(); if( rc != ERR_NO_ERR ) { return( rc ); } sstr = alloca( MAX_INPUT_LINE ); if( sstr == NULL ) { return( ERR_NO_STACK ); } data = SkipLeadingSpaces( data ); data = GetNextWord( data, sstr, SingleSlash ); if( *sstr == '\0' ) { return( ERR_INVALID_GLOBAL_CMD ); } if( *data == '/' ) ++data; // skip one slash character data = SkipLeadingSpaces( data ); /* * verify last line */ if( n2 > CurrentFile->fcbs.tail->end_line ) { rc = CFindLastLine( &ll ); if( rc != ERR_NO_ERR ) { return( rc ); } if( n2 > ll ) { return( ERR_INVALID_LINE_RANGE ); } } /* * set for start of search */ if( EditFlags.Verbose && EditFlags.EchoOn ) { ClearWindow( MessageWindow ); } rc = CurrentRegComp( sstr ); if( rc != ERR_NO_ERR ) { return( rc ); } SaveCurrentFilePos(); StartUndoGroup( UndoStack ); EditFlags.DisplayHold = true; /* * pass one - find all matches */ for( pos.line = n1; pos.line <= n2; pos.line++ ) { /* * go thorugh file, marking global lines */ pos.column = 0; rc = FindRegularExpression( NULL, &pos, &linedata, n2, 0 ); if( rc != ERR_NO_ERR ) { if( rc == ERR_FIND_PAST_TERM_LINE || rc == ERR_FIND_NOT_FOUND || rc == ERR_FIND_END_OF_FILE ) { break; } RestoreCurrentFilePos(); EditFlags.DisplayHold = false; return( rc ); } if( pos.line > n2 ) { break; } /* * go to appropriate spot in file */ rc = GoToLineNoRelCurs( pos.line ); if( rc != ERR_NO_ERR ) { RestoreCurrentFilePos(); EditFlags.DisplayHold = false; return( rc ); } /* * mark fcb and line for a match */ CurrentFcb->globalmatch = true; CurrentLine->u.ld.globmatch = true; if( EditFlags.Verbose && EditFlags.EchoOn ) { // WPrintfLine( MessageWindow,1,"Match on line %l",clineno ); Message1( "Match on line %l", pos.line ); } } /* * negate range, if needed */ if( dmt ) { /* * run through each line, flipping globmatch flag on lines */ CGimmeLinePtr( n1, &CurrentFcb, &CurrentLine ); match = false; for( CurrentPos.line = n1; CurrentPos.line <= n2; CurrentPos.line++ ) { if( CurrentLine->u.ld.globmatch ) { CurrentLine->u.ld.globmatch = false; } else { match = true; CurrentLine->u.ld.globmatch = true; } CurrentLine = CurrentLine->next; if( CurrentLine == NULL ) { CurrentFcb->globalmatch = match; CurrentFcb = CurrentFcb->next; FetchFcb( CurrentFcb ); CurrentLine = CurrentFcb->lines.head; match = false; } } } /* * Pass 2: do all changes */ rc = ERR_NO_ERR; EditFlags.GlobalInProgress = true; memcpy( &crx, CurrentRegularExpression, sizeof( crx ) ); for( CurrentFcb = CurrentFile->fcbs.head; CurrentFcb != NULL; CurrentFcb = CurrentFcb->next ) { if( !CurrentFcb->globalmatch ) continue; FetchFcb( CurrentFcb ); CurrentPos.line = CurrentFcb->start_line; for( CurrentLine = CurrentFcb->lines.head; CurrentLine != NULL; CurrentLine = CurrentLine->next, CurrentPos.line++ ) { if( !CurrentLine->u.ld.globmatch ) continue; CurrentLine->u.ld.globmatch = false; changecnt++; CurrentPos.column = 1; ProcessingMessage( CurrentPos.line ); /* * build command line */ rc = RunCommandLine( data ); if( rc > ERR_NO_ERR ) { break; } } if( rc > ERR_NO_ERR ) { break; } CurrentFcb->globalmatch = false; } /* * we have an error, so fix up fcbs */ if( rc > ERR_NO_ERR ) { for( cfcb = CurrentFile->fcbs.head; cfcb != NULL; cfcb = cfcb->next ) { if( cfcb->globalmatch ) { cfcb->globalmatch = false; cfcb->non_swappable = false; for( cline = cfcb->lines.head; cline != NULL; cline = cline->next ) { cline->u.ld.globmatch = false; } } } } /* * display results */ EditFlags.GlobalInProgress = false; EditFlags.DisplayHold = false; EndUndoGroup( UndoStack ); RestoreCurrentFilePos(); rc1 = SetCurrentLine( CurrentPos.line ); if( rc1 != ERR_NO_ERR ) { if( rc1 == ERR_NO_SUCH_LINE ) { SetCurrentLine( 1 ); } else { return( rc1 ); } } Message1( "%l matches found",changecnt ); DCDisplayAllLines(); return( rc ); } /* Global */
/* * 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 */
/* * InsertLinesAtCursor - insert a set of lines at current pos. in file */ vi_rc InsertLinesAtCursor( fcb_list *fcblist, undo_stack *us ) { fcb *cfcb; linenum e; int lastLineLen; char *source; line *tLine; vi_rc rc; rc = ModificationTest(); if( rc != ERR_NO_ERR ) { return( rc ); } /* * find the number of lines inserted */ e = 0; for( cfcb = fcblist->head; cfcb != NULL; cfcb = cfcb->next ) { e += (cfcb->end_line - cfcb->start_line + 1); } // add chars from right of cursor to end of last line of buffer source = CurrentLine->data + CurrentPos.column - 1; lastLineLen = fcblist->tail->lines.tail->len; fcblist->tail->lines.tail->len += CurrentLine->len - CurrentPos.column + 1; fcblist->tail->byte_cnt += CurrentLine->len - CurrentPos.column + 1; tLine = fcblist->tail->lines.tail->prev; fcblist->tail->lines.tail = MemReAlloc( fcblist->tail->lines.tail, sizeof( line ) + fcblist->tail->lines.tail->len + 1 ); if( tLine ) { tLine->next = fcblist->tail->lines.tail; } strcpy( fcblist->tail->lines.tail->data + lastLineLen, source ); StartUndoGroup( us ); // create new current line in work line CurrentLineReplaceUndoStart(); GetCurrentLine(); WorkLine->len = CurrentPos.column + fcblist->head->lines.head->len - 1; strcpy( WorkLine->data + CurrentPos.column - 1, fcblist->head->lines.head->data ); // replace current line ReplaceCurrentLine(); CurrentLineReplaceUndoEnd( true ); // remove first line of buffer FetchFcb( fcblist->head ); fcblist->head->non_swappable = true; fcblist->head->start_line++; fcblist->head->byte_cnt -= fcblist->head->lines.head->len + 1; tLine = fcblist->head->lines.head; fcblist->head->lines.head = fcblist->head->lines.head->next; fcblist->head->lines.head->prev = NULL; MemFree( tLine ); fcblist->head->non_swappable = false; // add rest of lines of buffer & done if( fcblist->head->lines.head) { InsertLines( CurrentPos.line, fcblist, us ); } EndUndoGroup( us ); // if are indeed linebased, move cursor as well if( !EditFlags.LineBased ) { GoToLineNoRelCurs( CurrentPos.line + e - 1 ); GoToColumnOnCurrentLine( lastLineLen + 1 ); } return( ERR_NO_ERR ); } /* InsertLinesAtCursor */