Exemplo n.º 1
0
int EBuffer::LineJoin() {
    if (JoinLine(VToR(CP.Row), CP.Col)) return 1;
    return 0;
}
Exemplo n.º 2
0
int EBuffer::BlockKill() {
    EPoint B, E;
    int L;
    int Y = -1;

    AutoExtend = 0;
    if (CheckBlock() == 0) return 0;
    if (RCount <= 0) return 0;
    B = BB;
    E = BE;
    Draw(B.Row, -1);
    //    if (MoveToPos(B.Col, B.Row) == 0) return 0;

#ifdef CONFIG_UNDOREDO
    if (BFI(this, BFI_Undo) == 1) {
        if (PushULong(CP.Col) == 0) return 0;
        if (PushULong(CP.Row) == 0) return 0;
        if (PushUChar(ucPosition) == 0) return 0;
    }
#endif

    switch (BlockMode) {
    case bmLine:
        Y = VToR(CP.Row);
        if (Y >= B.Row) {
            if (Y >= E.Row) {
                if (SetPosR(CP.Col, Y - (E.Row - B.Row)) == 0) return 0;
            } else {
                if (SetPosR(CP.Col, B.Row) == 0) return 0;
            }
        }
        for (L = B.Row; L < E.Row; L++)
            if (DelLine(B.Row) == 0) return 0;
        break;

    case bmColumn:
        Y = VToR(CP.Row);
        if (Y >= B.Row && Y < E.Row) {
            if (CP.Col >= B.Col) {
                if (CP.Col >= E.Col) {
                    if (SetPos(CP.Col - (E.Col - B.Col), CP.Row) == 0) return 0;
                } else {
                    if (SetPos(B.Col, CP.Row) == 0) return 0;
                }
            }
        }
        for (L = B.Row; L < E.Row; L++)
            if (DelText(L, B.Col, E.Col - B.Col) == 0) return 0;
        break;

    case bmStream:
        Y = VToR(CP.Row);

        if (B.Row == E.Row) {
            if (Y == B.Row) {
                if (CP.Col >= B.Col) {
                    if (CP.Col >= E.Col) {
                        if (SetPos(CP.Col - (E.Col - B.Col), CP.Row) == 0) return 0;
                    } else {
                        if (SetPos(B.Col, CP.Row) == 0) return 0;
                    }
                }
            }
            if (DelText(B.Row, B.Col, E.Col - B.Col) == 0) return 0;
        } else {
            if (Y >= B.Row) {
                if (Y > E.Row || (Y == E.Row && E.Col == 0)) {
                    if (SetPosR(CP.Col, Y - (E.Row - B.Row)) == 0) return 0;
                } else if (Y == E.Row) {
                    if (CP.Col >= E.Col) {
                        if (SetPosR(CP.Col - E.Col + B.Col, B.Row) == 0) return 0;
                    } else {
                        if (SetPosR(B.Col, B.Row) == 0) return 0;
                    }
                } else {
                    if (SetPosR(B.Col, B.Row) == 0) return 0;
                }
            }
            if (DelText(E.Row, 0, E.Col) == 0) return 0;
            for (L = B.Row + 1; L < E.Row; L++)
                if (DelLine(B.Row + 1) == 0) return 0;
            if (DelText(B.Row, B.Col, -1) == 0) return 0;
            if (JoinLine(B.Row, B.Col) == 0) return 0;
        }
        break;
    }
    return BlockUnmark();
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
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;
}