/* * ColorFind - find string and color it */ vi_rc ColorFind( char *data, find_type findfl ) { vi_rc rc; int len; char *buff; i_mark pos; /* * get search string and flags */ buff = StaticAlloc(); if( (len = NextWordSlash( data, 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 */
void DCUpdateAll( void ) { info *curr, *info; bool saved_cinfo; if( EditFlags.Quiet ) { return; } saved_cinfo = false; info = CurrentInfo; for( curr = info; curr != NULL; curr = curr->next ) { if( curr->CurrentFile->needs_display ) { if( !saved_cinfo ) { SaveCurrentInfo(); saved_cinfo = true; } RestoreInfo( curr ); DCUpdate(); curr->CurrentFile->needs_display = false; } } if( saved_cinfo ) { RestoreInfo( info ); SetWindowCursor(); } }
/* * 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 */
/* * HilightSearchString - bring a search string into view and hilight it */ void HilightSearchString( i_mark *pos, int slen ) { if( slen > 0 ) { GoToColumnOK( pos->column + slen ); } GoToColumnOK( pos->column + 1 ); if( slen > 0 ) { #ifdef __WIN__ SetSelRegionCols( pos->line, pos->column + 1, pos->column + slen ); DCUpdate(); #else DCUpdate(); HiliteAColumnRange( pos->line, pos->column, pos->column + slen - 1 ); #endif } EditFlags.ResetDisplayLine = TRUE; } /* HilightSearchString */
/* * ResetDisplayLine - reset display line, if required (after hilight) */ void ResetDisplayLine( void ) { if( EditFlags.ResetDisplayLine ) { memcpy( WorkLine->data, CurrentLine->data, CurrentLine->len + 1 ); WorkLine->len = CurrentLine->len; DisplayWorkLine( false ); DCUpdate(); WorkLine->len = -1; EditFlags.ResetDisplayLine = false; } } /* ResetDisplayLine */
/* * 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 */
/* * 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 ); }
/* * ResizeWindow - give a window a new size */ vi_rc ResizeWindow( window_id wid, windim x1, windim y1, windim x2, windim y2, bool scrflag ) { window *oldw; // int bt, k; // char *txt, *tptr; // char *ot; // int i, j; oldw = WINDOW_FROM_ID( wid ); AccessWindow( oldw ); if( !ValidDimension( x1, y1, x2, y2, oldw->has_border ) ) { ReleaseWindow( oldw ); return( ERR_WIND_INVALID ); } RestoreOverlap( wid, scrflag ); AllocWindow( wid, x1, y1, x2, y2, oldw->has_border, oldw->has_gadgets, true, oldw->border_color1, oldw->border_color2, oldw->text_color, oldw->background_color ); MarkOverlap( wid ); /* * display the new text */ ClearWindow( wid ); if( oldw->title != NULL ) { WindowTitle( wid, oldw->title ); } else { DrawBorder( wid ); } DCResize( CurrentInfo ); DCDisplayAllLines(); DCUpdate(); FreeWindow( oldw ); ReleaseWindow( WINDOW_FROM_ID( wid ) ); return( ERR_NO_ERR ); } /* ResizeWindow */
/* * InsertTextForSpecialKey - insert text for ^O, ALT_O */ void InsertTextForSpecialKey( vi_key event, char *buff ) { linenum line; int type; if( CurrentFile == NULL ) { return; } line = CurrentPos.line; type = INSERT_BEFORE; if( event == VI_KEY( CTRL_O ) ) { type = INSERT_AFTER; line += 1; } Modified( true ); StartUndoGroup( UndoStack ); UndoInsert( line, line, UndoStack ); AddNewLineAroundCurrent( buff, strlen( buff ), type ); EndUndoGroup( UndoStack ); DCDisplayAllLines(); DCUpdate(); } /* InsertTextForSpecialKey */
/* * 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 */
/* * MainWindowProc - procedure for main (root) window */ WINEXPORT LRESULT CALLBACK MainWindowProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { RECT rect; vi_rc rc; HANDLE hfileinfo; int cnt, i; char *buff; switch( msg ) { case WM_CREATE: Root = hwnd; GetClientRect( hwnd, &rect ); EditContainer = CreateContainerWindow( &rect ); InitWindows(); DragAcceptFiles( hwnd, TRUE ); timerID = SetTimer( hwnd, TIMER_ID, 60L * 1000L, NULL ); break; case WM_DROPFILES: hfileinfo = (HANDLE) wparam; cnt = DragQueryFile( hfileinfo, (UINT)-1, NULL, 0 ); buff = alloca( FILENAME_MAX + 2 ); /* we add a " at the beginning and at the end so we can handle path- and filenames with spaces */ if( buff != NULL ) { buff[0] = '"'; /* one " at the beginning of the filename */ for( i = 0; i < cnt; i++ ) { if( DragQueryFile( hfileinfo, i, buff + 1, FILENAME_MAX ) == (UINT)-1 ) { break; } strcat( buff, "\"" ); rc = EditFile( buff, FALSE ); if( rc > ERR_NO_ERR ) { Error( GetErrorMsg( rc ) ); } } } DragFinish( hfileinfo ); break; case WM_TIMER: UpdateStatusWindow(); break; case WM_KEYDOWN: if( WindowsKeyPush( wparam, HIWORD( lparam ) ) ) { return( 0 ); } break; case WM_SIZE: DefFrameProc( hwnd, EditContainer, msg, wparam, lparam ); RootState = wparam; if( wparam != SIZE_MINIMIZED ) { ResizeRoot(); GetWindowRect( hwnd, &RootRect ); if( wparam != SIZE_MAXIMIZED ) { RootState = 0; } } return( 0 ); case WM_MOVE: DefFrameProc( hwnd, EditContainer, msg, wparam, lparam ); if( RootState != SIZE_MINIMIZED ) { GetWindowRect( hwnd, &RootRect ); } return( 0 ); case WM_ACTIVATEAPP: if( BAD_ID( CurrentWindow ) ) { break; } SetFocus( Root ); #if 0 if( !wparam ) { InactiveWindow( CurrentWindow ); } else { SendMessage( EditContainer, WM_MDIACTIVATE, (WPARAM)CurrentWindow, 0L ); } #endif if( wparam ) { ResetEditWindowCursor( CurrentWindow ); } else { GoodbyeCursor( CurrentWindow ); } break; case WM_MOUSEACTIVATE: SetFocus( hwnd ); return( MA_ACTIVATE ); case WM_SETFOCUS: if( BAD_ID( CurrentWindow ) ) { break; } if( !IsIconic( CurrentWindow ) ) { SendMessage( EditContainer, WM_MDIACTIVATE, (WPARAM)CurrentWindow, 0L ); DCUpdate(); SetWindowCursor(); SetWindowCursorForReal(); return( 0 ); } break; case WM_NCLBUTTONDBLCLK: break; case WM_COMMAND: if( LOWORD( wparam ) > 0xF000 ) { break; } else { rc = MenuCommand( LOWORD( wparam ) ); if( rc != MENU_COMMAND_NOT_HANDLED ) { DCUpdateAll(); if( rc > ERR_NO_ERR ) { char *msg; msg = GetErrorMsg( rc ); Error( msg ); } } SetWindowCursor(); } return( 0 ); case WM_INITMENU: if( (HMENU)wparam == GetMenu( hwnd ) ) { HandleInitMenu( (HMENU)wparam ); } else { ResetMenuBits(); } break; case WM_MENUSELECT: HandleMenuSelect( wparam, lparam ); break; case WM_ENDSESSION: if( wparam ) { ExitEditor( 0 ); // will not return } return( 0 ); case WM_QUERYENDSESSION: return( ExitWithPrompt( FALSE, TRUE ) ); case WM_CLOSE: ExitWithPrompt( TRUE, TRUE ); return( 0 ); #ifdef __NT__ case WM_MOUSEWHEEL: { int i, increment; ULONG linesPerNotch; HWND activeWnd; activeWnd = (HWND)SendMessage( EditContainer, WM_MDIGETACTIVE, 0, 0 ); SystemParametersInfo( SPI_GETWHEELSCROLLLINES, 0, &linesPerNotch, 0 ); increment = GET_WHEEL_DELTA_WPARAM( wparam ) / 120; // see WM_MOUSEWHEEL-documentation for information about the "120" if( increment > 0 ) { for( i = 0; i < increment * (int)linesPerNotch; i++ ) { SendMessage( activeWnd, WM_VSCROLL, SB_LINEUP, 0 ); } } else { for( i = 0; i < (-increment) * (int)linesPerNotch; i++ ) { SendMessage( activeWnd, WM_VSCROLL, SB_LINEDOWN, 0 ); } } } return( 0 ); #endif case WM_DESTROY: DestroyToolBar(); DragAcceptFiles( hwnd, FALSE ); EditContainer = 0; if( timerID ) { KillTimer( hwnd, TIMER_ID ); } return( 0 ); } return( DefFrameProc( hwnd, EditContainer, msg, wparam, lparam ) ); } /* MainWindowProc */
/* * EditMain - main driver for editor (command mode) */ void EditMain( void ) { vi_rc rc; char *msg = NULL; bool doclear; /* * loop forever, or at least until all done */ for( ;; ) { #if 0 #ifdef __WIN__ PushMode(); UpdateFiles(); PopMode(); #endif #endif if( !EditFlags.InsertModeActive || EditFlags.Modeless ) { if( EditFlags.Modeless ) { UpdateEditStatus(); EditFlags.NoCapsLock = false; } else { UpdateCurrentStatus( CSTATUS_COMMAND ); EditFlags.NoCapsLock = true; } if( !EditFlags.Modeless && EditFlags.ReturnToInsertMode && !NonKeyboardEventsPending() ) { EditFlags.ReturnToInsertMode = false; if( EditFlags.WasOverstrike ) { LastEvent = 'R'; } else { LastEvent = 'i'; } } else { DCUpdateAll(); #ifdef __WIN__ SetWindowCursorForReal(); #endif LastEvent = GetNextEvent( true ); } EditFlags.NoCapsLock = false; doclear = true; if( LastEvent == VI_KEY( MOUSEEVENT ) ) { if( LastMouseEvent == MOUSE_MOVE ) { doclear = false; } } if( doclear ) { if( EditFlags.AutoMessageClear ) { ClearWindow( MessageWindow ); } #ifndef __WIN__ ResetDisplayLine(); #endif } } else { // Cannot do a RestoreInfo while we are in insert mode // because it will call ValidateCurrentColumn which will // do something stupid on us... PushMode/PopMode solution // not working yet... this needs a little work DCUpdate(); #ifdef __WIN__ SetWindowCursorForReal(); #endif LastEvent = GetNextEvent( true ); } rc = DoLastEvent(); if( EditFlags.ReadOnlyError && rc <= ERR_NO_ERR ) { EditFlags.ReadOnlyError = false; rc = ERR_READ_ONLY_FILE_MODIFIED; } if( rc > ERR_NO_ERR ) { msg = GetErrorMsg( rc ); } DoneLastEvent( rc, false ); if( rc > ERR_NO_ERR ) { Error( msg ); } } } /* EditMain */
/* * ResizeWindow - give a window a new size */ vi_rc ResizeWindow( window_id wn, int x1, int y1, int x2, int y2, int scrflag ) { wind *tmp, *w; int bt, k; // char *txt, *tptr; // char *ot; // int i, j; w = AccessWindow( wn ); if( !ValidDimension( x1, y1, x2, y2, w->has_border ) ) { ReleaseWindow( w ); return( ERR_WIND_INVALID ); } tmp = AllocWindow( x1, y1, x2, y2, w->has_border, w->border_color1, w->border_color2, w->text_color, w->background_color ); tmp->id = wn; tmp->has_gadgets = w->has_gadgets; // txt = MemAlloc( w->width + 1 ); // tptr = txt; RestoreOverlap( wn, scrflag ); Windows[wn] = tmp; tmp->accessed = TRUE; ResetOverlap( tmp ); MarkOverlap( wn ); /* * display the new text */ k = 1; bt = (int) w->has_border; ClearWindow( wn ); if( w->title != NULL ) { WindowTitle( wn, w->title ); } else { DrawBorder( wn ); } #if 0 for( j = bt; j < w->height - bt; j++ ) { ot = &(w->text[(j * w->width) * sizeof( char_info )]); for( i = bt; i < w->width - bt; i++ ) { *txt++ = ot[i * sizeof( char_info )]; } *txt = 0; DisplayLineInWindow( wn, k++, tptr ); txt = tptr; } #else DCResize( CurrentInfo ); DCDisplayAllLines(); DCUpdate(); #endif FreeWindow( w ); ReleaseWindow( tmp ); return( ERR_NO_ERR ); } /* ResizeWindow */
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 */