예제 #1
0
파일: e_cmds.cpp 프로젝트: dmcbride/efte
int EBuffer::InsertString(const char *aStr, int aCount) {
    int P;
    int C, L;
    int Y = VToR(CP.Row);

    if (BFI(this, BFI_InsertKillBlock) == 1)
        if (CheckBlock() == 1)
            if (BlockKill() == 0)
                return 0;

    if (BFI(this, BFI_Insert) == 0)
        if (CP.Col < LineLen())
            if (KillChar() == 0)
                return 0;
    if (InsText(Y, CP.Col, aCount, aStr) == 0)
        return 0;
    C = CP.Col;
    L = VToR(CP.Row);
    P = CharOffset(RLine(L), C);
    P += aCount;
    C = ScreenPos(RLine(L), P);
    if (SetPos(C, CP.Row) == 0)
        return 0;
    if (BFI(this, BFI_Trim) && *aStr != '\t')
        if (TrimLine(L) == 0)
            return 0;
    if (BFI(this, BFI_WordWrap) == 2) {
        if (DoWrap(0) == 0) return 0;
    } else if (BFI(this, BFI_WordWrap) == 1) {
        int P, C = CP.Col;
        PELine LP;
        int L;

        if (C > BFI(this, BFI_RightMargin)) {
            L = CP.Row;

            C = BFI(this, BFI_RightMargin);
            P = CharOffset(LP = RLine(L), C);
            while ((C > BFI(this, BFI_LeftMargin)) &&
                    ((LP->Chars[P] != ' ') &&
                     (LP->Chars[P] != 9)))
                C = ScreenPos(LP, --P);

            if (P <= BFI(this, BFI_LeftMargin)) {
                C = BFI(this, BFI_RightMargin);
            } else
                C = ScreenPos(LP, P);
            if (SplitLine(L, C) == 0) return 0;
            IndentLine(L + 1, BFI(this, BFI_LeftMargin));
            if (SetPos(CP.Col - C - 1 + BFI(this, BFI_LeftMargin), CP.Row + 1) == 0) return 0;
        }
    }
    return 1;
}
예제 #2
0
int EBuffer::FindTagWord(ExState &State) {
    char word[MAXSEARCH + 1];
    PELine L = VLine(CP.Row);
    int P, len = 0;

    P = CharOffset(L, CP.Col);
    while ((P > 0) && ((ChClass(L->Chars[P - 1]) == 1) || (L->Chars[P - 1] == '_')))
        P--;
    while (len < int(sizeof(word)) && P < L->Count && (ChClass(L->Chars[P]) == 1 || L->Chars[P] == '_'))
        word[len++] = L->Chars[P++];
    word[len] = 0;
    if (len == 0) {
        Msg(S_INFO, "No word at cursor.");
        return 0;
    }

    int j = 2;
    while (j--) {
        int i;

        i = TagFind(this, View, word);
        if (i > 0)
            return 1;
        else if (j && (i < 0)) {
            /* Try autoload tags */
            if (View->ExecCommand(ExTagLoad, State) == 0)
                break;
        } else {
            Msg(S_INFO, "Tag '%s' not found.", word);
            break;
        }
    }
    return 0;
}
예제 #3
0
파일: e_cmds.cpp 프로젝트: dmcbride/efte
int EBuffer::MoveTabStart() {
    PELine X = VLine(CP.Row);
    int C = CharOffset(X, CP.Col);

    if (C < X->Count)
        if (X->Chars[C] == 9)
            return SetPos(ScreenPos(X, C), CP.Row);
    return 1;
}
예제 #4
0
파일: e_cmds.cpp 프로젝트: dmcbride/efte
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);
}
예제 #5
0
파일: e_cmds.cpp 프로젝트: dmcbride/efte
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;
}
예제 #6
0
파일: e_cmds.cpp 프로젝트: dmcbride/efte
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;
}
예제 #7
0
파일: e_cmds.cpp 프로젝트: dmcbride/efte
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;
}
예제 #8
0
파일: e_cmds.cpp 프로젝트: dmcbride/efte
int EBuffer::MoveWordRightX(int start) {
    PELine L = VLine(CP.Row);
    int C, P;
    int wS = start, wE = 1 - start;

    C = CP.Col;
    P = CharOffset(L, C);

    if (P >= L->Count) return 0;

    while ((P < L->Count) && (WGETBIT(Flags.WordChars, L->Chars[P]) == wS)) P++;
    while ((P < L->Count) && (WGETBIT(Flags.WordChars, L->Chars[P]) == wE)) P++;
    C = ScreenPos(L, P);
    return SetPos(C, CP.Row);
}
예제 #9
0
파일: e_cmds.cpp 프로젝트: dmcbride/efte
int EBuffer::MoveWordOrCapEndRight() {
    PELine L = VLine(CP.Row);
    int C, P;

    C = CP.Col;
    P = CharOffset(L, C);

    if (P >= L->Count) return 0;

    while ((P < L->Count) && (WGETBIT(Flags.WordChars, L->Chars[P]) == 0)) P++;
    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++;
    C = ScreenPos(L, P);
    return SetPos(C, CP.Row);
}
예제 #10
0
파일: c_hilit.cpp 프로젝트: dmcbride/efte
int EBuffer::HilitWord() {
    PELine L = VLine(CP.Row);
    char s[CK_MAXLEN + 2];
    int P, len = 0;

    P = CharOffset(L, CP.Col);
    while ((P > 0) && ((ChClass(L->Chars[P - 1]) == 1) || (L->Chars[P - 1] == '_')))
        P--;
    while (len < CK_MAXLEN && P < L->Count && (ChClass(L->Chars[P]) == 1 || L->Chars[P] == '_'))
        s[len++] = L->Chars[P++];
    if (len == 0)
        return 0;
    s[len] = 0;

    return (HilitFindWord(s)) ? HilitRemoveWord(s) : HilitAddWord(s);
}
예제 #11
0
파일: e_cmds.cpp 프로젝트: dmcbride/efte
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;
}
예제 #12
0
int EBuffer::SearchWord(int SearchFlags) {
    char word[MAXSEARCH + 1];
    PELine L = VLine(CP.Row);
    int P, len = 0;
    int Case = BFI(this, BFI_MatchCase) ? 0 : SEARCH_NCASE;

    P = CharOffset(L, CP.Col);
    while ((P > 0) && ((ChClass(L->Chars[P - 1]) == 1) || (L->Chars[P - 1] == '_')))
        P--;
    while (len < int(sizeof(word)) && P < L->Count && (ChClass(L->Chars[P]) == 1 || L->Chars[P] == '_'))
        word[len++] = L->Chars[P++];
    word[len] = 0;
    if (len == 0)
        return 0;

    return FindStr(word, len, Case | SearchFlags | SEARCH_WORD);
}
예제 #13
0
파일: e_cmds.cpp 프로젝트: dmcbride/efte
int EBuffer::MoveWordLeftX(int start) {
    if (CP.Col > 0) {
        int wS = start, wE = 1 - start;
        PELine L = VLine(CP.Row);
        int C, P;

        C = CP.Col;
        P = CharOffset(L, C);

        if (P > L->Count) P = L->Count;
        if (P > 0) {
            while ((P > 0) && (WGETBIT(Flags.WordChars, L->Chars[P - 1]) == wE)) P--;
            while ((P > 0) && (WGETBIT(Flags.WordChars, L->Chars[P - 1]) == wS)) P--;
            C = ScreenPos(L, P);
            return SetPos(C, CP.Row);
        } else return 0;
    } else return 0;
}
예제 #14
0
파일: e_cmds.cpp 프로젝트: dmcbride/efte
int EBuffer::MoveWordOrCapEndLeft() {
    if (CP.Col > 0) {
        PELine L = VLine(CP.Row);
        int C, P;

        C = CP.Col;
        P = CharOffset(L, C);

        if (P > L->Count) P = L->Count;
        if (P > 0) {
            while ((P > 0) && (WGETBIT(Flags.WordChars, L->Chars[P - 1]) == 1) && (WGETBIT(Flags.CapitalChars, L->Chars[P - 1]) == 0)) P--;
            while ((P > 0) && (WGETBIT(Flags.CapitalChars, L->Chars[P - 1]) == 1)) P--;
            while ((P > 0) && (WGETBIT(Flags.WordChars, L->Chars[P - 1]) == 0)) P--;
            C = ScreenPos(L, P);
            return SetPos(C, CP.Row);
        } else return 0;
    } else return 0;
}
예제 #15
0
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;
}
예제 #16
0
파일: e_cmds.cpp 프로젝트: dmcbride/efte
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;
}
예제 #17
0
파일: e_cmds.cpp 프로젝트: dmcbride/efte
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;
}
예제 #18
0
파일: e_cmds.cpp 프로젝트: dmcbride/efte
int EBuffer::BackSpace() {
    int Y = VToR(CP.Row);

    if (CheckBlock() == 1 && BFI(this, BFI_BackSpKillBlock)) {
        if (BlockKill() == 0)
            return 0;
    } else if (BFI(this, BFI_WordWrap) == 2 && CP.Row > 0 && !IsLineBlank(Y - 1) &&
               CP.Col <= BFI(this, BFI_LeftMargin) && CP.Col <= LineIndented(Y)) {
        if (SetPos(LineLen(Y - 1), CP.Row - 1) == 0) return 0;
    } else if (CP.Col == 0) {
        if (CP.Row > 0)
            if (ExposeRow(VToR(CP.Row) - 1) == 0) return 0;
        if (MoveUp() == 0) return 0;
        if (MoveLineEnd() == 0) return 0;
        if (LineJoin() == 0) return 0;
    } else {
        if (BFI(this, BFI_BackSpUnindents) && (LineIndented(Y) == CP.Col)) {
            int C = CP.Col, C1 = 0;
            int L = VToR(CP.Row);

            C1 = C;
            while (L > 0 && (IsLineBlank(L - 1) || (C1 = LineIndented(L - 1)) >= C)) L--;
            if (L == 0) C1 = 0;
            if (C1 == C) C1--;
            if (C1 < 0) C1 = 0;
            if (C1 > C) C1 = C;
            if (SetPos(C1, CP.Row) == 0) return 0;
            if (C > LineIndented(Y)) return 0;
            if (DelText(Y, C1, C - C1) == 0) return 0;
            if (BFI(this, BFI_Insert) == 0)
                if (InsText(Y, C1, 1, " ") == 0) return 0;
        } else if (BFI(this, BFI_BackSpKillTab)) {
            int P;
            int C = CP.Col, C1;

            P = CharOffset(RLine(Y), C - 1);
            C1 = ScreenPos(RLine(Y), P);
            if (SetPos(C1, CP.Row) == 0) return 0;
            if (DelText(Y, C1, C - C1) == 0) return 0;
            if (BFI(this, BFI_Insert) == 0)
                if (InsText(Y, C1, 1, " ") == 0) return 0;
        } else {
            if (MovePrev() == 0) return 0;

            ELine *L = RLine(Y);
            int C = CharOffset(L, CP.Col);

            if (L->Count > 0 && L->Chars[C] == 9) {
                /* 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] == 9 || L->Chars[C+1] == ' ')) C++;
            }

            if (DelText(Y, ScreenPos(L, C), 1) == 0) return 0;
            if (BFI(this, BFI_Insert) == 0)
                if (InsText(Y, ScreenPos(L, C), 1, " ") == 0) return 0;
        }
    }
    if (BFI(this, BFI_WordWrap) == 2) {
        if (DoWrap(0) == 0) return 0;
    }
    if (BFI(this, BFI_Trim)) {
        Y = VToR(CP.Row);
        if (TrimLine(Y) == 0) return 0;
    }
    return 1;
}
예제 #19
0
int EBuffer::BlockWriteTo(const char *AFileName, int Append) {
    //int error = 0;
    EPoint B, E;
    int L;
    PELine LL;
    int A, Z;
    FILE *fp;
    int bc = 0, lc = 0, oldc = 0;

    AutoExtend = 0;
    if (CheckBlock() == 0) return 0;
    if (RCount == 0) return 0;
    B = BB;
    E = BE;
    Msg(S_INFO, "Writing %s...", AFileName);
    fp = fopen(AFileName, Append ? "ab" : "wb");
    if (fp == NULL) goto error;
    setvbuf(fp, FileBuffer, _IOFBF, sizeof(FileBuffer));
    for (L = B.Row; L <= E.Row; L++) {
        A = -1;
        Z = -1;
        LL = RLine(L);
        switch (BlockMode) {
        case bmLine:
            if (L < E.Row) {
                A = 0;
                Z = LL->Count;
            }
            break;
        case bmColumn:
            if (L < E.Row) {
                A = CharOffset(LL, B.Col);
                Z = CharOffset(LL, E.Col);
            }
            break;
        case bmStream:
            if (B.Row == E.Row) {
                A = CharOffset(LL, B.Col);
                Z = CharOffset(LL, E.Col);
            } else if (L == B.Row) {
                A = CharOffset(LL, B.Col);
                Z = LL->Count;
            } else if (L < E.Row) {
                A = 0;
                Z  = LL->Count;
            } else if (L == E.Row) {
                A = 0;
                Z = CharOffset(LL, E.Col);
            }
            break;
        }
        if (A != -1 && Z != -1) {
            if (A < LL->Count) {
                if (Z > LL->Count)
                    Z = LL->Count;
                if (Z > A) {
                    if ((int)fwrite(LL->Chars + A, 1, Z - A, fp) != Z - A) {
                        goto error;
                    } else
                        bc += Z - A;
                }
            }
            if (BFI(this, BFI_AddCR) == 1)
                if (fputc(13, fp) < 0) goto error;
                else
                    bc++;
            if (BFI(this, BFI_AddLF) == 1)
                if (fputc(10, fp) < 0)
                    goto error;
                else {
                    bc++;
                    lc++;
                }
            if (bc > 65536 + oldc) {
                Msg(S_INFO, "Writing %s, %d lines, %d bytes.", AFileName, lc, bc);
                oldc = bc;
            }
        }
    }
    fclose(fp);
    Msg(S_INFO, "Wrote %s, %d lines, %d bytes.", AFileName, lc, bc);
    return 1;
error:
    if(fp != NULL)
    {
        fclose(fp);
        unlink(AFileName);
    }
    View->MView->Win->Choice(GPC_ERROR, "Error", 1, "O&K", "Failed to write block to %s", AFileName);
    return 0;
}
예제 #20
0
int EBuffer::FindStr(const char *Data, int Len, SearchReplaceOptions &opt) {
    int Options = opt.Options;
    int LLen, Start, End;
    int C, L;
    PELine X;
    char *P;

    if (Options & SEARCH_RE)
        return 0;
    if (Len <= 0)
        return 0;

    if (Options & SEARCH_NOPOS) {
        C = Match.Col;
        L = Match.Row;
    } else {
        C = CP.Col;
        L = VToR(CP.Row);
    }
    if (Match.Row != -1)
        Draw(Match.Row, Match.Row);
    Match.Row = -1;
    Match.Col = -1;
    X = RLine(L);
    C = CharOffset(X, C);

    if (Options & SEARCH_NEXT) {
        int CC = MatchCount ? 1 : 0;

        if (Options & SEARCH_BACK) {
            C -= CC;
            if (C < 0) {
                if (L == 0) return 0;
                L--;
                X = RLine(L);
                C = X->Count;
            }
        } else {
            if (Options & SEARCH_REPLACE &&
                    opt.lastInsertLen > 0) {
                C += CC * opt.lastInsertLen; // 0 or opt.lastInsertLen
            } else {
                C += CC;
            }

            if (C >= X->Count) {
                C = 0;
                L++;
                if (L == RCount) return 0;
            }
        }
    }
    MatchLen = 0;
    MatchCount = 0;

    if (Options & SEARCH_BLOCK) {
        if (Options & SEARCH_BACK) {
            if (BlockMode == bmStream) {
                if (L > BE.Row) {
                    L = BE.Row;
                    C = BE.Col;
                }
                if (L == BE.Row && C > BE.Col)
                    C = BE.Col;
            } else {
                if (L >= BE.Row && BE.Row > 0) {
                    L = BE.Row - 1;
                    C = RLine(L)->Count;
                }
                if (BlockMode == bmColumn)
                    if (L == BE.Row - 1 && C >= BE.Col)
                        C = BE.Col;
            }
        } else {
            if (L < BB.Row) {
                L = BB.Row;
                C = 0;
            }
            if (L == BB.Row && C < BB.Col)
                C = BB.Col;
        }
    }
    while (1) {
        if (Options & SEARCH_BLOCK) {
            if (BlockMode == bmStream) {
                if (L > BE.Row || L < BB.Row) break;
            } else
                if (L >= BE.Row || L < BB.Row) break;
        } else
            if (L >= RCount || L < 0) break;

        X = RLine(L);

        LLen = X->Count;
        P = X->Chars;
        Start = 0;
        End = LLen;

        if (Options & SEARCH_BLOCK) {
            if (BlockMode == bmColumn) {
                Start = CharOffset(X, BB.Col);
                End = CharOffset(X, BE.Col);
            } else if (BlockMode == bmStream) {
                if (L == BB.Row)
                    Start = CharOffset(X, BB.Col);
                if (L == BE.Row)
                    End = CharOffset(X, BE.Col);
            }
        }
        if (Options & SEARCH_BACK) {
            if (C >= End - Len)
                C = End - Len;
        } else {
            if (C < Start)
                C = Start;
        }

        while (((!(Options & SEARCH_BACK)) && (C <= End - Len)) || ((Options & SEARCH_BACK) && (C >= Start))) {
            if ((!(Options & SEARCH_WORDBEG)
                    || (C == 0)
                    || (WGETBIT(Flags.WordChars, P[C - 1]) == 0))
                    &&
                    (!(Options & SEARCH_WORDEND)
                     || (C + Len >= End)
                     || (WGETBIT(Flags.WordChars, P[C + Len]) == 0))
                    &&
                    ((!(Options & SEARCH_NCASE)
                      && (P[C] == Data[0])
                      && (memcmp(P + C, Data, Len) == 0))
                     ||
                     ((Options & SEARCH_NCASE)
                      && (toupper(P[C]) == toupper(Data[0]))
                      && (strnicmp(P + C, Data, Len) == 0))) /* && BOL | EOL */
               ) {
                Match.Col = ScreenPos(X, C);
                Match.Row = L;
                MatchCount = Len;
                MatchLen = ScreenPos(X, C + Len) - Match.Col;
                if (!(Options & SEARCH_NOPOS)) {
                    if (Options & SEARCH_CENTER)
                        CenterPosR(Match.Col, Match.Row);
                    else
                        SetPosR(Match.Col, Match.Row);
                }
                Draw(L, L);
                return 1;
            }
            if (Options & SEARCH_BACK) C--;
            else C++;
        }
        if (Options & SEARCH_BACK) {
            L--;
            if (L >= 0)
                C = RLine(L)->Count;
        } else {
            C = 0;
            L++;
        }
    }
    //SetPos(OC, OL);
    return 0;
}
예제 #21
0
int EBuffer::Find(SearchReplaceOptions &opt) {
    int slen = strlen(opt.strSearch);
    int Options = opt.Options;
    int rlen = strlen(opt.strReplace);
    RxNode *R = NULL;

    opt.resCount = -1;
    opt.lastInsertLen = 0;

    if (slen == 0) return 0;
    if (Options & SEARCH_BLOCK) {
        if (CheckBlock() == 0) return 0;
    }
    if (Options & SEARCH_RE) {
        R = RxCompile(opt.strSearch);
        if (R == 0) {
            View->MView->Win->Choice(GPC_ERROR, "Find", 1, "O&K", "Invalid regular expression.");
            return 0;
        }
    }
    if (Options & SEARCH_GLOBAL) {
        if (Options & SEARCH_BLOCK) {
            if (Options & SEARCH_BACK) {
                if (SetPosR(BE.Col, BE.Row) == 0) goto error;
            } else {
                if (SetPosR(BB.Col, BB.Row) == 0) goto error;
            }
        } else {
            if (Options & SEARCH_BACK) {
                if (RCount < 1) goto error;
                if (SetPosR(LineLen(RCount - 1), RCount - 1) == 0) goto error;
            } else {
                if (SetPosR(0, 0) == 0) goto error;
            }
        }
    }
    opt.resCount = 0;
    while (1) {
        if (Options & SEARCH_RE) {
            if (FindRx(R, opt) == 0) goto end;
        } else {
            if (FindStr(opt.strSearch, slen, opt) == 0) goto end;
        }
        opt.resCount++;

        if (opt.Options & SEARCH_REPLACE) {
            char ask = 'A';

            if (!(Options & SEARCH_NASK)) {
                char ch;

                while (1) {
                    Draw(VToR(CP.Row), 1);
                    Redraw();
                    switch (View->MView->Win->Choice(0, "Replace",
                                                     5,
                                                     "&Yes",
                                                     "&All",
                                                     "&Once",
                                                     "&Skip",
                                                     "&Cancel",
                                                     "Replace with %s?", opt.strReplace)) {
                    case 0:
                        ch = 'Y';
                        break;
                    case 1:
                        ch = 'A';
                        break;
                    case 2:
                        ch = 'O';
                        break;
                    case 3:
                        ch = 'N';
                        break;
                    case 4:
                    case -1:
                    default:
                        ch = 'Q';
                        break;
                    }
                    if (ch == 'Y') {
                        ask = 'Y';
                        goto ok_rep;
                    }
                    if (ch == 'N') {
                        ask = 'N';
                        goto ok_rep;
                    }
                    if (ch == 'Q') {
                        ask = 'Q';
                        goto ok_rep;
                    }
                    if (ch == 'A') {
                        ask = 'A';
                        goto ok_rep;
                    }
                    if (ch == 'O') {
                        ask = 'O';
                        goto ok_rep;
                    }
                }
ok_rep:
                if (ask == 'N') goto try_join;
                if (ask == 'Q') goto end;
                if (ask == 'A') Options |= SEARCH_NASK;
            }

            if (Options & SEARCH_RE) {
                PELine L = RLine(Match.Row);
                int P, R;
                char *PR = 0;
                int LR = 0;

                R = Match.Row;
                P = Match.Col;
                P = CharOffset(L, P);

                if (0 == RxReplace(opt.strReplace, L->Chars, L->Count, MatchRes, &PR, &LR)) {
                    if (DelText(R, Match.Col, MatchLen) == 0) goto error;
                    if (PR && LR > 0)
                        if (InsText(R, Match.Col, LR, PR) == 0) goto error;
                    if (PR)
                        free(PR);
                    rlen = LR;
                }
            } else {
                if (DelText(Match.Row, Match.Col, MatchLen) == 0) goto error;
                if (InsText(Match.Row, Match.Col, rlen, opt.strReplace) == 0) goto error;

                // Cursor remains at start of inserted string. If there is recursive
                // replace pattern, fte can go it infinite loop.
                // Workaround: Move cursor to end of inserted string
                opt.lastInsertLen = strlen(opt.strReplace);
            }
            if (!(Options & SEARCH_BACK)) {
                MatchLen = rlen;
                MatchCount = rlen;
            }
            if (ask == 'O')
                goto end;
        }

try_join:
        if (Options & SEARCH_JOIN) {
            char ask = 'A';

            if (!(Options & SEARCH_NASK)) {
                char ch;

                while (1) {
                    Draw(VToR(CP.Row), 1);
                    Redraw();
                    switch (View->MView->Win->Choice(0, "Join Line",
                                                     5,
                                                     "&Yes",
                                                     "&All",
                                                     "&Once",
                                                     "&Skip",
                                                     "&Cancel",
                                                     "Join lines %d and %d?", 1 + VToR(CP.Row), 1 + VToR(CP.Row) + 1)) {
                    case 0:
                        ch = 'Y';
                        break;
                    case 1:
                        ch = 'A';
                        break;
                    case 2:
                        ch = 'O';
                        break;
                    case 3:
                        ch = 'N';
                        break;
                    case 4:
                    case -1:
                    default:
                        ch = 'Q';
                        break;
                    }
                    if (ch == 'Y') {
                        ask = 'Y';
                        goto ok_join;
                    }
                    if (ch == 'N') {
                        ask = 'N';
                        goto ok_join;
                    }
                    if (ch == 'Q') {
                        ask = 'Q';
                        goto ok_join;
                    }
                    if (ch == 'A') {
                        ask = 'A';
                        goto ok_join;
                    }
                    if (ch == 'O') {
                        ask = 'O';
                        goto ok_join;
                    }
                }
ok_join:
                if (ask == 'N') goto try_split;
                if (ask == 'Q') goto end;
                if (ask == 'A') Options |= SEARCH_NASK;
            }

            if (JoinLine(Match.Row, Match.Col) == 0) goto error;

            if (ask == 'O')
                goto end;
        }

try_split:
            if (Options & SEARCH_SPLIT) {
                char ask = 'A';

                if (!(Options & SEARCH_NASK)) {
                    char ch;

                    while (1) {
                        Draw(VToR(CP.Row), 1);
                        Redraw();
                        switch(View->MView->Win->Choice(0, "Split Line",
                                                        5,
                                                        "&Yes",
                                                        "&All",
                                                        "&Once",
                                                        "&Skip",
                                                        "&Cancel",
                                                        "Split line %d?", VToR(CP.Row)))
                        {
                        case 0:
                            ch = 'Y';
                            break;

                        case 1:
                            ch = 'A';
                            break;

                        case 2:
                            ch = 'O';
                            break;

                        case 3:
                            ch = 'S';
                            break;

                        case 4:
                        case -1:
                        default:
                            ch = 'Q';
                            break;
                        }

                        if (ch == 'Y') {
                            ask = 'Y';
                            goto ok_split;
                        }
                        else if (ch == 'N') {
                            ask = 'N';
                            goto ok_split;
                        }
                        else if (ch == 'Q') {
                            ask = 'Q';
                            goto ok_split;
                        }
                        else if (ch == 'A') {
                            ask = 'A';
                            goto ok_split;
                        }
                        else if (ch == 'O') {
                            ask = 'O';
                            goto ok_split;
                        }
                    }
ok_split:
                    if (ask == 'N') goto try_delete;
                    if (ask == 'Q') goto end;
                    if (ask == 'A') Options |= SEARCH_NASK;
                }

                if (SplitLine(Match.Row, Match.Col + strlen(opt.strReplace)) == 0)
                    goto error;

                if (ask == 'O')
                    goto end;
            }

try_delete:
            if (Options & SEARCH_DELETE) {
                char ask = 'A';

            if (!(Options & SEARCH_NASK)) {
                char ch;

                while (1) {
                    Draw(VToR(CP.Row), 1);
                    Redraw();
                    switch (View->MView->Win->Choice(0, "Delete Line",
                                                     5,
                                                     "&Yes",
                                                     "&All",
                                                     "&Once",
                                                     "&Skip",
                                                     "&Cancel",
                                                     "Delete line %d?", VToR(CP.Row))) {
                    case 0:
                        ch = 'Y';
                        break;
                    case 1:
                        ch = 'A';
                        break;
                    case 2:
                        ch = 'O';
                        break;
                    case 3:
                        ch = 'N';
                        break;
                    case 4:
                    case -1:
                    default:
                        ch = 'Q';
                        break;
                    }
                    if (ch == 'Y') {
                        ask = 'Y';
                        goto ok_delete;
                    }
                    if (ch == 'N') {
                        ask = 'N';
                        goto ok_delete;
                    }
                    if (ch == 'Q') {
                        ask = 'Q';
                        goto ok_delete;
                    }
                    if (ch == 'A') {
                        ask = 'A';
                        goto ok_delete;
                    }
                    if (ch == 'O') {
                        ask = 'O';
                        goto ok_delete;
                    }
                }
ok_delete:
                if (ask == 'N') goto next;
                if (ask == 'Q') goto end;
                if (ask == 'A') Options |= SEARCH_NASK;
            }

            if (Match.Row == RCount - 1) {
                if (DelText(Match.Row, 0, LineLen()) == 0) goto error;
            } else
                if (DelLine(Match.Row) == 0) goto error;

            if (ask == 'O')
                goto end;
            if (!(Options & SEARCH_ALL))
                break;
            goto last;
        }
next:
        if (!(Options & SEARCH_ALL))
            break;
        Options |= SEARCH_NEXT;
last:
        ;
    }
end:
    // end of search
    if (R)
        RxFree(R);

    if (Options & SEARCH_ALL)
        Msg(S_INFO, "%d match(es) found.", opt.resCount);
    else {
        if (opt.resCount == 0) {
            Msg(S_INFO, "[%s] not found", opt.strSearch);
            return 0;
        }
    }
    return 1;
error:

    if (R) {
        RxFree(R);
    }
    View->MView->Win->Choice(GPC_ERROR, "Find", 1, "O&K", "Error in search/replace.");
    return 0;
}
예제 #22
0
int EBuffer::GetMatchBrace(EPoint &M, int MinLine, int MaxLine, int show) {
    int StateLen;
    hsState *StateMap = 0;
    int Pos;
    PELine L = VLine(M.Row);
    int dir = 0;
    hsState State;
    char Ch1, Ch2;
    int CountX = 0;
    int StateRow = -1;

    M.Row = VToR(CP.Row);

    Pos = CharOffset(L, M.Col);
    if (Pos >= L->Count) return 0;
    switch (L->Chars[Pos]) {
    case '{':
        dir = + 1;
        Ch1 = '{';
        Ch2 = '}';
        break;
    case '[':
        dir = + 1;
        Ch1 = '[';
        Ch2 = ']';
        break;
    case '<':
        dir = + 1;
        Ch1 = '<';
        Ch2 = '>';
        break;
    case '(':
        dir = + 1;
        Ch1 = '(';
        Ch2 = ')';
        break;
    case '}':
        dir = -1;
        Ch1 = '}';
        Ch2 = '{';
        break;
    case ']':
        dir = -1;
        Ch1 = ']';
        Ch2 = '[';
        break;
    case '>':
        dir = -1;
        Ch1 = '>';
        Ch2 = '<';
        break;
    case ')':
        dir = -1;
        Ch1 = ')';
        Ch2 = '(';
        break;
    default:
        return 0;
    }
    StateMap = 0;
    if (GetMap(M.Row, &StateLen, &StateMap) == 0) return 0;
    State = StateMap[Pos];
    StateRow = M.Row;

    while (M.Row >= MinLine && M.Row < MaxLine) {
        while (Pos >= 0 && Pos < L->Count) {
            if (L->Chars[Pos] == Ch1 || L->Chars[Pos] == Ch2) {
                // update syntax state if needed
                if (StateRow != M.Row) {
                    free(StateMap);
                    StateMap = 0;
                    GetMap(M.Row, &StateLen, &StateMap);
                    if (StateMap == 0) return 0;
                    StateRow = M.Row;
                }
                if (StateMap[Pos] == State) {
                    if (L->Chars[Pos] == Ch1) CountX++;
                    if (L->Chars[Pos] == Ch2) CountX--;
                    if (CountX == 0) {
                        M.Col = ScreenPos(L, Pos);
                        free(StateMap);
                        return 1;
                    }
                }
            }
            Pos += dir;
        }
        M.Row += dir;
        if (M.Row >= 0 && M.Row < RCount) {
            L = RLine(M.Row);
            Pos = (dir == 1) ? 0 : (L->Count - 1);
        }
    }
    if (StateMap) free(StateMap);
    if (show)
        Msg(S_INFO, "No match (%d missing).", CountX);
    return 0;
}
예제 #23
0
파일: e_cmds.cpp 프로젝트: dmcbride/efte
int EBuffer::DoWrap(int WrapAll) {
    int L, Len, C, P, Ind;
    PELine LP;
    int Left = BFI(this, BFI_LeftMargin), Right = BFI(this, BFI_RightMargin);
    int FirstParaLine;
    int NoChange = 0, NoChangeX = 0;

    if (Left >= Right) return 0;

    L = VToR(CP.Row);

    FirstParaLine = 0;
    if (L > 0)
        if (IsLineBlank(L - 1)) FirstParaLine = L;

    while (L < RCount) {
        NoChange = 1;

        if (VToR(CP.Row) != L || L != FirstParaLine) {
            if (VToR(CP.Row) == L)
                if (CP.Col <= LineIndented(L))
                    if (SetPos(Left, CP.Row) == 0) WFAIL(1);
            Ind = IndentLine(L, Left);
            if (VToR(CP.Row) == L)
                if (SetPos((CP.Col + Ind > 0) ? CP.Col + Ind : 0, CP.Row) == 0) WFAIL(2);
            NoChange = 0;
        }
        Len = LineLen(L);

        if (IsLineBlank(L)) break;

        if (Len < Right) {
            int firstwordbeg = -1;
            int firstwordend = -1;
            int X;
            PELine lp;

            if (L < RCount - 1) {
                IndentLine(L + 1, 0);
                if ((ScreenPos(RLine(L + 1), RLine(L + 1)->Count) == 0) ||
                        (RLine(L + 1)->Chars[0] == '>') || (RLine(L + 1)->Chars[0] == '<')) break;
            } else
                break;
            if (L + 1 >= RCount) break;

            lp = RLine(L + 1);
            for (X = 0; X < lp->Count; X++) {
                if (firstwordbeg == -1 &&
                        ((lp->Chars[X] != ' ') && (lp->Chars[X] != '\t'))) {
                    firstwordbeg = X;
                } else if (firstwordend == -1 &&
                           ((lp->Chars[X] == ' ' || lp->Chars[X] == '\t'))) {
                    firstwordend = X - 1;
                }
            }
            if (firstwordbeg != -1)
                if (firstwordend == -1)
                    firstwordend = lp->Count;

            if (firstwordend == -1) break;
            if (Right - Len > firstwordend - firstwordbeg) {
                if (JoinLine(L, Len + 1) == 0) WFAIL(3);
                NoChange = 0;
                continue;
            } else
                IndentLine(L + 1, Left);
        } else if (Len > Right) {
            C = Right;
            P = CharOffset(LP = RLine(L), C);
            while ((C > Left) &&
                    ((LP->Chars[P] != ' ') &&
                     (LP->Chars[P] != 9)))
                C = ScreenPos(LP, --P);

            if (P <= Left) {
                L++;
                continue;
            }
            C = ScreenPos(LP, P);
            if (SplitLine(L, C) == 0) WFAIL(4);
            IndentLine(L + 1, Left);
            if (L < RCount - 2 && LineLen(L + 1) == Left) {
                if (!IsLineBlank(L + 2)) {
                    if (JoinLine(L + 1, Left) == 0) WFAIL(5);
                }
            }
            if (L == VToR(CP.Row) && CP.Col > C) {
                if (SetPos(Left + CP.Col - C - 1, CP.Row + 1) == 0) WFAIL(6);
            }
            NoChange = 0;
            L++;
            continue;
        }
        if (WrapAll == 0)
            if (NoChangeX) {
                //printf("\n\nBreak OUT = %d\n\x7", L);
                break;
            }
        L++;
        NoChangeX = NoChange;
    }
    if (WrapAll == 1)
        if (SetPosR(Left,
                    (L < RCount - 2) ? (L + 2) :
                    (L < RCount - 1) ? (L + 1) :
                    (RCount - 1)) == 0) WFAIL(7);
    return 1;
}
예제 #24
0
int EBuffer::ShowPosition() {
    int CLine, NLines;
    int CAct, NAct;
    int CColumn, NColumns;
    int CCharPos, NChars;
#ifdef HEAPWALK
    unsigned long MemUsed = 0, MemFree = 0, BlkUsed = 0, BlkFree = 0, BigFree = 0, BigUsed = 0;
#endif

    if (!View)
        return 0;

    CLine = CP.Row + 1;
    NLines = VCount;
    CAct = VToR(CP.Row) + 1;
    NAct = RCount;
    CColumn = CP.Col + 1;
    NColumns = LineLen(CP.Row);
    CCharPos = CharOffset(VLine(CP.Row), CP.Col) + 1;
    NChars = VLine(CP.Row)->Count;

#ifdef HEAPWALK
    if (_heapchk() != _HEAPOK) {
        MemUsed = -1;
    } else {
        _HEAPINFO hi;

        hi._pentry = NULL;
        while (_heapwalk(&hi) == _HEAPOK) {
            if (hi._useflag == _USEDENTRY) {
                BlkUsed++;
                MemUsed += hi._size;
                if (hi._size > BigUsed)
                    BigUsed = hi._size;
                //fprintf(stderr, "USED %d\n", hi._size);
            } else {
                BlkFree++;
                MemFree += hi._size;
                if (hi._size > BigFree)
                    BigFree = hi._size;
                //fprintf(stderr, "FREE %d\n", hi._size);
            }
        }
    }
#endif

    int NN = -1;
    if (US.UndoPtr > 0)
        NN = US.Top[US.UndoPtr - 1];
    Msg(S_INFO,
#ifdef HEAPWALK
        "M%ld,%ld B%ld,%ld S%ld,%ld"
#endif
        "L%d/%d G%d/%d/%d A%d/%d C%d/%d P%d/%d "
        "U%d/%d/%d "
        "H%d/%d/%d",
#ifdef HEAPWALK
        MemUsed, MemFree, BlkUsed, BlkFree, BigUsed, BigFree,
#endif
        CLine, NLines,
        RGap, RCount, RAllocated,
        CAct, NAct,
        CColumn, NColumns,
        CCharPos, NChars,
        US.UndoPtr, US.Num, NN,
        StartHilit, MinRedraw, MaxRedraw);
    return 1;
}
예제 #25
0
void EBuffer::Redraw() {
  int HilitX;
  EView *V;
  EEditPort *W;
  int Row;
  TDrawBuffer B;
  char s[256];
  ChColor SColor;
  int     RowA, RowZ;

  {
    int W1, H1;

    if (!(View && View->MView)) return;

    View->MView->ConQuerySize(&W1, &H1);

    if ((H1 < 1) || (W1 < 1)) return;
  }

  //    printf("Redraw\n");
  if (CP.Row >= VCount) CP.Row = VCount - 1;

  if (CP.Row < 0) CP.Row = 0;

  CheckBlock();
  V = View; /* check some window data */

  if (!V) {
    MinRedraw   = MaxRedraw = -1;
    RedrawToEos = 0;
    return;
  }

  if ((View == 0) || (View->MView == 0) || (View->MView->Win == 0)) return;

  for (; V; V = V->NextView) {
    //        printf("Checking\x7\n");
    if (V->Model != this) assert(1 == 0);

    W = GetViewVPort(V);

    if ((W->Rows < 1) || (W->Cols < 1)) continue;

    if (V == View) {
      int scrollJumpX   = Min(ScrollJumpX, W->Cols / 2);
      int scrollJumpY   = Min(ScrollJumpY, W->Rows / 2);
      int scrollBorderX = Min(ScrollBorderX, W->Cols / 2);
      int scrollBorderY = Min(ScrollBorderY, W->Rows / 2);

      W->CP = CP;
      TP    = W->TP;

      if (W->ReCenter) {
        W->TP.Row   = CP.Row - W->Rows / 2;
        W->TP.Col   = CP.Col - W->Cols + 8;
        W->ReCenter = 0;
      }

      if (W->TP.Row + scrollBorderY > CP.Row) W->TP.Row = CP.Row - scrollJumpY +
                                                          1 - scrollBorderY;

      if (W->TP.Row + W->Rows - scrollBorderY <= CP.Row) W->TP.Row = CP.Row -
                                                                     W->Rows +
                                                                     1 +
                                                                     scrollJumpY - 1 + scrollBorderY;

      if (!WeirdScroll) if (W->TP.Row + W->Rows >= VCount) W->TP.Row = VCount -
                                                                       W->Rows;

      if (W->TP.Row < 0) W->TP.Row = 0;

      if (W->TP.Col + scrollBorderX > CP.Col) W->TP.Col = CP.Col - scrollJumpX -
                                                          scrollBorderX;

      if (W->TP.Col + W->Cols - scrollBorderX <= CP.Col) W->TP.Col = CP.Col -
                                                                     W->Cols +
                                                                     scrollJumpX
                                                                     + scrollBorderX;

      if (W->TP.Col < 0) W->TP.Col = 0;

      if ((W->OldTP.Row != -1) && (W->OldTP.Col != -1) && (RedrawToEos == 0)) {
        if ((W->OldTP.Row != W->TP.Row) || (W->OldTP.Col != W->TP.Col)) {
          int A, B;
          int DeltaX, DeltaY;
          int Rows   = W->Rows;
          int Delta1 = 0, Delta2 = 0;

          DeltaY = W->TP.Row - W->OldTP.Row;
          DeltaX = W->TP.Col - W->OldTP.Col;

          if ((DeltaX == 0) && (-Rows < DeltaY) && (DeltaY < Rows)) {
            if (DeltaY < 0) {
              W->ScrollY(DeltaY);
              A = W->TP.Row;
              B = W->TP.Row - DeltaY;
            } else {
              W->ScrollY(DeltaY);
              A = W->TP.Row + Rows - DeltaY;
              B = W->TP.Row + Rows;
            }
          } else {
            A = W->TP.Row;
            B = W->TP.Row + W->Rows;
          }

          if (A >= VCount) {
            Delta1 = A - VCount + 1;
            A      = VCount - 1;
          }

          if (B >= VCount) {
            Delta2 = B - VCount + 1;
            B      = VCount - 1;
          }

          if (A < 0) A = 0;

          if (B < 0) B = 0;
          Draw(VToR(A) + Delta1, VToR(B) + Delta2);
        }
      } else {
        int A     = W->TP.Row;
        int B     = A + W->Rows;
        int Delta = 0;

        if (B > VCount) {
          Delta += B - VCount;
          B      = VCount;
        }
        int LastV = VToR(VCount - 1);
        int B1    = (B == VCount) ? RCount : VToR(B);

        if (B1 >= LastV) {
          Delta += B1 - LastV;
          B1     = LastV;
        }

        if (B1 < 0) B1 = 0;
          Draw(VToR(A), B1 + Delta);
      }

      W->OldTP = W->TP;
      TP       = W->TP;
    }

    if (W->CP.Row >= VCount) W->CP.Row = VCount - 1;

    if (W->CP.Row < 0) W->CP.Row = 0;

    if (W->TP.Row > W->CP.Row) W->TP.Row = W->CP.Row;

    if (W->TP.Row < 0) W->TP.Row = 0;

    if (V->MView->IsActive()) // hack
      SColor = hcStatus_Active;
    else SColor = hcStatus_Normal;
    MoveChar(B, 0, W->Cols, ' ', SColor, W->Cols);

    if (V->MView->Win->GetViewContext() == V->MView) {
      V->MView->Win->SetSbVPos(W->TP.Row, W->Rows, VCount +
                               (WeirdScroll ? W->Rows - 1 : 0));
      V->MView->Win->SetSbHPos(W->TP.Col, W->Cols, 1024 +
                               (WeirdScroll ? W->Cols - 1 : 0));
    }

    if (V->CurMsg == 0) {
      {
        int CurLine   = W->CP.Row;
        int ActLine   = VToR(W->CP.Row);
        int CurColumn = W->CP.Col;
        int CurPos    = CharOffset(RLine(ActLine), CurColumn);
        int NumLines  = RCount;
        int NumChars  = RLine(ActLine)->Count;

        //            int NumColumns = ScreenPos(Line(CurLine), NumChars);
        char *fName         = FileName;
        unsigned char CurCh = 0xFF;
        int  lf             = strlen(fName);
        char CCharStr[20]   = "";

        if (lf > 34) fName += lf - 34;

        if (CurPos < NumChars) {
          CurCh = VLine(CurLine)->Chars[CurPos];
          sprintf(CCharStr, "%3u,%02X", CurCh, CurCh);
        } else {
          if (CurPos > NumChars) strcpy(CCharStr, "      ");
          else if (CurLine < NumLines - 1) strcpy(CCharStr, "   EOL");
          else strcpy(CCharStr, "   EOF");
        }

          sprintf(s, "%04d:%02d (%04d:%02d) %c%c%c%c%c %.6s %c",

//                    CurLine + 1,
                ActLine + 1,
                CurColumn + 1,
                NumLines,
                NumChars,

//                    CurPos + 1,
                (BFI(this, BFI_Insert)) ? 'I' : ' ',
                (BFI(this, BFI_AutoIndent)) ? 'A' : ' ',

                //                    (BFI(this, BFI_ExpandTabs))?'T':' ',
                (BFI(this, BFI_MatchCase)) ? 'C' : ' ',
                AutoExtend ?
                (
                  (BlockMode == bmStream) ? 's' :
                  (BlockMode == bmLine) ? 'l' : 'c'
                ) :
                ((BlockMode == bmStream) ? 'S' :
                 (BlockMode == bmLine) ? 'L' : 'C'
                ),
                (BFI(this, BFI_WordWrap) == 3) ? 't' :
                (BFI(this, BFI_WordWrap) == 2) ? 'W' :
                (BFI(this, BFI_WordWrap) == 1) ? 'w' :
                ' ',

//                    (BFI(this, BFI_Undo))?'U':' ',
//                    (BFI(this, BFI_Trim))?'E':' ',
//                    (Flags.KeepBackups)?'B':' ',
                Mode->fName,
                (Modified != 0) ? '*' : (BFI(this, BFI_ReadOnly)) ? '%' : ' '
                );

        int  l  = strlen(s);
        int  fw = W->Cols - l;
        int  fl = strlen(FileName);
        char num[32];

        MoveStr(B, 0, W->Cols, s, SColor, W->Cols);
        sprintf(num, " %s %d", CCharStr, ModelNo);
          MoveStr(B, W->Cols - strlen(num), W->Cols, num, SColor, W->Cols);

        fw -= strlen(num);

        if (fl > fw) {
          MoveStr(B, l, W->Cols, FileName + fl - fw, SColor, W->Cols);
        } else {
          MoveStr(B, l, W->Cols, FileName,           SColor, W->Cols);
        }
      }
    } else {
          MoveStr(B, 0, W->Cols, V->CurMsg, SColor, W->Cols);
    }

    if (V->MView->Win->GetStatusContext() == V->MView) {
      V->MView->ConPutBox(0, W->Rows, W->Cols, 1, B);

      if (V->MView->IsActive()) {
        V->MView->ConSetCursorPos(W->CP.Col - W->TP.Col, W->CP.Row - W->TP.Row);
        V->MView->ConSetInsertState(BFI(this, BFI_Insert));
        V->MView->ConShowCursor();
      }
    }
  }

  Rehilit(VToR(CP.Row));

  if (BFI(this, BFI_AutoHilitParen) == 1) {
    if ((Match.Row == -1) && (Match.Col == -1)) HilitMatchBracket();
  }

  //    if ((Window == WW) && (MinRedraw == -1))
  //        MaxRedraw = MinRedraw = VToR(CP.Row);

  // printf("\n\nMinRedraw = %d, MaxRedraw = %d", MinRedraw, MaxRedraw);
  if (MinRedraw == -1) return;

  //    printf("Will redraw: %d to %d, to eos = %d\n", MinRedraw, MaxRedraw,
  // RedrawToEos);
  if (MinRedraw >= VCount) MinRedraw = VCount - 1;

  if (MinRedraw < 0) MinRedraw = 0;

  //    puts("xxx\x7");
  //    printf("%d\n", MinRedraw);
  Row = RowA = RToVN(MinRedraw);

  //    puts("xxx\x7");
  RowZ = MaxRedraw;

  if (MaxRedraw != -1) {
    int Delta = 0;

    if (MaxRedraw >= RCount) {
      Delta     = MaxRedraw - RCount + 1;
      MaxRedraw = RCount - 1;
    }

    if (MaxRedraw < 0) MaxRedraw = 0;

    //        printf("%d\n", MaxRedraw);
    RowZ = RToVN(MaxRedraw) + Delta;
  }

  //    puts("xxx\x7");
  // printf("\nRowA = %d, RowZ = %d", RowA, RowZ);

  V = View;

  while (V) {
    if (V->Model != this) assert(1 == 0);

    W = GetViewVPort(V);

    for (int R = W->TP.Row; R < W->TP.Row + W->Rows; R++) {
      Row = R;

      if ((Row >= RowA) &&
          (RedrawToEos || (Row <= RowZ))) {
        DrawLine(B, Row, W->TP.Col, W->Cols, HilitX);
        W->DrawLine(Row, B);

        if (HilitX && (Row == RowZ)) RowZ++;
      }
    }
    V = V->NextView;
  }
  MinRedraw   = MaxRedraw = -1;
  RedrawToEos = 0;
}
예제 #26
0
int EBuffer::FindRx(RxNode *Rx, SearchReplaceOptions &opt) {
    int Options = opt.Options;
    int LLen, Start, End;
    int C, L;
    char *P;
    PELine X;
    RxMatchRes b;

    if (!(Options & SEARCH_RE))
        return 0;
    if (Options & SEARCH_BACK) { // not supported
        View->MView->Win->Choice(GPC_ERROR, "FindRx", 1, "O&K", "Reverse regexp search not supported.");
        return 0;
    }
    if (Rx == 0)
        return 0;

    if (Match.Row != -1)
        Draw(Match.Row, Match.Row);
    Match.Row = -1;
    Match.Col = -1;

    C = CP.Col;
    L = VToR(CP.Row);
    X = RLine(L);
    C = CharOffset(X, C);

    if (Options & SEARCH_NEXT) {
        int CC = MatchCount ? MatchCount : 1;

        if (Options & SEARCH_BACK) {
            C -= CC;
            if (Options & SEARCH_BLOCK) {
                if (C < BB.Col && L == BB.Row)
                    return 0;
                L--;
                X = RLine(L);
                C = X->Count;
                if (BlockMode == bmColumn)
                    if (BE.Col < C)
                        C = BE.Col;
            } else {
                if (C < 0 && L == 0)
                    return 0;
                L--;
                X = RLine(L);
                C = X->Count;
            }
        } else {
            C += CC;
            if (Options & SEARCH_BLOCK) {
                if (BlockMode == bmStream || BlockMode == bmLine) {
                    if (C >= X->Count) {
                        C = 0;
                        L++;
                        if (BlockMode == bmLine) {
                            if (L == BE.Row) return 0;
                        } else
                            if (L == BE.Row && (C >= BE.Col || C >= X->Count))
                                return 0;
                    }
                } else if (BlockMode == bmColumn) {
                    if (C >= X->Count || C >= BE.Col) {
                        C = BB.Col;
                        L++;
                        if (L == BE.Row) return 0;
                    }
                }
            } else {
                if (C >= X->Count) {
                    C = 0;
                    L++;
                    if (L == RCount) return 0;
                }
            }
        }
    }
    MatchLen = 0;
    MatchCount = 0;

    if (Options & SEARCH_BLOCK) {
        if (Options & SEARCH_BACK) {
            if (BlockMode == bmStream) {
                if (L > BE.Row) {
                    L = BE.Row;
                    C = BE.Col;
                }
                if (L == BE.Row && C > BE.Col)
                    C = BE.Col;
            } else {
                if (L >= BE.Row && BE.Row > 0) {
                    L = BE.Row - 1;
                    C = RLine(L)->Count;
                }
                if (BlockMode == bmColumn)
                    if (L == BE.Row - 1 && C >= BE.Col)
                        C = BE.Col;
            }
        } else {
            if (L < BB.Row) {
                L = BB.Row;
                C = 0;
            }
            if (L == BB.Row && C < BB.Col)
                C = BB.Col;
        }
    }

    while (1) {
        if (Options & SEARCH_BLOCK) {
            if (BlockMode == bmStream) {
                if (L > BE.Row || L < BB.Row) break;
            } else
                if (L >= BE.Row || L < BB.Row) break;
        } else
            if (L >= RCount || L < 0) break;

        X = RLine(L);
        LLen = X->Count;
        P = X->Chars;
        Start = 0;
        End = LLen;

        if (Options & SEARCH_BLOCK) {
            if (BlockMode == bmColumn) {
                Start = CharOffset(X, BB.Col);
                End = CharOffset(X, BE.Col);
            } else if (BlockMode == bmStream) {
                if (L == BB.Row)
                    Start = CharOffset(X, BB.Col);
                if (L == BE.Row)
                    End = CharOffset(X, BE.Col);
            }
            if (End > LLen)
                End = LLen;
        }
        if (Options & SEARCH_BACK) {
            if (C >= End)
                C = End;
        } else {
            if (C < Start)
                C = Start;
        }

        if (Start <= End) {
            if (RxExec(Rx, P + Start, End - Start, P + C, &b, (Options & SEARCH_NCASE) ? 0 : RX_CASE) == 1) {
                C = ScreenPos(X, b.Open[0] + Start);
                Match.Col = C;
                Match.Row = L;
                MatchCount = b.Close[0] - b.Open[0];
                MatchLen = ScreenPos(X, b.Close[0] + Start) - C;
                for (int mm = 0; mm < NSEXPS; mm++) {
                    b.Open[mm] += Start;
                    b.Close[mm] += Start;
                }
                MatchRes = b;
                if (!(Options & SEARCH_NOPOS)) {
                    if (Options & SEARCH_CENTER)
                        CenterPosR(C, L);
                    else
                        SetPosR(C, L);
                }
                Draw(L, L);
                return 1;
            }
        }
        C = 0;
        L++;
    }
    //SetPos(OC, OL);
    return 0;

}