示例#1
0
文件: e_cmds.cpp 项目: dmcbride/efte
int EBuffer::IndentLine(int Row, int Indent) {
    int I, C;
    int Ind = Indent;

    if (Row < 0) return 0;
    if (Row >= RCount) return 0;
    if (Indent < 0) Indent = 0;
    I = LineIndented(Row);
    if (Indent != I) {
        if (I > 0)
            if (DelText(Row, 0, I) == 0) return 0;
        if (Indent > 0) {
            C = 0;
            if (BFI(this, BFI_IndentWithTabs)) {
                char ch = 9;

                while (BFI(this, BFI_TabSize) <= Indent) {
                    if (InsText(Row, C, 1, &ch) == 0) return 0;
                    Indent -= BFI(this, BFI_TabSize);
                    C += BFI(this, BFI_TabSize);
                }
            }
            if (Indent > 0)
                if (InsText(Row, C, Indent, 0) == 0) return 0;
        }
    }
    return Ind - I;
}
示例#2
0
int EBuffer::BlockUnindent() {
    EPoint B, E;
    int L;

    AutoExtend = 0;
    if (CheckBlock() == 0) return 0;
    if (RCount <= 0) return 0;
    B = BB;
    E = BE;
    Draw(B.Row, E.Row);
    if (SetPosR(B.Col, B.Row) == 0) return 0;
    for (L = B.Row; L <= E.Row; L++) {
        switch (BlockMode) {
        case bmStream:
        case bmLine:
            if (L < E.Row || E.Col != 0) {
                int I = LineIndented(L) - 1;
                if (I >= 0)
                    IndentLine(L, I);
            }
            break;
        case bmColumn:
            if (L < E.Row) {
                if (InsText(L, E.Col, 1, 0) == 0) return 0;
                if (DelText(L, B.Col, 1) == 0) return 0;
            }
            break;
        }
    }
    if (SetPosR(B.Col, B.Row) == 0) return 0;
    return 1;
}
示例#3
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;
}
示例#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::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;
}
示例#6
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;
}
示例#7
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;
}