/* * DoneCurrentInsert - finished current insertion of text */ void DoneCurrentInsert( bool trim ) { if( EditFlags.InsertModeActive ) { EditFlags.InsertModeActive = FALSE; if( trim ) { trimWorkLine(); } if( CurrentPos.column > WorkLine->len ) { if( EditFlags.Modeless ) { GoToColumnOK( WorkLine->len + 1 ); } else { GoToColumnOK( WorkLine->len ); } } doneWithCurrentLine(); EndUndoGroup( UndoStack ); if( !EditFlags.Modeless ) { NewCursor( CurrentWindow, EditVars.NormalCursorType ); SetWindowCursor(); } EditFlags.EscapedInsertChar = FALSE; EditFlags.NoReplaceSearchString = FALSE; } } /* DoneCurrentInsert */
/* * IMDelete - handle DEL key pressed in insert mode */ vi_rc IMDelete( void ) { int wlen; if( CurrentFile == NULL ) { return( ERR_NO_FILE ); } startNewLineUndo(); wlen = WorkLine->len + 1; if( wlen == 0 ) { wlen = CurrentLine->len + 1; } if( EditFlags.Modeless && CurrentPos.column == wlen && CurrentLine->next ) { /* go to beginning of next line */ GoToLineRelCurs( CurrentPos.line + 1 ); GoToColumnOK( 1 ); GetCurrentLine(); } else { GoToColumn( CurrentPos.column + 1, wlen ); if( CurrentPos.column != wlen - 1 || abbrevCnt == 0 ) { abbrevCnt++; /* gets subtracted by IMBackSpace */ } } return( IMBackSpace() ); } /* IMDelete */
/* * checkWrapMargin - see if we have moved past the wrap margin */ static void checkWrapMargin( void ) { int i; int width; int pos; bool old_ai; if( EditVars.WrapMargin != 0 ) { if( EditVars.WrapMargin < 0 ) { width = -EditVars.WrapMargin; } else { width = WindowAuxInfo( CurrentWindow, WIND_INFO_WIDTH ) - EditVars.WrapMargin; } if( CurrentPos.column > width ) { for( i = CurrentPos.column - 1; i >= 0; i-- ) { if( isspace( WorkLine->data[i] ) ) { pos = CurrentPos.column - 1 - i; CurrentPos.column = i + 2; old_ai = EditFlags.AutoIndent; EditFlags.AutoIndent = FALSE; IMEnter(); EditFlags.AutoIndent = old_ai; GoToColumnOK( pos ); return; } } } } } /* checkWrapMargin */
/* * DoDigit - process a digit typed in */ vi_rc DoDigit( void ) { vi_rc rc; if( LastEvent == '0' && RepeatDigits == 0 ) { LeftTopPos.column = 0; GoToColumnOK( 1 ); DCDisplayAllLines(); return( ERR_NO_ERR ); } if( RepeatDigits == MAX_REPEAT_STRING - 1 ) { DoneRepeat(); return( ERR_REPEAT_STRING_TOO_LONG ); } if( repeatWindow == NO_WINDOW && EditFlags.RepeatInfo ) { rc = NewWindow2( &repeatWindow, &repcntw_info ); if( rc != ERR_NO_ERR ) { DoneRepeat(); return( rc ); } WindowTitle( repeatWindow, "Repeat Count" ); } RepeatString[RepeatDigits++] = LastEvent; RepeatString[RepeatDigits] = 0; if( repeatWindow != NO_WINDOW ) { UpdateRepeatString( RepeatString ); } return( GOT_A_DIGIT ); } /* DoDigit */
/* * 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 */
/* * 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 */
void JumpTo( i_mark *pos ) { if( CurrentPos.line != pos->line ) { GoToLineNoRelCurs( pos->line ); } if( CurrentPos.column != pos->column ) { GoToColumnOK( pos->column ); } }
/* * continueInsertText - continue in insert mode after mouse events */ static void continueInsertText( int col, bool overstrike ) { overStrike = overstrike; abbrevCnt = 0; if( !EditFlags.Modeless ) { UpdateEditStatus(); } EditFlags.Dotable = TRUE; EditFlags.NoReplaceSearchString = TRUE; EditFlags.InsertModeActive = TRUE; if( col > 1 && CurrentLine->len == 0 ) { col = 1; } GoToColumnOK( col ); GetCurrentLine(); } /* continueInsertText */
/* * 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 */
/* * DeleteAndInsertText - delete text range, then insert at beginning */ vi_rc DeleteAndInsertText( int scol, int ecol ) { int startcol; vi_rc rc; StartUndoGroup( UndoStack ); CurrentLineReplaceUndoStart(); currLineRepUndo = TRUE; if( ecol >= 0 ) { if( CurrentLine->len > 0 ) { rc = DeleteBlockFromCurrentLine( scol, ecol, FALSE ); if( rc == ERR_NO_ERR ) { startcol = CurrentPos.column; if( scol > ecol ) { startcol = ecol + 1; } if( startcol > WorkLine->len ) { startcol = WorkLine->len + 1; } DisplayWorkLine( TRUE ); ReplaceCurrentLine(); rc = GoToColumnOK( startcol ); } if( rc != ERR_NO_ERR ) { CurrentLineReplaceUndoCancel(); EndUndoGroup( UndoStack ); return( rc ); } } else { ReplaceCurrentLine(); } } continueInsertText( CurrentPos.column, FALSE ); return( ERR_NO_ERR ); } /* DeleteAndInsertText */
/* * IMCursorKey - handle cursor keys in insert mode */ vi_rc IMCursorKey( void ) { int wlen; event *ev; int type; wlen = WorkLine->len + 1; if( wlen == 0 ) { wlen = CurrentLine->len + 1; } /* * handle movement on the same line */ switch( LastEvent ) { case VI_KEY( HOME ): GoToColumn( 1, wlen ); abbrevCnt = 0; return( ERR_NO_ERR ); case VI_KEY( END ): GoToColumnOK( wlen ); abbrevCnt = 0; return( ERR_NO_ERR ); case VI_KEY( LEFT ): GoToColumn( CurrentPos.column - 1, wlen ); abbrevCnt = 0; return( ERR_NO_ERR ); case VI_KEY( RIGHT ): GoToColumn( CurrentPos.column + 1, wlen ); abbrevCnt = 0; return( ERR_NO_ERR ); } /* * handle movement that leaves the current line */ ev = &EventList[LastEvent]; if( EditFlags.Modeless ) { type = ev->alt_b.type; } else { type = ev->b.type; } if( needNewUndoForLine ) { if( type == EVENT_REL_MOVE || type == EVENT_ABS_MOVE ) { DoMove( ev ); } else { if( EditFlags.Modeless ) { ev->alt_rtn.old(); } else { ev->rtn.old(); } } return( ERR_NO_ERR ); } if( CurrentPos.column > WorkLine->len ) { GoToColumnOK( WorkLine->len + 1 ); } doneWithCurrentLine(); if( type == EVENT_REL_MOVE || type == EVENT_ABS_MOVE ) { DoMove( ev ); } else { if( EditFlags.Modeless ) { ev->alt_rtn.old(); } else { ev->rtn.old(); } } needNewUndoForLine = TRUE; abbrevCnt = 0; return( ERR_NO_ERR ); } /* IMCursorKey */
/* * IMEnter - process the enter key in insert mode */ vi_rc IMEnter( void ) { char *buff, *buffx; int len, col, el; if( CurrentFile == NULL ) { return( ERR_NO_FILE ); } CurrentFile->need_autosave = TRUE; startNewLineUndo(); CheckAbbrev( abbrevBuff, &abbrevCnt ); abbrevCnt = 0; /* * truncate the working line */ buff = StaticAlloc(); buffx = StaticAlloc(); el = WorkLine->len - CurrentPos.column + 1; if( el > 0 && WorkLine->len > 0 ) { memcpy( buff, &WorkLine->data[CurrentPos.column - 1], el + 1 ); WorkLine->len -= el; WorkLine->data[CurrentPos.column - 1] = 0; } else { el = 0; buff[0] = 0; } len = trimWorkLine(); /* * replace the current line with the working copy */ ReplaceCurrentLine(); if( currLineRepUndo ) { CurrentLineReplaceUndoEnd( FALSE ); currLineRepUndo = FALSE; } /* * create a new line, insert leading spaces if needed * and copy in the truncation */ if( EditFlags.AutoIndent ) { len = GetAutoIndentAmount( buffx, len, FALSE ); el += len; strcat( buffx, buff ); AddNewLineAroundCurrent( buffx, el, INSERT_AFTER ); col = len + 1; } else { AddNewLineAroundCurrent( buff, el, INSERT_AFTER ); col = 1; } UndoInsert( CurrentPos.line + 1, CurrentPos.line + 1, UndoStack ); /* * display the result */ DCDisplayAllLines(); GoToLineRelCurs( CurrentPos.line + 1 ); GoToColumnOK( col ); GetCurrentLine(); StaticFree( buff ); StaticFree( buffx ); return( ERR_NO_ERR ); } /* IMEnter */
/* * 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 */