home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-12-12 | 48.5 KB | 1,838 lines |
-
- {***************************************}
- {* BIGED.IN1 1.03 *}
- {* (part of BIGED.PAS) *}
- {***************************************}
-
- function BigEditor.beOfsWhite(P : LinePtr) : Byte;
- var B : Byte;
- begin
- beOfsWhite := 0;
- if P^.lnLen = 0 then exit;
- B := 0;
- while (B <= Byte(P^.St^[0])) and (P^.St^[B+1] = ' ') do
- Inc(B);
- beOfsWhite := B;
- end;
-
- procedure BigEditor.beResetSplit;
- var
- I : Integer;
- begin
- CurTopIdx := EList.Num(CurTop);
- I := CurLineOfs;
- if I > Height-1 then
- I := Height-1;
- CurLine := CurTop;
- CurLineOfs := 0;
- beLineDown(I);
- end;
-
- procedure BigEditor.beReAlign;
- var
- N : LinePtr;
- I : Integer;
- begin
- CurTopIdx := EList.Num(CurTop);
- N := CurTop;
- I := 0;
- while (I < Height-1) and (CurLine <> N) do begin
- N := LinePtr(N^.dlNext);
- Inc(I);
- end;
- if I = Height-1 then
- CurLine := LinePtr(N^.dlPrev);
- CurLineOfs := I;
- end;
-
- procedure BigEditor.beRealignDown;
- var
- N : LinePtr;
- I : Integer;
- begin
- CurTopIdx := EList.Num(CurTop);
- N := CurTop;
- I := 0;
- while (N^.dlNext <> nil) and (CurLine <> N) do begin
- N := LinePtr(N^.dlNext);
- Inc(I);
- if I > Height-1 then begin
- CurTop := LinePtr(CurTop^.dlNext);
- Inc(CurTopIdx);
- end;
- end;
- if I >= Height-1 then
- CurLineOfs := Height-1
- else
- CurLineOfs := I;
- end;
-
- procedure BigEditor.beDeleteLinePrim(P : LinePtr);
- var Q,T : LinePtr;
- IsBetween : Boolean;
- InVis : Boolean;
- W : Integer;
- begin
- T := P;
- with EList do begin
- if T^.dlNext = NIL then
- T^.lnUpdate('')
- else begin
- if T = CurTop then begin
- CurTop := LinePtr(CurTop^.dlNext);
- if T = CurLine then
- CurLine := LinePtr(CurLine^.dlNext)
- else
- Dec(CurLineOfs);
- end
- else if T = CurLine then
- CurLine := LinePtr(CurLine^.dlNext)
- else begin
- IsBetween := False;
- InVis := False;
- Q := CurTop;
- for W := 1 to Height do begin
- if Q = T then InVis := True;
- if (Q = CurLine) and (InVis) then IsBetween := True;
-
- if Q <> NIL then
- Q := LinePtr(Next(Q));
- end;
- if IsBetween then
- Dec(CurLineOfs);
- end;
- beLineDeleted(T);
- EList.Delete(T);
- end;
- end;
- SetLongFlag(beOptions,beModified);
- beForceRedraw := True;
- end;
-
-
- procedure BigEditor.beCharsInserted(LP : LinePtr; Count : Integer);
- var I : Integer;
-
- procedure FixMarker(var MR : MarkerRec; IsEnd,IsTextMarker : Boolean);
- var T : Integer;
- begin
- with MR do
- if (Line = LP) and (Col >= COfs+XOfs) then begin
- T := Col;
- if (IsTextMarker) or
- ((IsEnd) and (T+1 >= COfs+XOfs)) or
- (T > COfs+XOfs) then
- Inc(T, Count);
-
- if T < COfs+XOfs then
- Col := COfs+XOfs
- else
- Col := T;
- end;
- end;
-
- begin
- if LP = BkTop.Line then FixMarker(BkTop,False,False);
- if LP = BkBot.Line then FixMarker(BkBot,True,False);
- beCheckBlock;
- if NOT beOptionsAreOn(beBlockOK) then
- beOptionsOff(beBlockOn);
-
- if MarkerFlags <> 0 then
- for I := 0 to MaxMarker do
- if LP = Markers[i].Line then
- FixMarker(Markers[i],False,True);
- end;
-
- procedure BigEditor.beLineDeleted(P : LinePtr);
- var I : Integer;
- begin
- if P = BkTop.Line then begin
- if P = BkBot.Line then begin
- beResetMarkers(False);
- beOptionsOff(beBlockOn);
- end
- else begin
- IncPtr(BkTop.Line,1);
- Inc(BkTop.LNum);
- BkTop.Col := 1;
- end;
- end
- else if P = BkBot.Line then begin
- IncPtr(BkBot.Line,1);
- Inc(BkBot.LNum);
- BkBot.Col := 0;
- end
- else begin
- I := EList.Num(P);
- if I < BkTop.LNum then begin
- Dec(BkTop.LNum);
- Dec(BkBot.LNum);
- end
- else if I < BkBot.LNum then
- Dec(BkBot.LNum);
- end;
- beCheckBlock;
- if beOptionsAreOn(beBlockOK) then begin
- beClearBlocking;
- beConnectMarks;
- end;
-
- if MarkerFlags <> 0 then
- for I := 0 to MaxMarker do
- if Markers[i].Line = P then
- Markers[i].Line := NIL;
-
- SetLongFlag(beOptions,beModified);
- beForceRedraw := True;
- end;
-
- procedure BigEditor.beBreakLine(At : Integer);
- var L : LinePtr;
- P : LinePtr;
- I : Integer;
- B : Byte;
-
- procedure FixMarker(var MR : MarkerRec; IsEnd : Boolean);
- begin
- with MR do if Line <> nil then
- if ((IsEnd) and (Col <= At)) or
- (Col >= At) then begin
- IncPtr(Line,1);
- Inc(LNum);
- Col := Col-At+1;
- end;
- end;
-
- begin
- Tmp := '';
- B := 1;
- P := CurLine;
-
- {place our new line in the stream}
- New(L,Init(''));
- EList.Place(L,P);
- {fixup blocking}
- if P = BkTop.Line then begin
- FixMarker(BkTop,False);
- if P = BkBot.Line then
- FixMarker(BkBot,True);
- end
- else if P = BkBot.Line then
- FixMarker(BkBot,True)
- else begin
- I := CurTopIdx+CurLineOfs;
- if I < BkTop.LNum then begin
- Inc(BkTop.LNum);
- Inc(BkBot.LNum);
- end
- else if I < BkBot.LNum then
- Inc(BkBot.LNum);
- end;
-
- beCheckBlock;
- if beOptionsAreOn(beBlockOK) then begin
- beClearBlocking;
- beConnectMarks;
- end;
- if MarkerFlags <> 0 then
- for I := 1 to MaxMarker do
- if Markers[i].Line = P then
- FixMarker(Markers[i],False);
-
- if At <= P^.lnLen then begin
- {split the line}
- Tmp := Copy(Current,At,Length(Current));
- Delete(Current,At,Length(Current));
- P^.lnUpdate(Current);
- end;
-
- {add padding if nessessary}
- if beOptionsAreOn(beIndent) then begin
- B := beOfsWhite(P);
- if B > 0 then
- Insert(CharStr(' ',B),Tmp,1);
- end;
-
- L^.lnUpdate(Tmp);
- beLineDown(1);
- beCursorHome;
- beCursorRight(B);
- beCharsInserted(CurLine,B);
- SetLongFlag(beOptions,beModified);
- beForceRedraw := True;
- end;
-
- procedure BigEditor.beWrapLine;
- var L : LinePtr;
- P : LinePtr;
- I : Integer;
- B : Byte;
-
- procedure FixMarker(var MR : MarkerRec; At : Integer);
- begin
- with MR do if Line <> nil then
- if Col >= At then begin
- IncPtr(Line,1);
- Inc(LNum);
- Col := Col-At+1;
- end;
- end;
-
- begin
- Tmp := '';
- B := 1;
- P := CurLine;
-
- {place our new line in the stream}
- New(L,Init(''));
- EList.Place(L,P);
- WordWrap(Current,Current,Tmp,Margin,False);
- P^.lnUpdate(Current);
-
- {fixup blocking}
- if P = BkTop.Line then begin
- FixMarker(BkTop,Length(Current)+1);
- if P = BkBot.Line then
- FixMarker(BkBot,Length(Current)+1);
- end
- else if P = BkBot.Line then
- FixMarker(BkBot,Length(Current)+1)
- else begin
- I := CurTopIdx+CurLineOfs;
- if I < BkTop.LNum then begin
- Inc(BkTop.LNum);
- Inc(BkBot.LNum);
- end
- else if I < BkBot.LNum then
- Inc(BkBot.LNum);
- end;
-
- beCheckBlock;
- if beOptionsAreOn(beBlockOK) then begin
- beClearBlocking;
- beConnectMarks;
- end;
- if MarkerFlags <> 0 then
- for I := 1 to MaxMarker do
- if Markers[i].Line = P then
- FixMarker(Markers[i],Length(Current)+1);
-
- {add padding if nessessary}
- if beOptionsAreOn(beIndent) then begin
- Tmp := Trim(Tmp);
- B := beOfsWhite(P);
- if B > 0 then
- Insert(CharStr(' ',B),Tmp,1);
- end;
-
- L^.lnUpdate(Tmp);
- beLineDown(1);
- beCursorHome;
- beCursorRight(Length(Tmp));
- beCharsInserted(CurLine,Length(Tmp));
- SetLongFlag(beOptions,beModified);
- beForceRedraw := True;
- end;
-
- procedure BigEditor.beJoinLines(LP : LinePtr);
- var L,P : LinePtr;
- I,J : Integer;
-
- procedure FixMarker(var MR : MarkerRec; PrevLen : Integer);
- begin
- with MR do if Line <> NIL then begin
- DecPtr(Line,1);
- Dec(LNum);
- Col := Col + PrevLen;
- end;
- end;
-
- begin
- P := LP;
- L := LinePtr(P^.dlNext);
- if L = NIL then exit;
- J := P^.lnLen;
- P^.lnUpdate(P^.lnReturn+L^.lnReturn);
-
- {fixup blocking}
- if P = BkTop.Line then begin
- FixMarker(BkTop,J);
- if P = BkBot.Line then
- FixMarker(BkBot,J);
- end
- else if P = BkBot.Line then
- FixMarker(BkBot,J)
- else begin
- I := EList.Num(P);
- if I < BkTop.LNum then begin
- Dec(BkTop.LNum);
- Dec(BkBot.LNum);
- end
- else if I < BkBot.LNum then
- Dec(BkBot.LNum);
- end;
-
- beCheckBlock;
- if beOptionsAreOn(beBlockOK) then begin
- beClearBlocking;
- beConnectMarks;
- end;
- if MarkerFlags <> 0 then
- for I := 0 to MaxMarker do
- if Markers[i].Line = L then
- FixMarker(Markers[i],J);
-
- EList.Delete(L);
- SetLongFlag(beOptions,beModified);
- beForceRedraw := True;
- end;
-
- procedure BigEditor.beTabOver;
- var P : LinePtr;
- N,W : Integer;
- begin
- if beOptionsAreOn(beSmartTabs) then begin
- W := COfs+XOfs;
- P := CurLine;
- DecPtr(P,1);
- if (P = NIL) or (W > P^.lnLen) then
- IncPtr(P,2);
- if (P <> NIL) and (W <= P^.lnLen) then begin
- Tmp := P^.lnReturn;
- N := W;
- while (W <= Length(Tmp)) and (Tmp[w] <> ' ') do
- Inc(W);
- while (W <= Length(Tmp)) and (Tmp[w] = ' ') do
- Inc(W);
- if W > N then begin
- if N <= Length(Current) then begin
- Insert(CharStr(' ',W-N),Current,N);
- CurLine^.lnUpdate(Current);
- beCharsInserted(CurLine,W-N);
- SetLongFlag(beOptions,beModified);
- end;
- beCursorRight(W-N);
- end;
- end;
- end
- else if beDefTabDelta > 0 then begin
- W := beDefTabDelta - ((COfs+XOfs) mod beDefTabDelta);
- if W = 0 then W := beDefTabDelta;
- if COfs+XOfs <= Length(Current) then begin
- Insert(CharStr(' ',W),Current,COfs+XOfs);
- CurLine^.lnUpdate(Current);
- beCharsInserted(CurLine,W);
- SetLongFlag(beOptions,beModified);
- end;
- beCursorRight(W);
- end;
- end;
-
- procedure BigEditor.beInsertChar(C : Char);
- {insert a character into the stream}
- var W : Byte absolute Current;
- B,L : Byte;
- S : String;
- P : LinePtr;
- begin
- if COfs+XOfs >= 255 then exit;
- if W < (COfs+XOfs) then begin
- Current := Pad(Current,COfs+XOfs-1) + C;
- beCharsInserted(CurLine,COfs+XOfs-W);
- end
- else if LongFlagIsSet(beOptions,beInsert) then begin
- Insert(C,Current,COfs+XOfs);
- beCharsInserted(CurLine,1);
- end
- else
- Current[COfs+XOfs] := C;
- CurLine^.lnUpdate(Current);
- beCursorRight(1);
- SetLongFlag(beOptions,beModified);
-
- {if we're wrapping, do so here}
- if (beOptionsAreOn(beWordWrap)) and
- (COfs+XOfs > Margin+1) and
- (C <> ' ') then
- beWrapLine;
- end;
-
- procedure BigEditor.beNewLine(MoveDown : Boolean);
- {-insert a new line below the current}
- var
- L : LinePtr;
- I : Integer;
- begin
- if NOT LongFlagIsSet(beOptions,beInsert) then begin
- beLineDown(1);
- COfs := 1;
- XOfs := 0;
- end
- else if NOT(MoveDown) then begin
- I := COfs+XOfs;
- beBreakLine(CurLine^.lnLen+1);
- beLineUp(1);
- beCursorHome;
- beCursorRight(I-1);
- end
- else
- beBreakLine(COfs+XOfs);
- end;
-
- procedure BigEditor.beBackspace;
- {-backspace over the previous character}
- var
- I : Integer;
- begin
- if (COfs+XOfs > 1) then begin
- if (COfs+XOfs) <= (CurLine^.lnLen+1) then begin
- System.Delete(Current,COfs+XOfs-1,1);
- CurLine^.lnUpdate(Current);
- beCharsInserted(CurLine, -1);
- SetLongFlag(beOptions,beModified);
- end;
- beCursorLeft(1);
- end
- else if CurLine^.dlPrev <> NIL then begin
- beLineUp(1);
- I := CurLine^.lnLen;
- beJoinLines(CurLine);
- beCursorHome;
- beCursorRight(I);
- beForceRedraw := True;
- SetLongFlag(beOptions,beModified);
- end;
- end;
-
- procedure BigEditor.beDeleteCharAtCursor;
- {-delete the current character}
- begin
- if (COfs+XOfs) <= Length(Current) then begin
- System.Delete(Current,COfs+XOfs,1);
- CurLine^.lnUpdate(Current);
- beCharsInserted(CurLine,-1);
- SetLongFlag(beOptions,beModified);
- end
- else if beOptionsAreOn(beDeleteJoins) then begin
- if Length(Current) < COfs+XOfs-1 then
- CurLine^.lnUpdate(Pad(Current,COfs+XOfs-1));
- beJoinLines(CurLine);
- SetLongFlag(beOptions,beModified);
- beForceRedraw := True;
- end;
- end;
-
- procedure BigEditor.beWordLeft;
- {-jump to the start of the previous word}
- var W : Byte absolute Current;
- X,N : Integer;
- Cl : CharClass;
- begin
- if COfs+XOfs > 1 then begin
- if W < (COfs+XOfs) then begin
- if COfs+XOfs{W} >= WinWidth then begin
- COfs := WinWidth;
- XOfs := W - WinWidth + 1;
- beForceRedraw := True;
- end
- else begin
- COfs := W+1;
- XOfs := 0;
- end;
- end;
- X := COfs+XOfs;
- N := X;
- while (X > 1) and (GetClass(Current[x-1]) <> Alpha) do
- Dec(x);
- while (X > 1) and (GetClass(Current[x-1]) = Alpha) do
- Dec(x);
- beCursorLeft(N-X);
- end
- else if CurLine^.dlPrev <> NIL then begin
- beLineUp(1);
- beCursorEOL;
- end;
- end;
-
- procedure BigEditor.beWordRight;
- {-jump to the start of the next word}
- var W : Byte Absolute Current;
- N,X : Integer;
- begin
- if (COfs+XOfs > W) and (CurLine^.dlNext <> NIL) then begin
- beLineDown(1);
- beCursorHome;
- end
- else begin
- X := COfs+XOfs;
- N := X;
- while (X <= W) and NOT(Current[x] in beWordDelims) do
- Inc(X);
- while (X <= W) and (Current[x] in beWordDelims) do
- Inc(X);
- beCursorRight(X-N);
- end;
- end;
-
- procedure BigEditor.beDeleteWordRight;
- {-delete the current word}
- var
- P : LinePtr;
- W,X,I : Integer;
- Sl : Byte absolute Current;
- ChClass : CharClass;
- begin
- X := XOfs+COfs;
- if (Sl < X) and (CurLine^.dlNext <> NIL) then
- beJoinLines(CurLine)
- else begin
- W := X;
- if Current[w] <> ' ' then begin
- ChClass := GetClass(Current[w]);
- while (W <= Sl) and (GetClass(Current[w]) = ChClass) do
- Inc(W);
- end;
- while (W <= Sl) and (GetClass(Current[w]) = Blank) do
- Inc(W);
-
- I := W-X;
- if W > X then begin
- System.Delete(Current,X,I);
- CurLine^.lnUpdate(Current);
- beCharsInserted(CurLine,-I);
- SetLongFlag(beOptions,beModified);
- end;
- end;
- end;
-
- procedure BigEditor.beDeleteToEndOfLine;
- {-delete the rest of the current line}
- var I : Integer;
- begin
- if (COfs+XOfs) <= Length(Current) then begin
- I := Length(Current) - (COfs+XOfs);
- System.Delete(Current,COfs+XOfs,Length(Current));
- CurLine^.lnUpdate(Current);
- beCharsInserted(CurLine,-I);
- SetLongFlag(beOptions,beModified);
- beForceRedraw := True;
- end;
- end;
-
- procedure BigEditor.beSaveStreamState(var S : StreamStateRec;
- SaveBlocking : Boolean);
- begin
- with S do begin
- SaveCurTopIdx := CurTopIdx;
- SaveCurLineOfs := CurLineOfs;
- SaveCOfs := COfs;
- SaveXOfs := XOfs;
- SaveFlags := beOptions;
- if SaveBlocking then begin
- SaveBkTop := BkTop;
- SaveBkBot := BkBot;
- SaveMarkers := Markers;
- end
- else begin
- FillChar(SaveBkTop,SizeOf(SaveBkTop),0);
- SaveBkBot := SaveBkBot;
- FillChar(SaveMarkers,SizeOf(SaveMarkers),0);
- end;
- end;
- end;
-
- procedure BigEditor.beRestoreStreamState(var S : StreamStateRec;
- RestoreBlocking : Boolean);
- var I : Integer;
- begin
- beResetLineList;
- with S do begin
- CurTop := LinePtr(EList.Nth(SaveCurTopIdx));
- CurLine := CurTop;
- CurTopIdx := SaveCurTopIdx;
- CurLineOfs := SaveCurLineOfs;
- I := 0;
- while I <> CurLineOfs do begin
- CurLine := LinePtr(CurLine^.dlNext);
- Inc(I);
- end;
- COfs := SaveCOfs;
- XOfs := SaveXOfs;
- beOptions := beOptions or (SaveFlags and not BadBigEdOptions);
- if RestoreBlocking then begin
- BkTop := SaveBkTop;
- BkTop.Line := LinePtr(EList.Nth(BkTop.LNum));
- BkBot := SaveBkBot;
- BkBot.Line := LinePtr(EList.Nth(BkBot.LNum));
- beCheckBlock;
- if beOptionsAreOn(beBlockOK) then begin
- beClearBlocking;
- beConnectMarks;
- beOptionsOn(beBlockOn);
- end;
- Markers := SaveMarkers;
- for I := 0 to MaxMarker do
- Markers[i].Line := LinePtr(EList.Nth(Markers[i].LNum));
- end;
- end;
- beForceRedraw := True;
- end;
-
- {----------------------- Block-oriented operations -------------------------}
-
- procedure BigEditor.beClearBlocking;
- var P : LinePtr;
- begin
- with EList do begin
- P := LinePtr(Head);
- while P <> NIL do begin
- P^.lnFlagsOff(IsBlocked);
- P := LinePtr(P^.dlNext);
- end;
- ClearLongFlag(beOptions,beBlockOK);
- end;
- end;
-
- procedure BigEditor.beConnectMarks;
- var P : LinePtr;
- begin
- P := BkTop.Line;
- if P = NIL then
- beClearBlocking
- else if BkBot.Line <> NIL then begin
- P^.lnFlagsOn(IsBlocked);
- while (P <> nil) and (P <> BkBot.Line) do begin
- P^.lnFlagsOn(IsBlocked);
- P := LinePtr(P^.dlNext);
- end;
- if P <> nil then begin
- P^.lnFlagsOn(IsBlocked);
- SetLongFlag(beOptions,beBlockOK);
- end
- else
- beClearBlocking;
- end;
- end;
-
- function BigEditor.beLineInBlock(P : LinePtr) : Boolean;
- var N : LinePtr;
- begin
- beLineInBlock := True;
- N := BkTop.Line;
- while (N <> nil) and (N <> BkBot.Line) do begin
- if N = P then exit;
- N := LinePtr(N^.dlNext);
- end;
- beLineInBlock := (P = BkBot.Line);
- end;
-
- procedure BigEditor.beSetBkTop;
- begin
- with BkTop do begin
- Line := CurLine;
- LNum := CurTopIdx+CurLineOfs;
- Col := COfs+XOfs;
- end;
- beCheckBlock;
- if beOptionsAreOn(beBlockOK) then begin
- beClearBlocking;
- beConnectMarks;
- beOptionsOn(beBlockOn);
- end
- else beOptionsOff(beBlockOn);
- beForceRedraw := True;
- end;
-
- procedure BigEditor.beSetBkBot;
- begin
- with BkBot do begin
- Line := CurLine;
- LNum := CurTopIdx+CurLineOfs;
- Col := Pred(COfs+XOfs);
- end;
- beCheckBlock;
- if beOptionsAreOn(beBlockOK) then begin
- beClearBlocking;
- beConnectMarks;
- beOptionsOn(beBlockOn);
- end
- else beOptionsOff(beBlockOn);
- beForceRedraw := True;
- end;
-
- procedure BigEditor.beCheckBlock;
- var P : LinePtr;
- begin
- ClearLongFlag(beOptions,beBlockOK);
- {if no markers defined, exit}
- if (BkTop.Line = NIL) or (BkBot.Line = NIL) then exit;
- {if same line but mismatched columns, exit}
- P := BkTop.Line;
- if (P = BkBot.Line) then
- if BkTop.Col >= BkBot.Col then exit;
- {scan forward, looking for BkBot}
- with EList do while P <> NIL do begin
- if P = BkBot.Line then begin
- SetLongFlag(beOptions,beBlockOK);
- exit;
- end;
- P := LinePtr(Next(P));
- end;
- end;
-
- function BigEditor.beStoreBlock(var ToList : LineList) : Boolean;
- label Skip;
- var P,N : LinePtr;
- begin
- beStoreBlock := False;
- beCheckBlock;
- if (NOT(beOptionsAreOn(beBlockOK))) or
- (NOT(beOptionsAreOn(beBlockOn))) then exit;
- SBkTop := BkTop;
- SBkBot := BkBot;
- ToList.Clean;
- P := BkTop.Line;
-
- if BkTop.Line = BkBot.Line then begin
- Tmp := Copy(P^.lnReturn,BkTop.Col,BkBot.Col-BkTop.Col+1);
- New(N,Init(Tmp));
- if N = NIL then goto Skip;
- ToList.Append(N);
- beStoreBlock := True;
- exit;
- end
- else begin
- Tmp := Copy(P^.lnReturn,BkTop.Col,P^.lnLen);
- New(N,Init(Tmp));
- if N = NIL then goto Skip;
- ToList.Append(N);
-
- P := LinePtr(EList.Next(P));
- while P <> BkBot.Line do begin
- New(N,Init(P^.lnReturn));
- if N = NIL then goto Skip;
- ToList.Append(N);
- P := LinePtr(EList.Next(P));
- end;
-
- Tmp := Copy(BkBot.Line^.lnReturn,1,BkBot.Col);
- if TrimLead(Tmp) = '' then Tmp := '';
- New(N,Init(Tmp));
- if N = NIL then goto Skip;
- ToList.Append(N);
- beStoreBlock := True;
- exit;
- end;
- Skip:
- GotError(epNonFatal+ecOutofMemory,'Out of memory');
- ToList.Clean;
- end;
-
- procedure BigEditor.beCopyBlock;
- var N,O,P : LinePtr;
- S : String;
- begin
- beCheckBlock;
- if (NOT(beOptionsAreOn(beBlockOK))) or
- (NOT(beOptionsAreOn(beBlockOn))) then exit;
- SBkTop := BkTop;
- SBkBot := BkBot;
-
- if BkTop.Line = BkBot.Line then begin
- S := Copy(BkTop.Line^.St^,BkTop.Col,BkBot.Col-BkTop.Col+1);
- Tmp := CurLine^.St^;
- if COfs+XOfs > Length(Tmp) then
- Tmp := Pad(Tmp,COfs+XOfs-1) + S
- else
- Insert(S,Tmp,COfs+XOfs);
- CurLine^.lnUpdate(Tmp);
-
- {update blocking}
- BkTop.Line^.lnFlagsOff(IsBlocked);
- BkTop.Line := CurLine;
- BkTop.LNum := CurTopIdx+CurLineOfs;
- BkTop.Col := COfs+XOfs;
- BkBot := BkTop;
- BkBot.Col := Min(CurLine^.lnLen,COfs+XOfs+Length(S)-1);
- CurLine^.lnFlagsOn(IsBlocked);
- end
- else begin
- N := BkTop.Line;
- P := CurLine;
- Tmp := P^.lnReturn;
- {if needed, split the current line}
- if COfs+XOfs <= Length(Tmp) then begin
- S := Copy(Tmp,COfs+XOfs,Length(Tmp));
- Delete(Tmp,COfs+XOfs,Length(Tmp));
- end
- else begin
- if COfs+XOfs-1 > Length(Tmp) then
- Tmp := Pad(Tmp,COfs+XOfs-1);
- S := '';
- end;
-
- {set BlockTop to our new starting point}
- BkTop.Line := P;
- BkTop.LNum := CurTopIdx+CurLineOfs;
- BkBot.LNum := BkTop.LNum;
- BkTop.Col := COfs+XOfs;
-
- {walk the list, inserting lines}
- Tmp := P^.St^ + N^.St^;
- P^.lnUpdate(Tmp);
- N^.lnFlagsOff(IsBlocked);
- N := LinePtr(N^.dlNext);
- while N <> BkBot.Line do begin
- New(O,Init(N^.St^));
- O^.lnFlagsOn(IsBlocked);
- EList.Place(O,P);
- P := LinePtr(P^.dlNext);
- N^.lnFlagsOff(IsBlocked);
- N := LinePtr(N^.dlNext);
- Inc(BkBot.LNum);
- end;
-
- {fixup the last line}
- Tmp := Copy(N^.lnReturn,1,BkBot.Col);
- N^.lnFlagsOff(IsBlocked);
- BkBot.Col := Length(Tmp);
- if S <> '' then Tmp := Tmp + S;
- New(O,Init(Tmp));
- O^.lnFlagsOn(IsBlocked);
- EList.Place(O,P);
- P := LinePtr(P^.dlNext);
- Inc(BkBot.LNum);
- BkBot.Line := P;
- BkTop.Line^.lnFlagsOn(IsBlocked);
- end;
- SetLongFlag(beOptions,beBlockOn);
- SetLongFlag(beOptions,beModified);
- beForceRedraw := True;
- end;
-
- procedure BigEditor.beMoveBlock;
- var N,O,P,SP : LinePtr;
- S,T : String;
- begin
- beCheckBlock;
- if (NOT(beOptionsAreOn(beBlockOK))) or
- (NOT(beOptionsAreOn(beBlockOn))) then exit;
- SBkTop := BkTop;
- SBkBot := BkBot;
-
- if BkTop.Line = BkBot.Line then begin
- Tmp := BkTop.Line^.lnReturn;
- S := Copy(Tmp,BkTop.Col,BkBot.Col-BkTop.Col+1);
- Delete(Tmp,BkTop.Col,BkBot.Col-BkTop.Col+1);
- BkTop.Line^.lnUpdate(Tmp);
- Tmp := CurLine^.St^;
- if COfs+XOfs > Length(Tmp) then
- Tmp := Pad(Tmp,COfs+XOfs-1) + S
- else
- Insert(S,Tmp,COfs+XOfs);
- CurLine^.lnUpdate(Tmp);
-
- {update blocking}
- BkTop.Line^.lnFlagsOff(IsBlocked);
- BkTop.Line := CurLine;
- BkTop.LNum := CurTopIdx+CurLineOfs;
- BkTop.Col := COfs+XOfs;
- BkBot := BkTop;
- BkBot.Col := Min(CurLine^.lnLen,COfs+XOfs+Length(S)-1);
- CurLine^.lnFlagsOn(IsBlocked);
- end
- else begin
- SP := nil;
- N := BkTop.Line;
- Tmp := N^.lnReturn;
- T := Copy(Tmp,BkTop.Col,Length(Tmp));
- Delete(Tmp,BkTop.Col,Length(Tmp));
- if Tmp = '' then
- SP := N
- else
- N^.lnUpdate(Tmp);
-
- P := CurLine;
- Tmp := P^.lnReturn;
- if COfs+XOfs <= Length(Tmp) then begin
- S := Copy(Tmp,COfs+XOfs,Length(Tmp));
- Delete(Tmp,COfs+XOfs,Length(Tmp));
- end
- else begin
- if COfs+XOfs-1 > Length(Tmp) then
- Tmp := Pad(Tmp,COfs+XOfs-1);
- S := '';
- end;
-
- {set BlockTop to our new starting point}
- BkTop.Line := P;
- BkTop.LNum := CurTopIdx+CurLineOfs;
- BkBot.LNum := BkTop.LNum;
- BkTop.Col := COfs+XOfs;
-
- {walk the list, removing at old and inserting at new location}
- Tmp := P^.St^ + T;
- P^.lnUpdate(Tmp);
- N^.lnFlagsOff(IsBlocked);
- N := LinePtr(N^.dlNext);
- while N <> BkBot.Line do begin
- O := N;
- N := LinePtr(N^.dlNext);
- EList.Remove(O);
- EList.Place(O,P);
- P := LinePtr(P^.dlNext);
- Inc(BkBot.LNum);
- end;
-
- {fixup the last line}
- Tmp := Copy(BkBot.Line^.lnReturn,1,BkBot.Col);
- BkBot.Line^.lnFlagsOff(IsBlocked);
- BkBot.Col := Length(Tmp);
- New(O,Init(Tmp+S));
- O^.lnFlagsOn(IsBlocked);
- EList.Place(O,P);
- P := LinePtr(P^.dlNext);
- Inc(BkBot.LNum);
- Delete(Tmp,1,BkBot.Col);
- BkBot.Line^.lnUpdate(Tmp);
- BkBot.Line := P;
- BkTop.Line^.lnFlagsOn(IsBlocked);
- if SP <> nil then
- EList.Delete(SP);
- beResetSplit;
- end;
- SetLongFlag(beOptions,beBlockOn);
- SetLongFlag(beOptions,beModified);
- beForceRedraw := True;
- end;
-
- procedure BigEditor.beDeleteBlock;
- var S : String;
- N,P : LinePtr;
- I : Integer;
- B : Boolean;
- SvSplt : Integer;
-
- function LineInBlock(P : LinePtr) : Boolean;
- var N : LinePtr;
- begin
- LineInBlock := True;
- N := BkTop.Line;
- while (N <> LinePtr(BkBot.Line^.dlNext)) do begin
- if P = N then exit;
- N := LinePtr(N^.dlNext);
- end;
- LineInBlock := False;
- end;
-
- function BlockIsBetween : Boolean;
- var P : LinePtr;
- begin
- BlockIsBetween := True;
- P := CurTop;
- while P <> CurLine do begin
- if P = BkTop.Line then exit;
- P := LinePtr(P^.dlNext);
- end;
- BlockIsBetween := False;
- end;
-
- begin
- B := False;
- beCheckBlock;
- if (NOT(beOptionsAreOn(beBlockOK))) or
- (NOT(beOptionsAreOn(beBlockOn))) then begin
- GotError(epNonFatal+ecNoBlock,'No block defined');
- exit;
- end;
- P := BkTop.Line;
- {if a single line, handle here}
- if BkTop.Line = BkBot.Line then begin
- S := P^.lnReturn;
- Delete(S,BkTop.Col,BkBot.Col-BkTop.Col+1);
- P^.lnUpdate(S);
- P^.lnFlagsOff(IsBlocked);
- beResetMarkers(False);
- if CurLine = P then begin
- beCursorHome;
- beCursorRight(BkTop.Col-1);
- end;
- end
- else with EList do begin
- if LineInBlock(CurTop) then begin
- CurTop := BkTop.Line;
- CurTopIdx := BkTop.LNum;
- if LineInBlock(CurLine) then begin
- CurLine := CurTop;
- CurLineOfs := 0;
- beCursorHome;
- beCursorRight(BkTop.Col - 1);
- end
- else B := True;
- end
- else if LineInBlock(CurLine) then begin
- P := CurTop;
- CurLine := BkTop.Line;
- CurLineOfs := 0;
- while (P <> CurLine) and (CurLineOfs < Height-1) do begin
- Inc(CurLineOfs);
- P := LinePtr(P^.dlNext);
- end;
- beCursorHome;
- beCursorRight(BkTop.Col - 1);
- end
- else B := BlockIsBetween;
-
- P := BkTop.Line;
- S := P^.lnReturn;
- System.Delete(S,BkTop.Col,Length(S));
- P^.lnUpdate(S);
-
- P := BkBot.Line;
- S := P^.lnReturn;
- System.Delete(S,1,BkBot.Col);
- SvSplt := 1;
- P^.lnUpdate(S);
-
- P := LinePtr(BkTop.Line^.dlNext);
- while P <> BkBot.Line do begin
- Inc(SvSplt);
- EList.Delete(P);
- P := LinePtr(BkTop.Line^.dlNext);
- end;
-
- P := BkTop.Line;
- beJoinLines(P);
- end;
- beResetSplit;
- if B then
- beLineUp(SvSplt);
- beResetMarkers(False);
- ClearLongFlag(beOptions,beBlockOn+beBlockOK);
- SetLongFlag(beOptions,beModified);
- beForceRedraw := True;
- end;
-
- procedure BigEditor.beInsertBlockAtCursor(var FromList : LineList);
- var P,N,O : LinePtr;
- B : Boolean;
- S : String;
- begin
- if (FromList.Size = 0) then begin
- GotError(epNonFatal+ecNoBlock,'No block defined');
- exit;
- end;
-
- P := CurLine;
- if FromList.Head = FromList.Tail then begin
- {a partial line to insert in the current line}
- S := LinePtr(FromList.Head)^.lnReturn;
-
- Tmp := CurLine^.St^;
- if COfs+XOfs > Length(Tmp) then
- Tmp := Pad(Tmp,COfs+XOfs-1) + S
- else
- Insert(S,Tmp,COfs+XOfs);
- CurLine^.lnUpdate(Tmp);
-
- {update blocking}
- beClearBlocking;
- BkTop.Line := CurLine;
- BkTop.LNum := CurTopIdx+CurLineOfs;
- BkTop.Col := COfs+XOfs;
- BkBot := BkTop;
- BkBot.Col := Min(CurLine^.lnLen,COfs+XOfs+Length(S)-1);
- CurLine^.lnFlagsOn(IsBlocked);
- end
- else begin
- Tmp := P^.lnReturn;
- {if needed, split the current line}
- if COfs+XOfs <= Length(Tmp) then begin
- S := Copy(Tmp,COfs+XOfs,Length(Tmp));
- Delete(Tmp,COfs+XOfs,Length(Tmp));
- end
- else begin
- if COfs+XOfs-1 > Length(Tmp) then
- Tmp := Pad(Tmp,COfs+XOfs-1);
- S := '';
- end;
-
- {set BlockTop to our new starting point}
- BkTop.Line := P;
- BkTop.LNum := CurTopIdx+CurLineOfs;
- BkBot.LNum := BkTop.LNum;
- BkTop.Col := COfs+XOfs;
-
- {walk the list, inserting lines}
- N := LinePtr(FromList.Head);
- Tmp := P^.St^ + N^.St^;
- P^.lnUpdate(Tmp);
- N := LinePtr(N^.dlNext);
- while N <> NIL do begin
- New(O,Init(N^.St^));
- EList.Place(O,P);
- P := LinePtr(P^.dlNext);
- N := LinePtr(N^.dlNext);
- Inc(BkBot.LNum);
- end;
-
- {set BlockBot to our ending line}
- BkBot.Line := P;
- BkBot.Col := BkBot.Line^.lnLen;
-
- {if needed, merge in the tail of the split top line}
- if S <> '' then begin
- Tmp := P^.lnReturn;
- P^.lnUpdate(Tmp+S);
- end;
-
- {reset things}
- beClearBlocking;
- beConnectMarks;
- end;
- SetLongFlag(beOptions,beBlockOn);
- SetLongFlag(beOptions,beModified);
- beForceRedraw := True;
- end;
-
- procedure BigEditor.beReadBlock;
- var F : Text;
- FHandle : Word;
- FName : PathStr;
- P,N : LinePtr;
- begin
- FName := '';
- if not beGetFileName(epMessage+mcBlockWrite, emBlockWrite,
- FName, True, False) then
- Exit;
- Assign(F,FName);
- Reset(F);
- if IOResult <> 0 then begin
- GotError(epNonFatal+ecFileNotFound,'File not found');
- exit;
- end
- else if HandleIsConsole(FHandle) then begin
- Close(F); if IOResult = 0 then ;
- GotError(epNonFatal+ecNotToScreen,'Cannot read file from screen');
- exit;
- end;
-
- TmpList.Clean;
- while NOT EOF(F) do begin
- ReadLn(F,Tmp);
- if IOResult = 0 then begin
- New(P,Init(Tmp));
- if P = NIL then begin
- GotError(epNonFatal+ecOutofMemory,'Out of memory');
- Close(F); if IOResult = 0 then ;
- exit;
- end;
- TmpList.Append(P);
- end;
- end;
- {assure block marks are not equal}
- BkTop.Line := CurTop;
- BkBot.Line := NIL;
- beInsertBlockAtCursor(TmpList);
- SetLongFlag(beOptions,beBlockOn);
- SetLongFlag(beOptions,beModified);
- beForceRedraw := True;
- end;
-
- procedure BigEditor.beWriteBlock(ToPrn : Boolean);
- var F : Text;
- FHandle : Word absolute F;
- FName : PathStr;
- I : Integer;
- P : LinePtr;
- begin
- beCheckBlock;
- if (NOT(beOptionsAreOn(beBlockOK))) then exit;
-
- if ToPrn then begin
- FName := 'LPT1';
- Inc(FName[4], Pred(beLPT));
- end
- else begin
- FName := '';
- if not beGetFileName(epMessage+mcBlockWrite, emBlockWrite,
- FName, True, False) then
- Exit;
- end;
-
- Assign(F, FName);
- Rewrite(F);
- I := IOResult;
- if I <> 0 then begin
- GotError(epNonFatal+I, emOpenError);
- Close(F);
- I := IOResult;
- Exit;
- end
- else if HandleIsConsole(FHandle) then begin
- GotError(epNonFatal+ecNotToScreen, emNotToScreen);
- Exit;
- end;
-
- if NOT beStoreBlock(TmpList) then exit;
- with TmpList do begin
- if Size = 0 then exit;
- P := LinePtr(Head);
- while P <> nil do begin
- WriteLn(F,P^.lnReturn);
- if IOResult <> 0 then begin
- GotError(epNonFatal+ecDeviceWrite, 'Error writing block');
- P := nil;
- end
- else
- P := LinePtr(P^.dlNext);
- end;
- Close(F); if IOResult = 0 then ;
- beInformation(0,'');
- end;
- end;
-
- procedure BigEditor.beIndentBlock(AddSp : Boolean);
- var P : LinePtr;
-
- function CursorInBlock : Boolean;
- var N : LinePtr;
- begin
- CursorInBlock := True;
- N := BkTop.Line;
- while N <> LinePtr(BkBot.Line^.dlNext) do begin
- if N = CurLine then exit;
- N := LinePtr(N^.dlNext);
- end;
- CursorInBlock := False;
- end;
-
- begin
- beCheckBlock;
- if (NOT(beOptionsAreOn(beBlockOK))) or
- (NOT(beOptionsAreOn(beBlockOn))) then begin
- GotError(epNonFatal+ecNoBlock,'No block defined');
- exit;
- end;
- if NOT(CursorInBlock) then exit;
- P := BkTop.Line;
- if P = BkBot.Line then exit;
-
- Tmp := P^.lnReturn;
- if P^.lnLen > 0 then begin
- if AddSp then begin
- Insert(CharStr(' ',DefBlockIndent),Tmp,BkTop.Col);
- if BkTop.Col > 1 then Inc(BkTop.Col,DefBlockIndent);
- end
- else begin
- Delete(Tmp,BkTop.Col,DefBlockIndent);
- if BkTop.Col > DefBlockIndent then
- Dec(BkTop.Col,DefBlockIndent)
- else
- BkTop.Col := 1;
- end;
- P^.lnUpdate(Tmp);
- end;
-
- P := LinePtr(P^.dlNext);
- while (P <> NIL) and (P <> BkBot.Line) do begin
- Tmp := P^.lnReturn;
- if P^.lnLen > 0 then begin
- if AddSp then
- Insert(CharStr(' ',DefBlockIndent),Tmp,1)
- else
- Delete(Tmp,1,DefBlockIndent);
- P^.lnUpdate(Tmp);
- end;
- P := LinePtr(P^.dlNext);
- end;
-
- if (P <> NIL) and (P^.lnLen > 0) then begin
- Tmp := P^.lnReturn;
- if (AddSp) then begin
- if (BkBot.Col > 0) then begin
- Insert(CharStr(' ',DefBlockIndent),Tmp,1);
- Inc(BkBot.Col,DefBlockIndent);
- end;
- end
- else begin
- Delete(Tmp,1,DefBlockIndent);
- if BkBot.Col >= DefBlockIndent then
- Dec(BkBot.Col,DefBlockIndent)
- else
- BkBot.Col := 0;
- end;
- P^.lnUpdate(Tmp);
- end;
- if AddSp then
- beCursorRight(DefBlockIndent)
- else
- beCursorLeft(DefBlockIndent);
- beForceRedraw := True;
- SetLongFlag(beOptions,beModified);
- end;
-
- procedure BigEditor.beBlockWord;
- var P : LinePtr;
- W,X : Integer;
- begin
- W := COfs+XOfs;
- Tmp := TrimTrail(CurLine^.lnReturn);
- if W > Length(Tmp) then exit;
- if Tmp[w] = ' ' then begin
- {find the start of the next word}
- while (W <= Length(Tmp)) and (Tmp[w] = ' ') do
- Inc(W);
- if W > Length(Tmp) then exit;
- end
- else
- {find the start of the current word}
- while (W > 1) and (Tmp[w-1] <> ' ') do Dec(W);
- BkTop.Line := CurLine;
- BkTop.Col := W;
- {find the end of the current word}
- while (W <= Length(Tmp)) and (Tmp[w+1] <> ' ') do
- Inc(W);
- BkBot.Line := CurLine;
- BkBot.Col := W;
- beClearBlocking;
- CurLine^.lnFlagsOn(IsBlocked);
- beOptionsOn(beBlockOn);
- beForceRedraw := True;
- end;
-
- procedure BigEditor.beChangeCaseBlock(Cmd : Byte);
- {-Change the case of all characters in block or of character at cursor}
- var
- P : LinePtr;
-
- function ToggleCase(Ch : Char) : Char;
- {-Toggle the case of the specified character}
- var
- NewCh : Char;
- begin
- NewCh := UpCase(Ch);
- if NewCh <> Ch then
- ToggleCase := NewCh
- else
- ToggleCase := Locase(Ch);
- end;
-
- procedure FixChar(var Ch : Char);
- {-Fix the case of Ch based on the user's command}
- begin
- if Ch > ' ' then
- case Cmd of
- ccBlkUCase : Ch := UpCase(Ch);
- ccBlkLCase : Ch := LoCase(Ch);
- ccBlkTCase : Ch := ToggleCase(Ch);
- end;
- end;
-
- procedure FixLine(P : LinePtr; Start, Stop : Integer);
- var
- TLen : Byte;
- I : Integer;
- begin
- TLen := P^.lnLen;
- for I := Start to Stop do
- if I <= TLen then
- FixChar(P^.St^[i]);
- end;
-
- begin
- if (LongFlagIsSet(beOptions, beBlockOn)) and
- (beLineInBlock(CurLine)) then begin
- if BkTop.Line = BkBot.Line then
- FixLine(CurLine,BkTop.Col,BkBot.Col)
- else begin
- P := BkTop.Line;
- FixLine(P,BkTop.Col,P^.lnLen);
- IncPtr(P,1);
- while P <> BkBot.Line do begin
- FixLine(P,1,P^.lnLen);
- IncPtr(P,1);
- end;
- FixLine(P,1,BkBot.Col);
- beForceRedraw := True;
- end;
- SetLongFlag(beOptions,beModified);
- end
- else if (COfs+COfs <= CurLine^.lnLen) then begin
- {change the case of the character at the cursor}
- FixChar(CurLine^.St^[COfs+XOfs]);
- SetLongFlag(beOptions,beModified);
- end;
- end;
-
- procedure BigEditor.beCopyToClipboard;
- begin
- if beStoreBlock(Clipboard) then begin
- beOptionsOff(beBlockOn);
- beForceRedraw := True;
- end;
- end;
-
- procedure BigEditor.beCutToClipboard;
- begin
- if beStoreBlock(Clipboard) then begin
- beDeleteBlock;
- beForceRedraw := True;
- end;
- end;
-
- procedure BigEditor.bePasteFromClipboard;
- begin
- if Clipboard.Head <> NIL then
- beInsertBlockAtCursor(Clipboard);
- end;
-
- {--------------------- Search/Replace/Reformat stuff -----------------------}
-
- procedure BigEditor.beTextSearch(Prompt : Boolean; SearchType : beSearchType);
- label ExitPoint;
- var
- SaveRec : StreamStateRec;
- SaveIdx : Integer;
- Hits : Integer;
- TSrch : String[MaxSearchLen];
- N : Integer;
- YN : Byte;
-
- procedure ReplaceText(var Cur : String; Repl : String; Start, Len : Integer);
- begin
- Delete(Cur,Start,Len);
- Insert(Repl,Cur,Start);
- end;
-
- function NextMatch(StartLine : LinePtr; Srch : String) : LinePtr;
- var P : LinePtr;
- T : String;
- begin
- NextMatch := NIL;
- P := StartLine;
- if P <> NIL then begin
- if NoCase then
- Tmp := StUpcase(P^.lnReturn)
- else
- Tmp := P^.lnReturn;
- if Backwards then begin
- while P <> NIL do begin
- while SaveIdx >= 1 do begin
- if Srch[1] = Tmp[SaveIdx] then begin {possible match}
- T := Copy(Tmp,SaveIdx,Length(Srch));
- if T = Srch then begin {positive match}
- NextMatch := P;
- exit;
- end;
- end;
- Dec(SaveIdx);
- end;
- P := LinePtr(EList.Prev(P));
- if P <> NIL then begin
- Dec(CurTopIdx);
- beStatusProc(@Self);
- SaveIdx := P^.lnLen;
- if NoCase then
- Tmp := StUpcase(P^.lnReturn)
- else
- Tmp := P^.lnReturn;
- end;
- end;
- end
- else begin
- while P <> NIL do begin
- while SaveIdx <= Length(Tmp) do begin
- if Srch[1] = Tmp[SaveIdx] then begin {possible match}
- T := Copy(Tmp,SaveIdx,Length(Srch));
- if T = Srch then begin {positive match}
- NextMatch := P;
- exit;
- end;
- end;
- Inc(SaveIdx);
- end;
- P := LinePtr(EList.Next(P));
- if P <> NIL then begin
- Inc(CurTopIdx);
- beStatusProc(@Self);
- SaveIdx := 1;
- if NoCase then
- Tmp := StUpcase(P^.lnReturn)
- else
- Tmp := P^.lnReturn;
- end;
- end;
- end;
- end;
- end;
-
- begin
- {if a reSearch and no prev search performed, quit}
- if (NOT(Prompt)) and (SearchType = bescSearch) and (beSearchLine = NIL) then
- exit;
-
- if (Prompt) then begin
- if NOT beGetString(0,'Search for: ',False,False,MaxSearchLen,beSearchSt) then
- exit;
-
- if (SearchType = bescReplace) then begin
- if NOT beGetString(0,'Replace with: ',False,False,MaxSearchLen,beReplaceSt) then
- exit;
- end;
-
- if NOT beGetString(0,'Options: ',True,True,MaxSearchOptions,beOptionSt) then
- exit;
- beReplacements := 0;
- NoCase := False;
- Backwards := False;
- NoConfirm := False;
- BlockOnly := False;
- Global := False;
- for N := 1 to Length(beOptionSt) do
- case Upcase(beOptionSt[N]) of
- beBackward : Backwards := True;
- beNoCase : NoCase := True;
- beNoConfirm : NoConfirm := True;
- beBlockOnly : BlockOnly := True;
- beGlobal : Global := Prompt and not(LongFlagIsSet(beOptions,beNoRepeatGlobal));
- end;
- end;
-
- beSaveStreamState(SaveRec,False);
- SetLongFlag(beOptions,beSearching);
-
- if NoCase then
- TSrch := StUpCase(beSearchSt)
- else
- TSrch := beSearchSt;
-
- if Backwards then
- ClearLongFlag(beOptions,beHighlightBack)
- else
- SetLongFlag(beOptions,beHighlightBack);
-
- beSearchLine := CurLine;
- if Backwards then
- SaveIdx := COfs+XOfs-1
- else
- SaveIdx := COfs+XOfs;
-
- {adjust so Curline is the top-of-screen}
- CurTopIdx := CurTopIdx+CurLineOfs;
-
- if (Prompt) and (Global) then begin
- if Backwards then begin
- beSearchLine := LinePtr(EList.Tail);
- CurTopIdx := EList.Size;
- SaveIdx := beSearchLine^.lnLen;
- end
- else begin
- beSearchLine := LinePtr(EList.Head);
- CurTopIdx := 1;
- SaveIdx := 1;
- end;
- end;
- YN := beYes;
- Hits := 0;
-
- while True do begin
- CurLineOfs := 0;
- beSearchLine := NextMatch(beSearchLine,TSrch);
- if (beSearchLine = NIL) or
- ((BlockOnly) and (NOT(beLineInBlock(beSearchLine)))) then begin
- GotError(epNonFatal+ecStringNotFound,'No match found');
- goto ExitPoint;
- end;
- Inc(Hits);
-
- {make it displayable}
- CurLine := beSearchLine;
- CurTop := CurLine;
- CurLineOfs := 0;
- COfs := 1;
- XOfs := 0;
- {try to center the line in the screen}
- while (CurTop^.dlPrev <> NIL) and (CurLineOfs < (Height div 2)) do begin
- CurTop := LinePtr(EList.Prev(CurTop));
- Dec(CurTopIdx);
- Inc(CurLineOfs);
- end;
- {position the cursor}
- if Backwards then
- beCursorRight(SaveIdx-1)
- else
- beCursorRight(SaveIdx+Length(beSearchSt)-1);
- beForceRedraw := True;
- beInformation(0,'');
- SetLongFlag(beOptions,beShowMkrs);
- beUpdateContents;
- beSaveStreamState(SaveRec,False);
-
- if SearchType = bescSearch then begin
- while NOT cwCmdPtr^.cpKeyPressed do ;
- goto ExitPoint;
- end
- else begin
- if NOT NoConfirm then begin
- YN := beYesNo(0,'Replace?',beNo,True);
- NoConfirm := (YN = beAll);
- if (YN = beQuit) then
- goto ExitPoint;
- end;
- if YN <> beNo then begin
- Tmp := CurLine^.lnReturn;
- ReplaceText(Tmp,beReplaceSt,SaveIdx,Length(beSearchSt));
- CurLine^.lnUpdate(Tmp);
- inc(beReplacements);
- ClearLongFlag(beOptions,beShowMkrs);
- beForceRedraw := True;
- beUpdateContents;
- end;
- CurTopIdx := CurTopIdx+CurLineOfs;
- if Backwards then
- Dec(SaveIdx)
- else if Length(beReplaceSt) > Length(beSearchSt) then
- Inc(SaveIdx,Length(beReplaceSt))
- else
- Inc(SaveIdx,Length(beSearchSt));
- end;
- end;
-
- ExitPoint:
- beRestoreStreamState(SaveRec,False);
- if beReplacements > 0 then
- SetLongFlag(beOptions,beModified);
- if (SearchType = bescReplace) and (beReplacements > 0) then
- beInformation(0,' Replacements: '+Long2Str(beReplacements));
- ClearLongFlag(beOptions,beSearching);
- beUpdateContents;
- end;
-
- procedure BigEditor.beReformatPara;
- label BrkOut;
- var B : Byte;
- P,N : LinePtr;
- S : String;
- begin
- if NOT beOptionsAreOn(beWordWrap) then exit;
- SetLongFlag(beOptions,beReformatting);
-
- while (CurLine^.dlNext <> NIL) and (CurLine^.St^ = '') do
- beLineDown(1);
- if CurLine^.dlNext = NIL then exit;
- B := beOfsWhite(CurLine);
- P := CurLine;
-
- {run the loop}
- while (P <> NIL) and (P^.lnLen > 0) do begin
- while (P^.lnLen <= Margin+1) and (LinePtr(P^.dlNext)^.lnLen > 0) do begin
- N := LinePtr(P^.dlNext);
- if N = nil then goto BrkOut;
- Tmp := N^.lnReturn;
- Tmp := ' '+Trim(Tmp);
- P^.lnUpdate(P^.lnReturn+Tmp);
- EList.Delete(N);
- end;
- WordWrap(P^.lnReturn,Tmp,S,Margin,False);
- Tmp := Trim(Tmp);
- if B > 0 then
- Insert(CharStr(' ',B),Tmp,1);
- P^.lnUpdate(Tmp);
- S := Trim(S);
- if S <> '' then begin
- if B > 0 then
- Insert(CharStr(' ',B),S,1);
- New(N,Init(S));
- EList.Place(N,P);
- end;
- P := LinePtr(P^.dlNext);
- end;
- BrkOut:
- CurLine := P;
- beRealignDown;
- beCursorHome;
- beCursorRight(CurLine^.lnLen);
- ClearLongFlag(beOptions,beReformatting);
- SetLongFlag(beOptions,beModified);
-
- beCheckBlock;
- if beOptionsAreOn(beBlockOK) then begin
- beClearBlocking;
- beResetMarkers(False);
- beOptionsOff(beBlockOn);
- end;
- beForceRedraw := True;
- end;
-
- procedure BigEditor.beReformatGlobally;
- var S : StreamStateRec;
- begin
- beSaveStreamState(S,False);
- while CurLine^.dlNext <> nil do begin
- beReformatPara;
- beUpdateContents;
- end;
- beRestoreStreamState(S,False);
- end;
-
- procedure BigEditor.beCenterLine;
- var
- StLen : Byte absolute Current;
- I, J, Delta, Len : Integer;
- begin
- if StLen = 0 then
- Exit;
-
- {find the first non-blank}
- I := 1;
- while Current[I] = ' ' do
- Inc(I);
-
- {length of actual text in string}
- Len := Succ(StLen-I);
-
- {can it be centered?}
- if Len >= Margin then begin
- if I > 1 then begin
- {can't center it, but we can move it to the left margin}
- Delete(Current, 1, Pred(I));
- beCharsInserted(CurLine, -Pred(I));
-
- {adjust cursor}
- if COfs+XOfs >= I then
- beCursorLeft(Pred(I))
- else
- beCursorHome;
- end;
- end
- else begin
- {calculate new starting column}
- J := Succ((Margin-Len) shr 1);
- Delta := J-I;
-
- if Delta > 0 then begin
- {insert extra spaces at beginning of line}
- Insert(CharStr(' ', Delta), Current, 1);
- beCharsInserted(CurLine, Delta);
-
- {adjust cursor}
- beCursorRight(Delta);
- end
- else if Delta < 0 then begin
- {delete extra spaces at beginning of line}
- Delete(Current, 1, -Delta);
- beCharsInserted(CurLine, -Delta);
-
- {adjust cursor}
- if COfs+XOfs > Abs(Delta) then
- beCursorRight(Delta)
- else
- beCursorHome;
- end;
- end;
- CurLine^.lnUpdate(Current);
- SetLongFlag(beOptions,beModified);
- end;
-