This repository has been archived on 2023-07-11. You can view files and clone it, but cannot push or open issues or pull requests.
fte/e_cmds.cpp

1347 lines
35 KiB
C++

/* e_cmds.cpp
*
* Copyright (c) 1994-1996, Marko Macek
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
*
*/
#include "fte.h"
int EBuffer::MoveLeft() {
if (CP.Col == 0) return 0;
SetPos(CP.Col - 1, CP.Row, tmLeft);
return 1;
}
int EBuffer::MoveRight() {
SetPos(CP.Col + 1, CP.Row, tmRight);
return 1;
}
int EBuffer::MoveUp() {
if (CP.Row == 0) return 0;
SetPos(CP.Col, CP.Row - 1, tmLeft);
return 1;
}
int EBuffer::MoveDown() {
if (CP.Row == VCount - 1) return 0;
SetPos(CP.Col, CP.Row + 1, tmLeft);
return 1;
}
int EBuffer::MovePrev() {
if (MoveLeft()) return 1;
if (MoveUp() && MoveLineEnd()) return 1;
return 0;
}
int EBuffer::MoveNext() {
if (CP.Col < LineLen())
if (MoveRight()) return 1;
if (MoveDown() && MoveLineStart()) return 1;
return 0;
}
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;
}
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);
}
int EBuffer::MoveWordLeft() {
return MoveWordLeftX(1);
}
int EBuffer::MoveWordRight() {
return MoveWordRightX(1);
}
int EBuffer::MoveWordPrev() {
if (MoveWordLeft()) return 1;
if (MoveUp() && MoveLineEnd()) return 1;
return 0;
}
int EBuffer::MoveWordNext() {
if (MoveWordRight()) return 1;
if (MoveDown() && MoveLineStart()) return 1;
return 0;
}
int EBuffer::MoveWordEndLeft() {
return MoveWordLeftX(0);
}
int EBuffer::MoveWordEndRight() {
return MoveWordRightX(0);
}
int EBuffer::MoveWordEndPrev() {
if (MoveWordEndLeft()) return 1;
if (MoveUp() && MoveLineEnd()) return 1;
return 0;
}
int EBuffer::MoveWordEndNext() {
if (MoveWordEndRight()) return 1;
if (MoveDown() && MoveLineStart()) return 1;
return 0;
}
int EBuffer::MoveWordOrCapLeft() {
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]) == 0)) P--;
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--;
C = ScreenPos(L, P);
return SetPos(C, CP.Row);
} else return 0;
} else return 0;
}
int EBuffer::MoveWordOrCapRight() {
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.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++;
while ((P < L->Count) && (WGETBIT(Flags.WordChars, L->Chars[P]) == 0)) P++;
C = ScreenPos(L, P);
return SetPos(C, CP.Row);
}
int EBuffer::MoveWordOrCapPrev() {
if (MoveWordOrCapLeft()) return 1;
if (MoveUp() && MoveLineEnd()) return 1;
return 0;
}
int EBuffer::MoveWordOrCapNext() {
if (MoveWordOrCapRight()) return 1;
if (MoveDown() && MoveLineStart()) return 1;
return 0;
}
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;
}
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);
}
int EBuffer::MoveWordOrCapEndPrev() {
if (MoveWordOrCapEndLeft()) return 1;
if (MoveUp() && MoveLineEnd()) return 1;
return 0;
}
int EBuffer::MoveWordOrCapEndNext() {
if (MoveWordOrCapEndRight()) return 1;
if (MoveDown() && MoveLineStart()) return 1;
return 0;
}
int EBuffer::MoveLineStart() {
SetPos(0, CP.Row);
return 1;
}
int EBuffer::MoveLineEnd() {
SetPos(LineLen(VToR(CP.Row)), CP.Row);
return 1;
}
int EBuffer::MovePageUp() {
return ScrollDown(GetVPort()->Rows);
}
int EBuffer::MovePageDown() {
return ScrollUp(GetVPort()->Rows);
}
int EBuffer::MovePageLeft() {
return ScrollRight(GetVPort()->Cols);
}
int EBuffer::MovePageRight() {
return ScrollRight(GetVPort()->Cols);
}
int EBuffer::MovePageStart() {
SetPos(CP.Col, GetVPort()->TP.Row, tmLeft);
return 1;
}
int EBuffer::MovePageEnd() {
SetNearPos(CP.Col,
GetVPort()->TP.Row +
GetVPort()->Rows - 1, tmLeft);
return 1;
}
int EBuffer::MoveFileStart() {
SetPos(0, 0);
return 1;
}
int EBuffer::MoveFileEnd() {
SetPos(LineLen(VToR(VCount - 1)), VCount - 1);
return 1;
}
int EBuffer::MoveBlockStart() {
if (BB.Col == -1 && BB.Row == -1)
return 0;
assert(BB.Col >= 0 && BB.Row >= 0 && BB.Row < RCount);
if (SetPosR(BB.Col, BB.Row))
return 1;
return 0;
}
int EBuffer::MoveBlockEnd() {
if (BE.Col == -1 && BE.Row == -1)
return 0;
assert(BE.Col >= 0 && BE.Row >= 0 && BE.Row < RCount);
if (SetPosR(BE.Col, BE.Row))
return 1;
return 0;
}
int EBuffer::MoveFirstNonWhite() {
int C = 0, P = 0;
PELine L = VLine(CP.Row);
while (C < L->Count) {
if (L->Chars[C] == ' ') P++;
else if (L->Chars[C] == 9) P = NextTab(P, BFI(this, BFI_TabSize));
else break;
C++;
}
if (SetPos(P, CP.Row) == 0) return 0;
return 1;
}
int EBuffer::MoveLastNonWhite() {
int C = LineLen(), P;
PELine L = VLine(CP.Row);
while (C > 0) {
if (L->Chars[C - 1] == ' ' || L->Chars[C - 1] == 9) C--;
else break;
}
P = ScreenPos(VLine(CP.Row), C);
if (SetPos(P, CP.Row) == 0) return 0;
return 1;
}
int EBuffer::MovePrevEqualIndent() {
int L = VToR(CP.Row);
int I = LineIndented(L);
while (--L >= 0)
if ((RLine(L)->Count > 0) && (LineIndented(L) == I))
return SetPosR(I, L);
return 0;
}
int EBuffer::MoveNextEqualIndent() {
int L = VToR(CP.Row);
int I = LineIndented(L);
while (L++ < RCount - 1)
if ((RLine(L)->Count > 0) && (LineIndented(L) == I))
return SetPosR(I, L);
return 0;
}
int EBuffer::MoveNextTab() {
int P = CP.Col;
P = NextTab(P, BFI(this, BFI_TabSize));
return SetPos(P, CP.Row);
}
int EBuffer::MovePrevTab() {
int P = CP.Col;
if (P > 0) {
P = ((P - 1) / BFI(this, BFI_TabSize)) * BFI(this, BFI_TabSize);
return SetPos(P, CP.Row);
} else return 0;
}
int EBuffer::MoveLineTop() {
if (View)
if (GetVPort()->SetTop(GetVPort()->TP.Col, CP.Row) == 0) return 0;
return 1;
}
int EBuffer::MoveLineCenter() {
if (View) {
int Row = CP.Row - GetVPort()->Rows / 2;
if (Row < 0) Row = 0;
if (GetVPort()->SetTop(GetVPort()->TP.Col, Row) == 0) return 0;
}
return 1;
}
int EBuffer::MoveLineBottom() {
if (View) {
int Row = CP.Row - GetVPort()->Rows + 1;
if (Row < 0) Row = 0;
if (GetVPort()->SetTop(GetVPort()->TP.Col, Row) == 0) return 0;
}
return 1;
}
int EBuffer::MovePrevPos() {
if (PrevPos.Col == -1 || PrevPos.Row == -1) return 0;
if (SetPosR(PrevPos.Col, PrevPos.Row) == 0) return 0;
return 1;
}
int EBuffer::MoveSavedPosCol() {
if (SavedPos.Col == -1) return 0;
if (SetPos(SavedPos.Col, CP.Row) == 0) return 0;
return 1;
}
int EBuffer::MoveSavedPosRow() {
if (SavedPos.Row == -1) return 0;
if (SetPosR(CP.Col, SavedPos.Row) == 0) return 0;
return 1;
}
int EBuffer::MoveSavedPos() {
if (SavedPos.Col == -1 || SavedPos.Row == -1) return 0;
if (SetPosR(SavedPos.Col, SavedPos.Row) == 0) return 0;
return 1;
}
int EBuffer::SavePos() {
SavedPos = CP;
SavedPos.Row = VToR(CP.Row);
return 1;
}
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;
}
int EBuffer::MoveTabEnd() {
PELine X = VLine(CP.Row);
int C = CharOffset(X, CP.Col);
if (C < X->Count)
if (X->Chars[C] == 9)
if (ScreenPos(X, C) < CP.Col)
return SetPos(ScreenPos(X, C + 1), CP.Row);
return 1;
}
int EBuffer::ScrollLeft(int Cols) {
int C = GetVPort()->TP.Col;
if (SetNearPos(CP.Col + Cols, CP.Row, tmLeft) == 0) return 0;
if (GetVPort()->SetTop(C + Cols, GetVPort()->TP.Row) == 0) return 0;
return 1;
}
int EBuffer::ScrollRight(int Cols) {
int C = GetVPort()->TP.Col;
if (SetNearPos(CP.Col - Cols, CP.Row, tmLeft) == 0) return 0;
if (GetVPort()->SetTop(C - Cols, GetVPort()->TP.Row) == 0) return 0;
return 1;
}
int EBuffer::ScrollDown(int Lines) {
int L = GetVPort()->TP.Row;
if (SetNearPos(CP.Col, CP.Row - Lines, tmLeft) == 0) return 0;
if (GetVPort()->SetTop(GetVPort()->TP.Col, L - Lines) == 0) return 0;
return 1;
}
int EBuffer::ScrollUp(int Lines) {
int L = GetVPort()->TP.Row;
if (SetNearPos(CP.Col, CP.Row + Lines, tmLeft) == 0) return 0;
if (GetVPort()->SetTop(GetVPort()->TP.Col, L + Lines) == 0) return 0;
return 1;
}
int EBuffer::MoveBeginOrNonWhite() {
if (CP.Col == 0)
return MoveFirstNonWhite();
else
return MoveLineStart();
}
int EBuffer::MoveBeginLinePageFile() {
int L = GetVPort()->TP.Row;
if (CP.Col == 0 && CP.Row == L)
return MoveFileStart();
else if (CP.Col == 0)
return MovePageStart();
else
return MoveLineStart();
}
int EBuffer::MoveEndLinePageFile() {
int L = GetVPort()->TP.Row + GetVPort()->Rows - 1;
int Len = LineLen();
if (CP.Col == Len && CP.Row == L)
return MoveFileEnd();
else if (CP.Col == Len)
if (MovePageEnd() == 0)
return 0;
return MoveLineEnd();
}
int EBuffer::KillLine() {
int Y = VToR(CP.Row);
if (Y == RCount - 1) {
if (DelText(Y, 0, LineLen())) return 1;
} else
if (DelLine(Y)) return 1;
return 0;
}
int EBuffer::KillChar() {
int Y = VToR(CP.Row);
if (CP.Col < LineLen()) {
if (DelText(Y, CP.Col, 1)) return 1;
} else if (LineJoin()) return 1;
return 0;
}
int EBuffer::KillCharPrev() {
if (CP.Col == 0) {
if (CP.Row > 0)
if (ExposeRow(VToR(CP.Row) - 1) == 0) return 0;
if (!MoveUp()) return 0;
if (!MoveLineEnd()) return 0;
if (LineJoin()) return 1;
} else {
if (!MovePrev()) return 0;
if (DelText(CP.Row, CP.Col, 1)) return 1;
}
return 0;
}
int EBuffer::KillWord() {
int Y = VToR(CP.Row);
if (CP.Col >= LineLen()) {
if (KillChar() == 0) return 0;
} else {
PELine L = RLine(Y);
int P = CharOffset(L, CP.Col);
int C;
int Class = ChClassK(L->Chars[P]);
while ((P < L->Count) && (ChClassK(L->Chars[P]) == Class)) P++;
C = ScreenPos(L, P);
if (DelText(Y, CP.Col, C - CP.Col) == 0) return 0;
}
return 1;
}
int EBuffer::KillWordPrev() {
int Y = VToR(CP.Row);
if (CP.Col == 0) {
if (KillCharPrev() == 0) return 0;
} else if (CP.Col > LineLen()) {
if (SetPos(LineLen(), CP.Row) == 0) return 0;
} else {
PELine L = RLine(Y);
int P = CharOffset(L, CP.Col);
int C;
int Class = ChClassK(L->Chars[P - 1]);
while ((P > 0) && (ChClassK(L->Chars[P - 1]) == Class)) P--;
C = ScreenPos(L, P);
if (DelText(Y, C, CP.Col - C) == 0) return 0;
if (SetPos(C, CP.Row) == 0) return 0;
}
return 1;
}
int EBuffer::KillWordOrCap() {
int Y = VToR(CP.Row);
if (CP.Col >= LineLen()) {
if (KillChar() == 0) return 0;
} else {
PELine L = VLine(CP.Row);
int P = CharOffset(L, CP.Col);
int C;
int Class = ChClassK(L->Chars[P]);
if (Class == 1) {
if (WGETBIT(Flags.CapitalChars, L->Chars[P]) == 1)
while ((P < L->Count) && (WGETBIT(Flags.CapitalChars, L->Chars[P]) == 1)) P++;
while ((P < L->Count) && (WGETBIT(Flags.WordChars, L->Chars[P]) == 1) && (WGETBIT(Flags.CapitalChars, L->Chars[P]) == 0)) P++;
} else while ((P < L->Count) && (ChClassK(L->Chars[P]) == Class)) P++;
C = ScreenPos(L, P);
if (DelText(Y, CP.Col, C - CP.Col) == 0) return 0;
}
return 1;
}
int EBuffer::KillWordOrCapPrev() {
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]);
if (Class == 1) {
if (WGETBIT(Flags.CapitalChars, L->Chars[P - 1]) == 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--;
} else while ((P > 0) && (ChClassK(L->Chars[P - 1]) == Class)) P--;
C = ScreenPos(L, P);
if (DelText(Y, C, CP.Col - C) == 0) return 0;
if (SetPos(C, CP.Row) == 0) return 0;
}
return 1;
}
int EBuffer::KillToLineStart() {
int Y = VToR(CP.Row);
if (DelText(Y, 0, CP.Col) == 0) return 0;
if (MoveLineStart() == 0) return 0;
return 1;
}
int EBuffer::KillToLineEnd() {
int Y = VToR(CP.Row);
if (DelText(Y, CP.Col, LineLen() - CP.Col)) return 1;
return 0;
}
int EBuffer::KillBlock() {
return BlockKill();
}
int EBuffer::KillBlockOrChar() {
if (CheckBlock() == 0)
return KillChar();
else
return BlockKill();
}
int EBuffer::KillBlockOrCharPrev() {
if (CheckBlock() == 0)
return KillCharPrev();
else
return BlockKill();
}
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;
} 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;
} else {
if (MovePrev() == 0) return 0;
if (DelText(Y, CP.Col, 1) == 0) return 0;
}
}
#ifdef CONFIG_WORDWRAP
if (BFI(this, BFI_WordWrap) == 2) {
if (DoWrap(0) == 0) return 0;
}
#endif
if (BFI(this, BFI_Trim)) {
Y = VToR(CP.Row);
if (TrimLine(Y) == 0) return 0;
}
return 1;
}
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
if (DelText(Y, CP.Col, 1) == 0) return 0;
} else
if (LineJoin() == 0) return 0;
#ifdef CONFIG_WORDWRAP
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;
}
}
#endif
if (BFI(this, BFI_Trim))
if (TrimLine(VToR(CP.Row)) == 0)
return 0;
return 1;
}
int EBuffer::LineInsert() {
if (InsLine(VToR(CP.Row), 0)) return 1;
return 0;
}
int EBuffer::LineAdd() {
if (InsLine(VToR(CP.Row), 1) && MoveDown()) return 1;
return 0;
}
int EBuffer::LineSplit() {
if (SplitLine(VToR(CP.Row), CP.Col) == 0) return 0;
if (BFI(this, BFI_Trim))
if (TrimLine(VToR(CP.Row)) == 0) return 0;
return 1;
}
int EBuffer::LineJoin() {
if (JoinLine(VToR(CP.Row), CP.Col)) return 1;
return 0;
}
int EBuffer::LineNew() {
if (SplitLine(VToR(CP.Row), CP.Col) == 0)
return 0;
if (!MoveDown())
return 0;
if (CP.Col > 0) {
if (!MoveLineStart())
return 0;
//int Indent = LineIndented(VToR(CP.Row));
if (!LineIndent())
return 0;
//if (Indent > 0)
// if (InsText(Row, C, Indent, 0) == 0)
// return 0;
if (BFI(this, BFI_Trim))
if (TrimLine(VToR(CP.Row - 1)) == 0)
return 0;
}
return 1;
}
int EBuffer::LineIndent() {
int rc = 1;
if (BFI(this, BFI_AutoIndent)) {
int L = VToR(CP.Row);
switch (BFI(this, BFI_IndentMode)) {
#ifdef CONFIG_INDENT_C
case INDENT_C: rc = Indent_C(this, L, 1); break;
#endif
#ifdef CONFIG_INDENT_REXX
case INDENT_REXX: rc = Indent_REXX(this, L, 1); break;
#endif
#ifdef CONFIG_INDENT_SIMPLE
case INDENT_SIMPLE: rc = Indent_SIMPLE(this, L, 1); break;
#endif
default: rc = Indent_Plain(this, L, 1); break;
}
}
if (rc == 0) return 0;
if (BFI(this, BFI_Trim))
if (TrimLine(VToR(CP.Row)) == 0) return 0;
return 1;
}
int EBuffer::LineLen() {
return LineLen(VToR(CP.Row));
}
int EBuffer::LineCount() {
assert(1 == 0);
return RCount;
}
int EBuffer::CLine() {
assert(1 == 0);
return VToR(CP.Row);
}
int EBuffer::CColumn() {
return CP.Col;
}
int EBuffer::InsertChar(char aCh) {
return InsertString(&aCh, 1);
}
int EBuffer::TypeChar(char aCh) { // does abbrev expansion if appropriate
if (BFI(this, BFI_InsertKillBlock) == 1)
if (CheckBlock() == 1)
if (BlockKill() == 0)
return 0;
#ifdef CONFIG_ABBREV //fprintf(stderr, "TypeChar\n");
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;
}
}
}
}
}
#endif
return InsertString(&aCh, 1);
}
int EBuffer::InsertString(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))
if (TrimLine(L) == 0)
return 0;
#ifdef CONFIG_WORDWRAP
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;
}
}
#endif
return 1;
}
int EBuffer::InsertSpacesToTab(int TSize) {
int P = CP.Col, P1;
if (BFI(this, BFI_InsertKillBlock) == 1)
if (CheckBlock() == 1)
if (BlockKill() == 0)
return 0;
if (TSize <= 0)
TSize = BFI(this, BFI_TabSize);
P1 = NextTab(P, TSize);
if (BFI(this, BFI_Insert) == 0) {
if (CP.Col < LineLen())
if (DelText(VToR(CP.Row), CP.Col, P1 - P) == 0) return 0;
}
if (InsText(VToR(CP.Row), CP.Col, P1 - P, 0) == 0) return 0;
if (SetPos(P1, CP.Row) == 0) return 0;
return 1;
}
int EBuffer::InsertTab() {
return (BFI(this, BFI_SpaceTabs)) ?
InsertSpacesToTab(BFI(this, BFI_TabSize)) : InsertChar(9);
}
int EBuffer::InsertSpace() {
return TypeChar(32);
}
int EBuffer::LineIndented(int Row) {
int P;
char *PC;
int I;
int Ind = 0;
if (Row < 0) return 0;
if (Row >= RCount) return 0;
P = RLine(Row)->Count;
PC = RLine(Row)->Chars;
for (I = 0; I < P; I++) {
if (PC[I] == ' ') Ind++;
else if ((PC[I] == 9) && (BFI(this, BFI_ExpandTabs) == 1)) Ind = NextTab(Ind, BFI(this, BFI_TabSize));
else break;
}
return Ind;
}
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;
}
#ifdef CONFIG_UNDOREDO
int EBuffer::CanUndo() {
if (BFI(this, BFI_Undo) == 0) return 0;
if (US.Num == 0 || US.UndoPtr == 0) return 0;
return 1;
}
int EBuffer::CanRedo() {
if (BFI(this, BFI_Undo) == 0) return 0;
if (US.Num == 0 || US.UndoPtr == US.Num) return 0;
return 1;
}
#endif
int EBuffer::IsLineBlank(int Row) {
PELine X = RLine(Row);
int P;
for (P = 0; P < X->Count; P++)
if (X->Chars[P] != ' ' && X->Chars[P] != 9)
return 0;
return 1;
}
#ifdef CONFIG_WORDWRAP
#define WFAIL(x) return 0 /*do { puts(#x "\x7"); return -1; } while (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;
}
int EBuffer::WrapPara() {
while (VToR(CP.Row) < RCount - 1 && IsLineBlank(VToR(CP.Row)))
if (SetPos(CP.Col, CP.Row + 1) == 0) return 0;
return DoWrap(1);
}
#endif
int EBuffer::LineCenter() {
if (LineTrim() == 0)
return 0;
int ind = LineIndented(VToR(CP.Row));
int left = BFI(this, BFI_LeftMargin);
int right = BFI(this, BFI_RightMargin);
int len = LineLen();
//int chs = len - ind;
int newind = left + ((right - left) - (len - ind)) / 2;
if (newind < left)
newind = left;
return IndentLine(VToR(CP.Row), newind);
}
int EBuffer::InsPrevLineChar() {
int L = VToR(CP.Row);
int C = CP.Col, P;
if (L > 0) {
L--;
if (C < LineLen(L)) {
P = CharOffset(RLine(L), C);
return InsertChar(RLine(L)->Chars[P]);
}
}
return 0;
}
int EBuffer::InsPrevLineToEol() {
int L = VToR(CP.Row);
int C = CP.Col, P;
int Len;
if (L > 0) {
L--;
P = CharOffset(RLine(L), C);
Len = RLine(L)->Count - P;
if (Len > 0)
return InsertString(RLine(L)->Chars + P, Len);
}
return 0;
}
int EBuffer::LineDuplicate() {
int Y = VToR(CP.Row);
if (InsLine(Y, 1) == 0) return 0;
if (InsChars(Y + 1, 0, RLine(Y)->Count, RLine(Y)->Chars) == 0) return 0;
return 1;
}
int EBuffer::TrimLine(int Row) {
PELine L = RLine(Row);
int P, X, E;
if (L->Count == 0) return 1;
P = L->Count;
while ((P > 0) && ((L->Chars[P - 1] == ' ') || (L->Chars[P - 1] == 9)))
P--;
X = ScreenPos(L, P);
E = ScreenPos(L, L->Count);
if (E - X > 0)
if (DelText(Row, X, E - X, 1) == 0) return 0;
return 1;
}
int EBuffer::LineTrim() {
return TrimLine(VToR(CP.Row));
}
int EBuffer::FileTrim() {
for (int L = 0; L < RCount; L++)
if (TrimLine(L) == 0)
return 0;
return 1;
}
int EBuffer::BlockTrim() {
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);
for (L = B.Row; L <= E.Row; L++) {
switch (BlockMode) {
case bmStream:
if (L < E.Row || E.Col != 0)
if (TrimLine(L) == 0)
return 0;
break;
case bmLine:
case bmColumn:
if (L < E.Row)
if (TrimLine(L) == 0)
return 0;
break;
}
}
return 1;
}
#define TOGGLE(x) \
Flags.num[BFI_##x] = (Flags.num[BFI_##x]) ? 0 : 1; \
/*Msg(INFO, #x " is now %s.", Flags.num[BFI_##x] ? "ON" : "OFF");*/ \
return 1;
#define TOGGLE_R(x) \
Flags.num[BFI_##x] = (Flags.num[BFI_##x]) ? 0 : 1; \
/*Msg(INFO, #x " is now %s.", Flags.num[BFI_##x] ? "ON" : "OFF");*/ \
FullRedraw(); \
return 1;
int EBuffer::ToggleAutoIndent() { TOGGLE(AutoIndent); }
int EBuffer::ToggleInsert() { TOGGLE(Insert); }
int EBuffer::ToggleExpandTabs() { TOGGLE_R(ExpandTabs); }
int EBuffer::ToggleShowTabs() { TOGGLE_R(ShowTabs); }
int EBuffer::ToggleUndo() { FreeUndo(); TOGGLE(Undo); }
int EBuffer::ToggleReadOnly() { TOGGLE(ReadOnly); }
int EBuffer::ToggleKeepBackups() { TOGGLE(KeepBackups); }
int EBuffer::ToggleMatchCase() { TOGGLE(MatchCase); }
int EBuffer::ToggleBackSpKillTab() { TOGGLE(BackSpKillTab); }
int EBuffer::ToggleDeleteKillTab() { TOGGLE(DeleteKillTab); }
int EBuffer::ToggleSpaceTabs() { TOGGLE(SpaceTabs); }
int EBuffer::ToggleIndentWithTabs() { TOGGLE(IndentWithTabs); }
int EBuffer::ToggleBackSpUnindents() { TOGGLE(BackSpUnindents); }
int EBuffer::ToggleTrim() { TOGGLE(Trim); }
int EBuffer::ToggleShowMarkers() { TOGGLE_R(ShowMarkers); }
int EBuffer::ToggleWordWrap() {
BFI(this, BFI_WordWrap) = (BFI(this, BFI_WordWrap) + 1) % 3;
/*Msg(INFO,
"WordWrap is now %s.",
(BFI(this, BFI_WordWrap) == 2) ? "AUTO" :
(BFI(this, BFI_WordWrap) == 1) ? "ON" : "OFF"); */
return 1;
}
int EBuffer::SetLeftMargin() {
BFI(this, BFI_LeftMargin) = CP.Col;
Msg(S_INFO, "LeftMargin set to %d.", BFI(this, BFI_LeftMargin) + 1);
return 1;
}
int EBuffer::SetRightMargin() {
BFI(this, BFI_RightMargin) = CP.Col;
Msg(S_INFO, "RightMargin set to %d.", BFI(this, BFI_RightMargin) + 1);
return 1;
}
int EBuffer::ChangeMode(char *AMode) {
if (FindMode(AMode) != 0) {
Mode = FindMode(AMode);
Flags = Mode->Flags;
HilitProc = 0;
if (Mode && Mode->fColorize)
HilitProc = GetHilitProc(Mode->fColorize->SyntaxParser);
FullRedraw();
return 1;
}
Msg(S_ERROR, "Mode '%s' not found.", AMode);
return 0;
}
int EBuffer::ChangeKeys(char *AMode) {
if (FindMode(AMode) != 0) {
Mode = FindMode(AMode);
HilitProc = 0;
if (Mode && Mode->fColorize)
HilitProc = GetHilitProc(Mode->fColorize->SyntaxParser);
FullRedraw();
return 1;
}
Msg(S_ERROR, "Mode '%s' not found.", AMode);
return 0;
}
int EBuffer::ChangeFlags(char *AMode) {
if (FindMode(AMode) != 0) {
EMode *XMode;
XMode = FindMode(AMode);
Flags = XMode->Flags;
HilitProc = 0;
if (Mode && Mode->fColorize)
HilitProc = GetHilitProc(Mode->fColorize->SyntaxParser);
FullRedraw();
return 1;
}
Msg(S_ERROR, "Mode '%s' not found.", AMode);
return 0;
}