/* * RestoreCurrentFilePos */ void RestoreCurrentFilePos( void ) { vi_rc rc; CurrentFile = oldFile[stackDepth]; CurrentPos = oldCurrentPos[stackDepth]; LeftTopPos = oldLeftTopPos[stackDepth]; if( CurrentFile != NULL ) { rc = CGimmeLinePtr( CurrentPos.line, &CurrentFcb, &CurrentLine ); if( rc == ERR_NO_SUCH_LINE ) { if( CurrentFile->fcbs.tail != NULL ) { CurrentPos.line = CurrentFile->fcbs.tail->end_line; CGimmeLinePtr( CurrentPos.line, &CurrentFcb, &CurrentLine ); } } } else { CurrentFcb = NULL; CurrentLine = NULL; } ValidateCurrentColumn(); VarAddRandC(); stackDepth--; } /* RestoreCurrentFilePos */
/* * GetHiddenBreaks */ linenum GetHiddenLineBreaks( linenum s, linenum e ) { linenum curr; line *cline; fcb *cfcb; int i; linenum cnt, s1, e1, tmp; if( s > e ) { tmp = s; s = e; e = tmp; } cnt = 0L; curr = s; while( curr <=e ) { i = CGimmeLinePtr( curr, &cfcb, &cline ); if( i ) { break; } if( cline->u.ld.hidden ) { GetHiddenRange( curr, &s1, &e1 ); curr = e1 + 1; cnt++; } else { curr++; } } return( cnt ); } /* GetHiddenLineBreaks */
/* * SetCurrentLine - reset current line after changes in current file structure */ vi_rc SetCurrentLine( linenum lineno ) { int text_lines; fcb *cfcb; line *cline; vi_rc rc; if( lineno <= 0 ) { lineno = 1; } rc = CGimmeLinePtr( lineno, &cfcb, &cline ); if( rc != ERR_NO_ERR ) { return( rc ); } CurrentLine = cline; CurrentFcb = cfcb; text_lines = WindowAuxInfo( current_window_id, WIND_INFO_TEXT_LINES ); if( lineno < LeftTopPos.line || lineno > (LeftTopPos.line + text_lines - 1) ) { LeftTopPos.line = lineno - text_lines / 2; } if( LeftTopPos.line < 1 ) { LeftTopPos.line = 1; } CheckCurrentColumn(); SetCurrentLineNumber( lineno ); UpdateStatusWindow(); SetWindowCursor(); DCDisplayAllLines(); return( ERR_NO_ERR ); } /* SetCurrentLine */
/* * GimmeCurrentWord - fetch word at cursor position */ vi_rc GimmeCurrentWord( char *buffer, int buffer_size, bool big ) { i_mark curr, end, start; int i, j; line *line; fcb *fcb; vi_rc rc; curr = CurrentPos; start = curr; rc = MarkEndOfNextWordForward( &end, &curr, big ); if( rc == ERR_NO_ERR ) { rc = CGimmeLinePtr( end.line, &fcb, &line ); if( rc == ERR_NO_ERR ) { i = start.column - 1; j = 0; buffer_size -= 1; while( i < end.column && j < buffer_size ) { buffer[j++] = line->data[i++]; } buffer[j] = '\0'; } } return( rc ); } /* GimmeCurrentWord */
/* * markRegion - mark a region as selected/unselected */ static void markRegion( bool val ) { fcb *cfcb; line *cline; linenum ln; linenum s, e; if( SelRgn.start.line > SelRgn.end.line ) { s = SelRgn.end.line; e = SelRgn.start.line; } else { s = SelRgn.start.line; e = SelRgn.end.line; } if( CGimmeLinePtr( s, &cfcb, &cline ) ) { return; } ln= e - s; for( ;; ) { cline->u.ld.hilite = val; ln--; if( ln < 0 ) { break; } if( CGimmeNextLinePtr( &cfcb, &cline ) ) { break; } } } /* markRegion */
/* * SetSelectedRegion - set the selected region to a specific area */ vi_rc SetSelectedRegion( range *r ) { vi_rc rc; line *line; fcb *fcb; UnselectRegion(); SelRgn.start.line = r->start.line; SelRgn.end.line = r->end.line; SelRgn.start_col_v = 1; if( r->line_based ) { SelRgn.lines = TRUE; SelRgn.start.column = 1; SelRgn.end.column = LineLength( r->end.line ); } else { SelRgn.lines = FALSE; if( r->start.column < r->end.column ) { SelRgn.start.column = r->start.column + 1; SelRgn.end.column = r->end.column + 2; } else { SelRgn.start.column = r->end.column + 1; SelRgn.end.column = r->start.column + 2; } rc = CGimmeLinePtr( SelRgn.start.line, &fcb, &line ); if( rc == ERR_NO_ERR ) { SelRgn.start_col_v = WinVirtualCursorPosition( line->data, SelRgn.start.column ); } } SelRgn.selected = TRUE; updateRegion(); return( ERR_NO_ERR ); } /* SetSelectedRegion */
/* * getBracketLoc - find a matching '(' for a ')' */ static vi_rc getBracketLoc( i_mark *pos ) { vi_rc rc; char tmp[3]; int len; // linenum lne; tmp[0] = '\\'; tmp[1] = ')'; tmp[2] = 0; // lne = CurrentPos.line; RegExpAttrSave( -1, NULL ); rc = GetFind( tmp, pos, &len, FINDFL_BACKWARDS | FINDFL_NOERROR | FINDFL_NOCHANGE ); RegExpAttrRestore(); if( pos->line != CurrentPos.line ) { return( ERR_FIND_NOT_FOUND ); } if( rc != ERR_NO_ERR ) { return( rc ); } /* * find the matching '(' */ CurrentPos = *pos; CGimmeLinePtr( CurrentPos.line, &CurrentFcb, &CurrentLine ); rc = FindMatch( pos ); return( rc ); } /* getBracketLoc */
/* * HideLineRange - hide/unhide a given line range */ vi_rc HideLineRange( linenum s, linenum e, bool unhide ) { vi_rc rc; bool hideval; fcb *cfcb; line *cline; char *st; linenum c; hideval = TRUE; if( unhide ) { hideval = FALSE; } for( c = s; c <= e; c++ ) { rc = CGimmeLinePtr( c, &cfcb, &cline ); if( rc != ERR_NO_ERR ) { return( rc ); } cline->u.ld.hidden = hideval; } DCDisplayAllLines(); if( unhide ) { st = "revealed"; } else { st = "hidden"; } Message1( "%l lines %s", e - s + 1, st ); EditFlags.Dotable = TRUE; return( DO_NOT_CLEAR_MESSAGE_WINDOW ); } /* HideLineRange */
/* * GetHiddenLineCount - get number of hidden lines in a range */ linenum GetHiddenLineCount( linenum s, linenum e ) { line *cline; fcb *cfcb; int i; linenum cnt, tmp; if( s > e ) { tmp = s; s = e; e = tmp; } i = CGimmeLinePtr( s, &cfcb, &cline ); if( i ) { return( 0L ); } cnt = 0L; while( s <= e ) { if( cline->u.ld.hidden ) { cnt++; } s++; i = CGimmeNextLinePtr( &cfcb, &cline ); if( i ) { break; } } return( cnt ); } /* GetHiddenLineCount */
/* * CAdvanceToLine - advance to given line in file */ vi_rc CAdvanceToLine( linenum l ) { fcb *cfcb; line *cline; vi_rc rc; rc = CGimmeLinePtr( l, &cfcb, &cline ); return( rc ); } /* CAdvanceToLine */
int LineLength( linenum l ) { line *line; fcb *fcb; vi_rc rc; rc = CGimmeLinePtr( l, &fcb, &line ); if( rc != ERR_NO_ERR ) { return( 0 ); } return( line->len ); }
/* * SaveAndResetFilePos - as it sounds */ vi_rc SaveAndResetFilePos( linenum n1 ) { vi_rc rc; SaveCurrentFilePos(); SetCurrentLineNumber( n1 ); rc = CGimmeLinePtr( n1, &CurrentFcb, &CurrentLine ); if( rc != ERR_NO_ERR ) { RestoreCurrentFilePos(); } return( rc ); } /* SaveAndResetFilePos */
/* * SplitUpLine - split up a line with SPLIT_CHAR's in them */ linenum SplitUpLine( linenum cl ) { linenum extra = 0; int j, i, k; char *buff; /* * run through, and for every 0x01, make a new line */ for( ;; ) { /* * get current line */ CurrentPos.line = cl + extra; CGimmeLinePtr( CurrentPos.line, &CurrentFcb, &CurrentLine ); GetCurrentLine(); for( i = 0; i <= WorkLine->len; i++ ) { /* * found a place to split. make this line shorter, * and create a new line with the rest of the data * for this line */ if( WorkLine->data[i] == SPLIT_CHAR ) { buff = StaticAlloc(); k = 0; for( j = i + 1; j <= WorkLine->len; j++ ) { buff[k++] = WorkLine->data[j]; } WorkLine->data[i] = 0; WorkLine->len = i; ReplaceCurrentLine(); AddNewLineAroundCurrent( buff, k - 1, INSERT_AFTER ); extra++; StaticFree( buff ); break; } /* * at the very end, undo what we did and go back */ if( WorkLine->data[i] == 0 ) { ReplaceCurrentLine(); UndoInsert( cl + 1, cl + extra, UndoStack ); return( extra ); } } } } /* SplitUpLine */
/* * GetHiddenRange - get range of lines hidden around a given line */ void GetHiddenRange( linenum l, linenum *s, linenum *e ) { line *cline, *oline; fcb *cfcb, *ofcb; int i; (*s) = (*e) = l; i = CGimmeLinePtr( l, &ofcb, &oline ); if( i ) { return; } /* * go back */ cfcb = ofcb; cline = oline; for( ;; ) { i = GimmePrevLinePtr( &cfcb, &cline ); if( i ) { break; } if( cline->u.ld.hidden ) { (*s)--; continue; } else { break; } } /* * go forwards */ cfcb = ofcb; cline = oline; for( ;; ) { i = CGimmeNextLinePtr( &cfcb, &cline ); if( i ) { break; } if( cline->u.ld.hidden ) { (*e)++; continue; } else { break; } } } /* GetHiddenRange */
void InitFORTRANFlags( linenum line_no ) { char *text; // char *start; line *line; fcb *fcb; vi_rc rc; int numQuotes = 0; flags.inString = false; rc = CGimmeLinePtr( line_no, &fcb, &line ); if( rc != ERR_NO_ERR ) { // probably past eof return; } if( isInitialLine( line ) ) { return; } for( ;; ) { rc = GimmePrevLinePtr( &fcb, &line ); if( rc != ERR_NO_ERR ) { break; } text = line->u.ld.nolinedata ? WorkLine->data : line->data; // start = text; if( iscomment( *text ) ) { continue; } while( *text != '\0' ) { if( *text == '!' ) { // rest of line is part of a comment break; } else if( *text == '\'' ) { numQuotes ^= 1; } text++; } if( isInitialLine( line ) ) { break; } } if( numQuotes == 1 ) { flags.inString = true; } }
/* * 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 */
/* * SetSelectedRegionFromLine - set the SelRgn w/ start_v */ vi_rc SetSelectedRegionFromLine( range *r, linenum lineno ) { vi_rc rc; fcb *fcb; line *line; char *data; SetSelectedRegion( r ); rc = CGimmeLinePtr( lineno, &fcb, &line ); if( rc != ERR_NO_ERR ) { return( rc ); } data = line->u.ld.nolinedata ? WorkLine->data : line->data; SelRgn.start_col_v = GetVirtualCursorPosition( data, SelRgn.start.column ); return( ERR_NO_ERR ); } /* SetSelectedRegionFromLine */
/* * findMatchingBrace find '{' for a '}' */ static vi_rc findMatchingBrace( i_mark *pos1 ) { vi_rc rc; i_mark pos2; rc = FindMatch( pos1 ); if( rc != ERR_NO_ERR ) { return( rc ); } SaveCurrentFilePos(); CurrentPos = *pos1; CGimmeLinePtr( CurrentPos.line, &CurrentFcb, &CurrentLine ); rc = getBracketLoc( &pos2 ); RestoreCurrentFilePos(); if( rc == ERR_NO_ERR ) { *pos1 = pos2; } return( ERR_NO_ERR ); } /* findMatchingBrace */
void DCDisplaySomeLines( int start, int end ) { int i; dc dc; linenum line_no; line *line; fcb *cfcb; vi_rc rc; if( EditFlags.DisplayHold || CurrentFile == NULL || CurrentInfo == NULL ) { return; } assert( CurrentInfo ); if( CurrentInfo->dc_size == 0 ) { return; } CurrentFile->needs_display = true; shaveRange( &start, &end ); cfcb = CurrentFcb; line_no = LeftTopPos.line + start; rc = CGimmeLinePtr( line_no, &cfcb, &line ); if( rc != ERR_NO_ERR && rc != ERR_NO_SUCH_LINE ) { return; } CTurnOffFileDisplayBits(); cfcb->on_display = true; dc = CurrentInfo->dc; dc += start; for( i = start; i <= end; i++ ) { dc->display = true; dc++; } }
/* * ptrFromMark: Return a character pointer to the position in some * line's data which is indicated by the given mark. */ static char *ptrFromMark( i_mark *curr ) { line *line; fcb *fcb; vi_rc rc; char *ptr; ptr = NULL; rc = CGimmeLinePtr( curr->line, &fcb, &line ); if( rc == ERR_NO_ERR ) { if( curr->column > 0 && curr->column <= line->len ) { ptr = &(line->data[curr->column - 1]); } else if( !EditFlags.WordWrap ) { if( curr->column == 0 ) { ptr = &(line->data[curr->column]); } else { ptr = &(line->data[line->len - 1]); } noWrap = true; } } return( ptr ); } /* ptrFromMark */
/* * changeOneLine: change the case for each character on the given line * from the starting column given by start_col (base 0) to the column * denoted by end_col (base 0). */ static vi_rc changeOneLine( linenum line_num, int start_col, int end_col ) { line *line; fcb *fcb; int num_cols, i; char *s; vi_rc rc; rc = CGimmeLinePtr( line_num, &fcb, &line ); if( rc == ERR_NO_ERR ) { assert( end_col < line->len && end_col >= start_col ); num_cols = end_col - start_col + 1; s = &line->data[start_col]; for( i = 0; i < num_cols; i++ ) { if( isupper( *s ) ) { *s = tolower( *s ); } else { *s = toupper( *s ); } s++; } } return( rc ); }
/* * IMCloseBrace - handle '}' in insert mode */ vi_rc IMCloseBrace( void ) { int i, j; int ts; fcb *cfcb; line *cline; vi_rc rc; int newcol; i_mark pos; startNewLineUndo(); insertChar( TRUE, FALSE ); newcol = CurrentPos.column + 1; if( EditFlags.ShowMatch ) { ReplaceCurrentLine(); rc = FindMatch( &pos ); if( rc == ERR_NO_ERR ) { tempMatch( &pos ); } GetCurrentLine(); } if( EditFlags.CMode ) { i = 0; while( isspace( WorkLine->data[i] ) ) { i++; } if( WorkLine->data[i] == '}' ) { /* * added a {, so: * find matching } * find out indentation of that line * shift current line over to that indentation * set current indentation to that */ ReplaceCurrentLine(); rc = findMatchingBrace( &pos ); if( rc == ERR_NO_ERR ) { newcol = VirtualColumnOnCurrentLine( CurrentPos.column ); CGimmeLinePtr( pos.line, &cfcb, &cline ); i = FindStartOfALine( cline ); i = GetVirtualCursorPosition( cline->data, i ); j = i - VirtualColumnOnCurrentLine( CurrentPos.column ); ts = EditVars.ShiftWidth; if( j > 0 ) { EditVars.ShiftWidth = j; Shift( CurrentPos.line, CurrentPos.line, '>', FALSE ); } else if( j < 0 ) { EditVars.ShiftWidth = -j; Shift( CurrentPos.line, CurrentPos.line, '<', FALSE ); } EditVars.ShiftWidth = ts; newcol = 1 + RealColumnOnCurrentLine( j + newcol ); } GetCurrentLine(); } } GoToColumn( newcol, WorkLine->len + 1 ); return( ERR_NO_ERR ); } /* IMCloseBrace */
/* * SrcAssign - assign a value to a variable */ vi_rc SrcAssign( const char *data, vlist *vl ) { int i, j, k, l; long val; bool rxflag = false; bool envflag = false; bool setflag = false; bool expflag = false; bool timeflag = false; bool lnumflag = false; char tmp[MAX_SRC_LINE], tmp1[MAX_SRC_LINE], name[MAX_SRC_LINE]; const char *v1; char *t; vars *v; jmp_buf jmpaddr; time_t tod; bool check_end; char tmpstr[MAX_STR]; /* * get assign syntax : * ASSIGN %v = /v1/(r)($)(@)(x)(l)(t) * possible v1: * strlen %a * strchr %a ch * substr %a n1 n2 */ data = GetNextWord1( data, tmp ); if( *tmp == '\0' ) { return( ERR_SRC_INVALID_ASSIGN ); } if( !VarName( name, tmp, vl ) ) { return( ERR_SRC_INVALID_ASSIGN ); } data = GetNextWord1( data, tmp ); if( *tmp == '\0' ) { return( ERR_SRC_INVALID_ASSIGN ); } if( stricmp( tmp, "=" ) != 0 ) { return( ERR_SRC_INVALID_ASSIGN ); } data = SkipLeadingSpaces( data ); if( data[0] == '/' || data[0] == '"' ) { check_end = false; if( data[0] == '"' ) { data = GetNextWord( data, tmp, SingleQuote ); if( data[0] == '"' ) { check_end = true; } } else { data = GetNextWord( data, tmp, SingleSlash ); if( data[0] == '/' ) { check_end = true; } } if( check_end ) { for( ++data; data[0] != '\0'; data++ ) { switch( data[0] ) { case 't': timeflag = true; break; case 'r': rxflag = true; break; case '$': envflag = true; break; case '@': setflag = true; break; case 'x': expflag = true; break; case 'l': lnumflag = true; break; } } } Expand( tmp1, tmp, vl ); } else { data = GetNextWord1( data, tmp ); if( *tmp == '\0' ) { return( ERR_SRC_INVALID_ASSIGN ); } j = Tokenize( StrTokens, tmp, false ); if( j != TOK_INVALID ) { data = GetNextWord1( data, tmp ); if( *tmp == '\0' ) { return( ERR_SRC_INVALID_ASSIGN ); } if( !VarName( tmp1, tmp, vl ) ) { return( ERR_SRC_INVALID_ASSIGN ); } v = VarFind( tmp1, vl ); switch( j ) { case STR_T_STRLEN: if( v != NULL ) { sprintf( tmp1, "%d", v->len ); } else { strcpy( tmp1, "0" ); } break; case STR_T_SUBSTR: data = GetNextWord1( data, tmp ); if( *tmp == '\0' ) { return( ERR_SRC_INVALID_ASSIGN ); } Expand( tmp1, tmp, vl ); i = atoi( tmp1 ) - 1; data = GetNextWord1( data, tmp ); if( *tmp == '\0' ) { return( ERR_SRC_INVALID_ASSIGN ); } Expand( tmp1, tmp, vl ); j = atoi( tmp1 ) - 1; if( v == NULL ) { tmp1[0] = '\0'; break; } if( j >= v->len || i < 0 ) { tmp1[0] = '\0'; } else { l = 0; for( k = i; k <= j; k++ ) { tmp1[l++] = v->value[k]; } tmp1[l] = '\0'; } break; case STR_T_STRCHR: data = GetNextWord1( data, tmp ); if( *tmp == '\0' ) { return( ERR_SRC_INVALID_ASSIGN ); } Expand( tmp1, tmp, vl ); if( v == NULL ) { j = -1; } else { t = strchr( v->value, tmp1[0] ); if( t != NULL ) { j = t - v->value; } else { j = -1; } j++; } sprintf( tmp1, "%d", j ); break; } } else { Expand( tmp1, tmp, vl ); } } /* * regular expression subs. */ if( rxflag && CurrentRegularExpression != NULL ) { RegSub( CurrentRegularExpression, tmp1, tmp, CurrentPos.line ); strcpy( tmp1, tmp ); } /* * special processing */ if( envflag ) { v1 = getenv( tmp1 ); if( v1 == NULL ) { v1 = ""; } } else if( setflag ) { v1 = GetASetVal( tmp1, tmpstr ); } else if( timeflag ) { tod = time( NULL ); strftime( tmp, sizeof( tmp ), tmp1, localtime( &tod ) ); v1 = tmp; } else if( expflag || lnumflag ) { i = setjmp( jmpaddr ); if( i != 0 ) { return( (vi_rc)i ); } StartExprParse( tmp1, jmpaddr ); val = GetConstExpr(); if( lnumflag ) { fcb *cfcb; line *cline; vi_rc rc; rc = CGimmeLinePtr( val, &cfcb, &cline ); v1 = cline->data; if( rc != ERR_NO_ERR ) { v1 = ""; } } else { v1 = ltoa( val, tmp1, EditVars.Radix ); } } else { v1 = tmp1; } VarAddStr( name, v1, vl ); return( ERR_NO_ERR ); } /* SrcAssign */
/* * 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 */
/* * setLineCol - set up line and column to start search at */ static vi_rc setLineCol( char *st, i_mark *pos, find_type flags ) { fcb *cfcb; line *cline; bool wrapped; /* * get next position */ if( st[0] == 0 ) { if( lastFind == NULL ) { return( ERR_NO_PREVIOUS_SEARCH_STRING ); } if( lastPos.line != 0 && currPos.column == CurrentPos.column && currPos.line == CurrentPos.line ) { *pos = lastPos; if( flags & FINDFL_FORWARD ) { pos->column += 1; } else { pos->column -= 2; } } else { *pos = CurrentPos; if( flags & FINDFL_FORWARD ) { pos->column += 0; } else { pos->column -= 2; } } AddString2( &sStr, lastFind ); } else { if( !(flags & FINDFL_NOCHANGE) ) { AddString2( &lastFind, st ); } AddString2( &sStr, st ); *pos = CurrentPos; if( flags & FINDFL_FORWARD ) { pos->column += 0; } else { pos->column -= 2; } } /* * wrap if needed */ if( flags & FINDFL_NEXTLINE ) { wrapped = FALSE; if( flags & FINDFL_FORWARD ) { pos->column = 0; pos->line += 1; if( IsPastLastLine( pos->line ) ) { pos->line = 1; wrapped = TRUE; } } else { pos->line -= 1; if( pos->line == 0 ) { CFindLastLine( &pos->line ); wrapped = TRUE; } CGimmeLinePtr( pos->line, &cfcb, &cline ); pos->column = cline->len - 1; if( pos->column < 0 ) { pos->column = 0; } } if( wrapped && !(flags & FINDFL_WRAP) ) { if( flags & FINDFL_FORWARD ) { return( ERR_FIND_END_OF_FILE ); } else { return( ERR_FIND_TOP_OF_FILE ); } } } return( ERR_NO_ERR ); } /* setLineCol */
static void getLiteral( ss_block *ss_new, char *start, int skip ) { char *text; char lastchar = '\0'; bool empty; bool multiLine = flags.inString; line *line; fcb *fcb; char *data; vi_rc rc; empty = true; for( text = start + skip; *text != '\0'; ++text ) { if( text[0] == '\'' ) { if( text[1] != '\'' ) break; ++text; } empty = false; } flags.inString = false; if( *text == '\0' ) { // if next line a continuation line, then flag flags.inString, else // flag unterminated string rc = CGimmeLinePtr( thisLine + 1, &fcb, &line ); for( ;; ) { if( rc != ERR_NO_ERR ) { break; } data = (line->u.ld.nolinedata) ? WorkLine->data : line->data; if( !iscomment( data[0] ) ) { break; } rc = CGimmeNextLinePtr( &fcb, &line ); } ss_new->type = SE_INVALIDTEXT; if( rc == ERR_NO_ERR && !isInitialLine( line ) ) { ss_new->type = SE_STRING; flags.inString = true; } } else { text++; lastchar = tolower( *text ); switch( lastchar ) { case 'c': text++; ss_new->type = SE_STRING; break; case 'x': text++; ss_new->type = SE_HEX; break; case 'o': text++; ss_new->type = SE_OCTAL; break; default: // hard to say if invalid or not - take a guess if( islower( *text ) ) { text++; ss_new->type = SE_INVALIDTEXT; } else { ss_new->type = SE_STRING; } break; } } ss_new->len = text - start; if( empty && !multiLine ) { ss_new->type = SE_INVALIDTEXT; } }
/* * goToLine - go to a specified line number */ static vi_rc goToLine( linenum lineno, bool relcurs ) { int text_lines, tl; linenum diff, cwl, nwl; // linenum s, e, hiddcnt; bool dispall, pageshift; fcb *cfcb; line *cline; int pad; vi_rc rc; if( lineno < 1 ) { return( ERR_NO_SUCH_LINE ); } /* * get pointer to requested line */ rc = CGimmeLinePtr( lineno, &cfcb, &cline ); if( rc != ERR_NO_ERR ) { return( rc ); } #if 0 if( cline->u.ld.hidden ) { GetHiddenRange( lineno, &s, &e ); if( lineno > CurrentPos.line ) { lineno = e + 1; } else { lineno = s - 1; } rc = CGimmeLinePtr( lineno, &cfcb, &cline ); if( rc != ERR_NO_ERR ) { return( rc ); } } #endif /* * compute new location */ CurrentFcb = cfcb; CurrentLine = cline; diff = lineno - CurrentPos.line; if( diff == 0 && !EditFlags.GlobalInProgress ) { return( ERR_NO_ERR ); } cwl = CurrentPos.line - LeftTopPos.line + 1; nwl = cwl + diff; /* * if we go off the window, relocate */ pageshift = false; dispall = false; text_lines = WindowAuxInfo( current_window_id, WIND_INFO_TEXT_LINES ); if( nwl < 1 || nwl > text_lines ) { tl = text_lines / 2; if( !relcurs ) { LeftTopPos.line = lineno - tl; } else { LeftTopPos.line = lineno + 1 - cwl; pad = ( EditFlags.JumpyScroll ) ? 1 : 0; if( diff > 0 ) { LeftTopPos.line += pad; diff += pad; } else { LeftTopPos.line -= pad; diff -= pad; } if( diff > -tl && diff < tl && !dispall ) { pageshift = true; } } if( LeftTopPos.line < 1 ) { assert( diff <= 0 ); // < -> <= W.Briscoe 20031003 to avoid debug build failure of // C:\watcom\source\docs\nt) wmake -h -f ..\mif\master.mif hbook=wccerrs dotarget=nt diff += ( 1 - LeftTopPos.line ); LeftTopPos.line = 1; } if( LeftTopPos.line > lineno ) { assert( diff > 0 ); diff = LeftTopPos.line - lineno; LeftTopPos.line = lineno; } dispall = true; } #if 0 hiddcnt = GetHiddenLineCount( LeftTopPos.line, lineno ); if( hiddcnt > 0 ) { pageshift = false; dispall = true; } #endif if( CheckCurrentColumn() || EditFlags.Dragging ) { // pageshift wont help if we also have to column shift // and not really useful if dragging dispall = true; pageshift = false; } /* call SetCurrentLineNumber AFTER LeftTopPos.line set & CurrentColumn checked */ SetCurrentLineNumber( lineno ); if( pageshift ) { dispall = false; ShiftWindowUpDown( current_window_id, diff ); if( EditFlags.LineNumbers ) { ShiftWindowUpDown( curr_num_window_id, diff ); } if( diff > 0 ) { DCDisplaySomeLines( text_lines - diff, text_lines - 1 ); } else { DCDisplaySomeLines( 0, -diff - 1 ); } } UpdateStatusWindow(); SetWindowCursor(); if( dispall ) { DCInvalidateAllLines(); // lines definitely invalid DCDisplayAllLines(); } return( ERR_NO_ERR ); } /* goToLine */
void InitPerlFlags( linenum line_no ) { fcb *fcb; char *text; line *thisline; // line *topline; vi_rc rc; bool withinQuotes = false; line *line; bool inBlock = false; flags.inString = false; flags.beforeRegExp = true; flags.doubleRegExp = false; CGimmeLinePtr( line_no, &fcb, &thisline ); line = thisline; rc = GimmePrevLinePtr( &fcb, &line ); while( rc == ERR_NO_ERR ) { if( line->data[line->len - 1] != '\\' ) { break; } inBlock = true; rc = GimmePrevLinePtr( &fcb, &line ); } if( rc == ERR_NO_ERR ) { // topline = line; if( inBlock ) { CGimmeNextLinePtr( &fcb, &line ); } } else { // topline = NULL; if( inBlock ) { CGimmeLinePtr( 1, &fcb, &line ); } else { return; } } if( inBlock ) { // parse down through lines, noticing " while( line != thisline ) { text = line->data; while( *text ) { if( *text == '"' ) { if( !withinQuotes ) { withinQuotes = true; } else if( *(text - 1) != '\\' || *(text - 2) == '\\' ) { withinQuotes = false; } } text++; } rc = CGimmeNextLinePtr( &fcb, &line ); } if( withinQuotes ) { flags.inString = true; } } }
void InitRexxFlags( linenum line_no ) { fcb *fcb; char *text; char *starttext; line *thisline; line *topline; char topChar; vi_rc rc; bool withinQuotes = false; line *line; bool inBlock = false; flags.inCComment = false; flags.inCPPComment = false; flags.inString = false; flags.inPreprocessor = false; CGimmeLinePtr( line_no, &fcb, &thisline ); line = thisline; while( (rc = GimmePrevLinePtr( &fcb, &line )) == ERR_NO_ERR ) { if( line->data[line->len - 1] != '\\' ) { break; } inBlock = true; } if( rc == ERR_NO_ERR ) { topline = line; if( inBlock ) { CGimmeNextLinePtr( &fcb, &line ); } } else { topline = NULL; if( inBlock ) { CGimmeLinePtr( 1, &fcb, &line ); } else { return; } } if( inBlock ) { // jot down whether it started with # text = line->data; while( *text != '\0' && isspace( *text ) ) { text++; } topChar = *text; // parse down through lines, noticing /*, */ and " while( line != thisline ) { for( text = line->data; ; ++text ) { for( ; *text != '\0' && *text != '/'; ++text ) { if( text[0] == '"' ) { if( !withinQuotes ) { withinQuotes = true; } else if( text[-1] != '\\' || text[-2] == '\\' ) { withinQuotes = false; } } } if( text[0] == '\0' ) { break; } if( !withinQuotes ) { if( text[-1] == '/' ) { flags.inCPPComment = true; } else if( text[1] == '*' ) { flags.inCComment = true; lenCComment = 100; } } if( text[-1] == '*' && !withinQuotes ) { flags.inCComment = false; } } rc = CGimmeNextLinePtr( &fcb, &line ); } // if not in a comment (and none above), we may be string or pp if( !flags.inCComment ) { if( topChar == '#' && !EditFlags.PPKeywordOnly ) { flags.inPreprocessor = true; } if( withinQuotes ) { flags.inString = true; } } } if( topline == NULL ) { return; } if( !flags.inCComment ) { // keep going above multi-line thing till hit /* or */ line = topline; do { starttext = line->data; for( text = starttext + line->len; ; --text ) { while( text != starttext && *text != '/' ) { text--; } if( text[1] == '*' && text[0] == '/' && text[-1] != '/' ) { if( text == starttext ) { flags.inCComment = true; lenCComment = 100; return; } withinQuotes = false; do { text--; if( text[0] == '"' ) { if( !withinQuotes ) { withinQuotes = true; } else if( text[-1] != '\\' || text[-2] == '\\' ) { withinQuotes = false; } } } while( text != starttext ); if( withinQuotes ) { flags.inString = true; } else { flags.inCComment = true; lenCComment = 100; } return; } if( text == starttext ) { break; } if( text[-1] == '*' ) { // we may actually be in a string, but that's extreme // (if this becomes a problem, count the "s to beginning // of line, check if multiline, etc. etc.) return; } } rc = GimmePrevLinePtr( &fcb, &line ); } while( rc == ERR_NO_ERR ); } }
/* * 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 */