int EBuffer::LineCenter() { if (LineTrim() == 0) return 0; int ind = LineIndented(VToR(CP.Row)); int left = BFI(this, BFI_LeftMargin); int right = BFI(this, BFI_RightMargin); int len = LineLen(); //int chs = len - ind; int newind = left + ((right - left) - (len - ind)) / 2; if (newind < left) newind = left; return IndentLine(VToR(CP.Row), newind); }
// FindFunction -- search for line matching 'RoutineRegexp' // starting from current line + 'delta'. 'way' should be +1 or -1. int EBuffer::FindFunction(int delta, int way) { RxNode *regx; int line; PELine L; RxMatchRes res; if (BFS(this, BFS_RoutineRegexp) == 0) { View->MView->Win->Choice(GPC_ERROR, "Error", 1, "O&K", "No routine regexp."); return -1; } regx = RxCompile(BFS(this, BFS_RoutineRegexp)); if (regx == 0) { View->MView->Win->Choice(GPC_ERROR, "Error", 1, "O&K", "Failed to compile regexp '%s'", BFS(this, BFS_RoutineRegexp)); return -1; } //** Scan backwards from the current cursor position, Msg(S_BUSY, "Matching %s", BFS(this, BFS_RoutineRegexp)); line = VToR(CP.Row) + delta; while (line >= 0 && line < RCount) { L = RLine(line); if (RxExec(regx, L->Chars, L->Count, L->Chars, &res) == 1) break; line += way; } if (line < 0) line = 0; if (line >= RCount) line = RCount - 1; RxFree(regx); return line; }
int EBuffer::BlockExtendBegin() { CheckBlock(); ExtendGrab = 0; AutoExtend = 0; int Y = VToR(CP.Row); switch (BlockMode) { case bmStream: if ((Y == BB.Row) && (CP.Col == BB.Col)) ExtendGrab |= 1; if ((Y == BE.Row) && (CP.Col == BE.Col)) ExtendGrab |= 2; break; case bmLine: if (Y == BB.Row) ExtendGrab |= 1; if (Y == BE.Row) ExtendGrab |= 2; break; case bmColumn: if (Y == BB.Row) ExtendGrab |= 1; if (Y == BE.Row) ExtendGrab |= 2; if (CP.Col == BB.Col) ExtendGrab |= 4; if (CP.Col == BE.Col) ExtendGrab |= 8; break; } if (ExtendGrab == 0) { BlockBegin(); BlockEnd(); if (BlockMode == bmColumn) ExtendGrab = 1 | 2 | 4 | 8; else ExtendGrab = 1 | 2; } return 1; }
int EBuffer::KillChar() { int Y = VToR(CP.Row); if (CP.Col < LineLen()) { if (DelText(Y, CP.Col, 1)) return 1; } else if (LineJoin()) return 1; return 0; }
int EBuffer::MovePrevEqualIndent() { int L = VToR(CP.Row); int I = LineIndented(L); while (--L >= 0) if ((RLine(L)->Count > 0) && (LineIndented(L) == I)) return SetPosR(I, L); return 0; }
int EBuffer::KillLine() { int Y = VToR(CP.Row); if (Y == RCount - 1) { if (DelText(Y, 0, LineLen())) return 1; } else if (DelLine(Y)) return 1; return 0; }
int EBuffer::BlockEnd() { EPoint X; X.Row = VToR(CP.Row); X.Col = CP.Col; CheckBlock(); SetBE(X); return 1; }
int EBuffer::MoveNextEqualIndent() { int L = VToR(CP.Row); int I = LineIndented(L); while (L++ < RCount - 1) if ((RLine(L)->Count > 0) && (LineIndented(L) == I)) return SetPosR(I, L); return 0; }
int EBuffer::MoveFoldPrev() { /*FOLD00*/ int f = FindNearFold(VToR(CP.Row)); if ((f == 0) || (f == -1)) return 0; if (FF[f].line == VToR(CP.Row)) { do { f--; if (f < 0) return 0; if (RToV(FF[f].line) != -1) break; } while (1); } if (SetPosR(CP.Col, FF[f].line, tmLeft) == 0) return 0; return 1; }
int EBuffer::InsertSpacesToTab(int TSize) { int P = CP.Col, P1; if (BFI(this, BFI_InsertKillBlock) == 1) if (CheckBlock() == 1) if (BlockKill() == 0) return 0; if (TSize <= 0) TSize = BFI(this, BFI_TabSize); P1 = NextTab(P, TSize); if (BFI(this, BFI_Insert) == 0) { if (CP.Col < LineLen()) if (DelText(VToR(CP.Row), CP.Col, P1 - P) == 0) return 0; } if (InsText(VToR(CP.Row), CP.Col, P1 - P, 0) == 0) return 0; if (SetPos(P1, CP.Row) == 0) return 0; return 1; }
int EBuffer::TypeChar(char aCh) { // does abbrev expansion if appropriate if (BFI(this, BFI_InsertKillBlock) == 1) if (CheckBlock() == 1) if (BlockKill() == 0) return 0; if (ChClass(aCh) == 0 && BFI(this, BFI_Abbreviations) == 1) { PELine L = VLine(CP.Row); int C, P, P1, C1, Len, R; char Str[256]; EAbbrev *ab; R = VToR(CP.Row); C = CP.Col; P = CharOffset(L, C); if (P >= 0 && P <= L->Count) { //fprintf(stderr, "TypeChar 1\n"); P1 = P; C1 = ScreenPos(L, P); while ((P > 0) && ((ChClass(L->Chars[P - 1]) == 1) || (L->Chars[P - 1] == '_'))) P--; Len = P1 - P; C = ScreenPos(L, P); assert(C1 - C == Len); if (Len > 0 && Len < int (sizeof(Str))) { //fprintf(stderr, "TypeChar 2\n"); memcpy(Str, L->Chars + P, Len); Str[Len] = 0; ab = Mode->FindAbbrev(Str); if (ab) { //fprintf(stderr, "TypeChar 3\n"); if (ab->Replace != 0) { //fprintf(stderr, "TypeChar 4\n"); if (DelText(R, C, C1 - C) == 0) return 0; if (ab->Replace) { //fprintf(stderr, "TypeChar 5 %s <- %s\n", ab->Replace, ab->Match); Len = strlen(ab->Replace); if (InsText(R, C, Len, ab->Replace) == 0) return 0; if (SetPos(C + Len, CP.Row) == 0) return 0; } else { if (SetPos(C, CP.Row) == 0) return 0; } } else { if (((EGUI *)gui)->ExecMacro(View->MView->Win, ab->Cmd) == 0) return 0; } } } } } return InsertString(&aCh, 1); }
void EBuffer::FullRedraw() { // redraw all views EView *V = View; EEditPort *W; int Min, Max; while (V) { W = GetViewVPort(V); // Need to use real lines, not virtual // (similar to HilitMatchBracket) Min = VToR(W->TP.Row); Max = W->TP.Row + W->Rows; if (Max >= VCount) Max = RCount; else Max = VToR(Max); Draw(Min, Max); V = V->Next; if (V == View) break; } }
int EBuffer::Delete() { int Y = VToR(CP.Row); if (CheckBlock() == 1 && BFI(this, BFI_DeleteKillBlock)) { if (BlockKill() == 0) return 0; } else if (CP.Col < LineLen()) { if (BFI(this, BFI_DeleteKillTab)) { int P; int C = CP.Col, C1; P = CharOffset(RLine(Y), C); C1 = ScreenPos(RLine(Y), P + 1); if (DelText(Y, C, C1 - C) == 0) return 0; } else { ELine *L = RLine(Y); int C = CharOffset(L, CP.Col); if (L->Count > 0 && L->Chars[C] == '\t') { /* We're on top of tab character. Skip over all spaces and tabs so that only the last space/tab gets deleted. */ while (C < L->Count && (L->Chars[C+1] == '\t' || L->Chars[C+1] == ' ')) C++; } if (DelText(Y, ScreenPos(L, C), 1) == 0) return 0; } } else if (LineJoin() == 0) return 0; if (BFI(this, BFI_WordWrap) == 2) { if (DoWrap(0) == 0) return 0; if (CP.Col >= LineLen(Y)) if (CP.Row < VCount - 1) { if (SetPos(BFI(this, BFI_LeftMargin), CP.Row + 1) == 0) return 0; } } if (BFI(this, BFI_Trim)) if (TrimLine(VToR(CP.Row)) == 0) return 0; return 1; }
int EBuffer::InsPrevLineChar() { int L = VToR(CP.Row); int C = CP.Col, P; if (L > 0) { L--; if (C < LineLen(L)) { P = CharOffset(RLine(L), C); return InsertChar(RLine(L)->Chars[P]); } } return 0; }
int EBuffer::BlockSelectLine() { int Y = VToR(CP.Row); if (BlockUnmark() == 0) return 0; BlockMode = bmStream; if (SetBB(EPoint(Y, 0)) == 0) return 0; if (Y == RCount - 1) { if (SetBE(EPoint(Y, LineLen(Y))) == 0) return 0; } else { if (SetBE(EPoint(Y + 1, 0)) == 0) return 0; } return 1; }
int EBuffer::KillCharPrev() { if (CP.Col == 0) { if (CP.Row > 0) if (ExposeRow(VToR(CP.Row) - 1) == 0) return 0; if (!MoveUp()) return 0; if (!MoveLineEnd()) return 0; if (LineJoin()) return 1; } else { if (!MovePrev()) return 0; if (DelText(CP.Row, CP.Col, 1)) return 1; } return 0; }
int EBuffer::InsPrevLineToEol() { int L = VToR(CP.Row); int C = CP.Col, P; int Len; if (L > 0) { L--; P = CharOffset(RLine(L), C); Len = RLine(L)->Count - P; if (Len > 0) return InsertString(RLine(L)->Chars + P, Len); } return 0; }
int EBuffer::LineIndent() { int rc = 1; if (BFI(this, BFI_AutoIndent)) { int L = VToR(CP.Row); switch (BFI(this, BFI_IndentMode)) { case INDENT_C: rc = Indent_C(this, L, 1); break; case INDENT_REXX: rc = Indent_REXX(this, L, 1); break; case INDENT_SIMPLE: rc = Indent_SIMPLE(this, L, 1); break; case INDENT_CONTINUE: rc = Indent_Continue(this, L, 1); break; default: rc = Indent_Plain(this, L, 1); break; } } if (rc == 0) return 0; if (BFI(this, BFI_Trim)) if (TrimLine(VToR(CP.Row)) == 0) return 0; return 1; }
int EBuffer::FoldToggleOpenClose() { /*FOLD00*/ int Line = VToR(CP.Row); int f; f = FindNearFold(Line); if (f == -1) return 0; if (FF[f].open) { if (FoldClose(Line) == 0) return 0; } else { if (FoldOpen(Line) == 0) return 0; } return 1; }
int EBuffer::KillWord() { int Y = VToR(CP.Row); if (CP.Col >= LineLen()) { if (KillChar() == 0) return 0; } else { PELine L = RLine(Y); int P = CharOffset(L, CP.Col); int C; int Class = ChClassK(L->Chars[P]); while ((P < L->Count) && (ChClassK(L->Chars[P]) == Class)) P++; C = ScreenPos(L, P); if (DelText(Y, CP.Col, C - CP.Col) == 0) return 0; } return 1; }
int EBuffer::MoveFoldNext() { /*FOLD00*/ int f = FindNearFold(VToR(CP.Row)); if ((f == FCount - 1) || (f == -1)) return 0; do { f++; if (f == FCount) return 0; if (RToV(FF[f].line) != -1) break; } while (1); if (SetPosR(CP.Col, FF[f].line, tmLeft) == 0) return 0; return 1; }
int EBuffer::BlockExtendEnd() { EPoint T, B, E; CheckBlock(); B = BB; E = BE; switch (BlockMode) { case bmLine: if (ExtendGrab & 1) { B.Row = VToR(CP.Row); B.Col = 0; } else if (ExtendGrab & 2) { E.Row = VToR(CP.Row); E.Col = 0; } if (B.Row > E.Row) { T = B; B = E; E = T; } break; case bmStream: if (ExtendGrab & 1) { B.Col = CP.Col; B.Row = VToR(CP.Row); } else if (ExtendGrab & 2) { E.Col = CP.Col; E.Row = VToR(CP.Row); } if ((B.Row > E.Row) || ((B.Row == E.Row) && (B.Col > E.Col))) { T = B; B = E; E = T; } break; case bmColumn: if (ExtendGrab & 1) B.Row = VToR(CP.Row); else if (ExtendGrab & 2) E.Row = VToR(CP.Row); if (ExtendGrab & 4) B.Col = CP.Col; else if (ExtendGrab & 8) E.Col = CP.Col; if (B.Row > E.Row) { int T; T = B.Row; B.Row = E.Row; E.Row = T; } if (B.Col > E.Col) { int T; T = B.Col; B.Col = E.Col; E.Col = T; } break; } SetBB(B); SetBE(E); ExtendGrab = 0; AutoExtend = 0; return 1; }
int EBuffer::KillWordPrev() { int Y = VToR(CP.Row); if (CP.Col == 0) { if (KillCharPrev() == 0) return 0; } else if (CP.Col > LineLen()) { if (SetPos(LineLen(), CP.Row) == 0) return 0; } else { PELine L = RLine(Y); int P = CharOffset(L, CP.Col); int C; int Class = ChClassK(L->Chars[P - 1]); while ((P > 0) && (ChClassK(L->Chars[P - 1]) == Class)) P--; C = ScreenPos(L, P); if (DelText(Y, C, CP.Col - C) == 0) return 0; if (SetPos(C, CP.Row) == 0) return 0; } return 1; }
int EBuffer::KillWordOrCap() { int Y = VToR(CP.Row); if (CP.Col >= LineLen()) { if (KillChar() == 0) return 0; } else { PELine L = VLine(CP.Row); int P = CharOffset(L, CP.Col); int C; int Class = ChClassK(L->Chars[P]); if (Class == 1) { if (WGETBIT(Flags.CapitalChars, L->Chars[P]) == 1) while ((P < L->Count) && (WGETBIT(Flags.CapitalChars, L->Chars[P]) == 1)) P++; while ((P < L->Count) && (WGETBIT(Flags.WordChars, L->Chars[P]) == 1) && (WGETBIT(Flags.CapitalChars, L->Chars[P]) == 0)) P++; } else while ((P < L->Count) && (ChClassK(L->Chars[P]) == Class)) P++; C = ScreenPos(L, P); if (DelText(Y, CP.Col, C - CP.Col) == 0) return 0; } return 1; }
int EBuffer::BlockSelectWord() { int Y = VToR(CP.Row); PELine L = RLine(Y); int P; int C; if (BlockUnmark() == 0) return 0; BlockMode = bmStream; P = CharOffset(L, CP.Col); if (P >= L->Count) return 0; C = ChClassK(L->Chars[P]); while ((P > 0) && (C == ChClassK(L->Chars[P - 1]))) P--; if (SetBB(EPoint(Y, ScreenPos(L, P))) == 0) return 0; while ((P < L->Count) && (C == ChClassK(L->Chars[P]))) P++; if (SetBE(EPoint(Y, ScreenPos(L, P))) == 0) return 0; return 1; }
int EBuffer::FoldOpenNested() { /*FOLD00*/ int Line = VToR(CP.Row); int f = FindFold(Line); int l; int level; if (f == -1) return 0; level = FF[f].level; while (f + 1 < FCount && FF[f + 1].level > level) f++; if (f + 1 == FCount) { if (FoldOpen(Line) == 0) return 0; } else { for (l = Line; l < RCount && l < FF[f + 1].line; l++) { if (FindFold(l) != -1) if (FoldOpen(l) == 0) return 0; } } return 0; }
int EBuffer::CLine() { assert(1 == 0); return VToR(CP.Row); }
int EBuffer::LineLen() { return LineLen(VToR(CP.Row)); }
int EBuffer::LineJoin() { if (JoinLine(VToR(CP.Row), CP.Col)) return 1; return 0; }
int EBuffer::LineSplit() { if (SplitLine(VToR(CP.Row), CP.Col) == 0) return 0; if (BFI(this, BFI_Trim)) if (TrimLine(VToR(CP.Row)) == 0) return 0; return 1; }