/* * 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 */
vi_rc Delete( range *r ) { vi_rc rc; // need to perform the actual delete if( r->line_based ) { rc = DeleteLineRange( r->start.line, r->end.line, SAVEBUF_FLAG ); DCDisplayAllLines(); LineDeleteMessage( r->start.line, r->end.line ); } else if( r->start.line != r->end.line ) { rc = Cut( r->start.line, r->start.column, r->end.line, r->end.column, true ); DCDisplayAllLines(); } else { GoToLineNoRelCurs( r->start.line ); rc = DeleteRangeOnCurrentLine( r->start.column, r->end.column, true ); } // move cursor to tl corner of region if( rc == ERR_NO_ERR ) { GoToLineNoRelCurs( r->start.line ); r->start.column += 1; if( r->start.column > CurrentLine->len ) { if( EditFlags.Modeless ) { r->start.column = CurrentLine->len + 1; } else { r->start.column = CurrentLine->len; } } GoToColumnOnCurrentLine( r->start.column ); EditFlags.Dotable = true; } else { rc = DO_NOT_CLEAR_MESSAGE_WINDOW; } return( rc ); } /* Delete */
/* * SelectHome - update selected region, moving to beginning of line */ vi_rc SelectHome( void ) { if( !EditFlags.Dragging ) { startSelectedRegion( FALSE ); } return( GoToColumnOnCurrentLine( 1 ) ); } /* SelectHome */
/* * 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 */
/* * SelectEnd - update selected region, moving to end of line */ vi_rc SelectEnd( void ) { if( !EditFlags.Dragging ) { startSelectedRegion( FALSE ); } CurrentPos.column = MAX_INPUT_LINE; ValidateCurrentColumn(); return( GoToColumnOnCurrentLine( CurrentPos.column ) ); } /* SelectEnd */
void EditRCSCurrentFile( void ) { linenum row; int col; row = CurrentPos.line; col = CurrentPos.column; EditFile( CurrentFile->name, true ); GoToLineNoRelCurs( row ); GoToColumnOnCurrentLine( col ); }
/* * 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 */
/* * 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 */
/* * 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 */
/* * 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 */
/* * 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 */
/* * 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 */
/* * 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 */
/* * 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 */